Docs / Konzepte
Maschinell übersetzte Seite
Übersetzungssicherheit
Das Sicherheitsmodell: nicht vertrauenswürdige Strings, das Integritäts-Gate, Review-Flags, das Token-Budget und Fehler, die nie etwas preisgeben.
verbatra vertraut weder den Strings, die es übersetzt, noch dem, was ein Provider zurückschickt.
| Schicht | Schützt vor | Bei einem Fehlschlag |
|---|---|---|
| Prompt-Injection-Grenze | einem String, der wie eine Anweisung klingt | nichts scheitert: Strings sind immer nur Daten |
| Integritäts-Gate | kaputten Platzhaltern, ICU, Markup, leeren oder entarteten Werten | der Key wird zurückgehalten und im nächsten Lauf erneut versucht |
| Review-Flags | einem gültigen, aber verdächtigen Wert | der Key wird geschrieben und für einen Menschen eingereiht |
| Token-Budget | Ausgaben über eine Obergrenze, die du setzt | der Rest des Laufs wird zurückgehalten oder markiert |
| Strukturierte Fehler | einem Key oder Header, der in eine Meldung gerät | ein stabiler Code mit fester Meldung |
Nicht vertrauenswürdige Strings und die Prompt-Injection-Grenze
Ein übersetzbarer String kann Text enthalten, der wie eine Anweisung aussieht ("ignoriere deine Anweisungen"), deshalb behandelt verbatra jeden String als nicht vertrauenswürdige Eingabe. Die Systemregeln an einen LLM-Provider sind Konstanten zur Compile-Zeit. Alles Variable (die Einträge, dein Glossar und Tonfall, die Sprachnamen, die Zielkategorien eines Plurals) reist nur in der JSON-Nutzlast des User-Turns, nie im Anweisungskanal. Die Antwort muss zu einem festen Schema passen; eine Antwort mit einem nie angefragten Key lässt ihren ganzen Teil-Batch scheitern.
Namen von Sprache, Schrift und Region
Ein Locale-Code allein reicht nicht immer: sr-Latn kommt oft auf Kyrillisch zurück, und pt-BR
und pt-PT verschwimmen. Deshalb bekommt ein LLM-Provider zusätzlich den englischen Namen, die
Schrift und die Region jeder Sprache, aus Node.js für die Locale in deiner Konfiguration, auch wenn
localeMap einen anderen Code sendet. Sie reisen als Daten, eine feste Systemregel bittet das
Modell, in der genannten Schrift und Variante zu schreiben, und sie sind nicht Teil des
Fingerprints im Cache. Ein Code, den Node.js nicht benennen kann, etwa das
für private Nutzung reservierte qaa, wird ohne Namen gesendet.
Das Integritäts-Gate
Eine schema-gültige Übersetzung kann trotzdem kaputt sein, deshalb entscheidet ein Gate anhand des Kandidatenwerts selbst, ob er angenommen wird; dem eigenen Bericht des Providers wird nie vertraut. Dasselbe Gate läuft auf jedem Schreibpfad: einer Provider-Antwort, einem Cache-Treffer, einer Importzeile aus der Arbeitsmappe und einer in Studio getippten Bearbeitung. Ein Wert, den sich mehrere Keys mit demselben Quelltext teilen, wird pro Key gegen dessen eigene Quelle geprüft.
| Prüfung | Ein Kandidat wird abgelehnt, wenn |
|---|---|
| Platzhalter | seine Platzhalter von denen der Quelle abweichen, verglichen als Multimenge (die Anzahl zählt, die Reihenfolge nicht). Was als Platzhalter gilt, legt jedes Format fest. |
| ICU | er sich bei next-intl und ARB nicht mehr als ICU-Nachricht parsen lässt oder seine Plural-Zweige nicht zur Zielsprache passen (unten). Der Vergleich beachtet Zweige, ein in einem Plural-Zweig erfundener Platzhalter wird also erkannt. |
| Erfundene Tokens | er bei i18next, ngx-translate und YAML ein Token der Form {name} hinzufügt, das die Quelle nie hatte. Eines wegzulassen ist erlaubt, weil einfache geschweifte Klammern dort wörtlicher Text sind. |
| Inline-Markup | seine HTML- oder XML-Tags von denen der Quelle abweichen oder unausgeglichen sind (unten). |
| Entartung | er eine Wiederholungsschleife ist oder seine Länge sich von der Quelle entfernt hat. |
| Leere | er bei nicht leerer Quelle leer ist oder nur aus Leerraum besteht. Eine Übersetzung zu leeren ist ein bewusster Schritt: Das macht der Platzhalter [[CLEAR]] der Arbeitsmappe (Mit Excel oder CSV übergeben). |
Ein Kandidat, der mehrere Prüfungen verletzt, wird mit einem Grund abgelehnt, dem ersten, der in
dieser Reihenfolge zutrifft: empty, icu (lässt sich nicht parsen), placeholder, markup,
icu (Zweige), degenerate. Jeder Grund und die Details, die verbatra dazu ausgibt, stehen unter
Gründe für Integritätsablehnungen.
Was das Gate garantiert: Ein abgelehnter Wert wird nie geschrieben. Er erscheint in der Lauf-Zusammenfassung als Integritätsabweichung, behält seinen bisherigen Hash in der Lock-Datei und wird im nächsten Lauf erneut versucht. Ein Key, für den gar keine Übersetzung kam (der Provider-Aufruf scheiterte, oder der Key fehlte auch nach einer Nachfrage noch), wird stattdessen als Provider-Fehlschlag gemeldet und genauso erneut versucht. Auf der Quellseite wird ein Key, dessen eigener Wert ungültiges ICU ist, vor der Übersetzung beiseitegelegt.
Was es nicht garantiert: dass die Übersetzung richtig ist. Es beweist Struktur, nicht Bedeutung.
Plural-Zweige je Zielsprache
Ein ICU-Plural hat einen Zweig pro CLDR-Pluralkategorie seiner Sprache (Beispiele). Bei next-intl und ARB liest verbatra die Kategorien der Zielsprache aus den in Node.js eingebauten CLDR-Daten:
- Ein LLM-Provider wird nach genau diesen Zweigen gefragt (Kardinalzahlen für
plural, Ordinalzahlen fürselectordinal). Die Kategorien reisen als Daten, die Injection-Grenze bleibt also unverändert. - Das Gate lehnt ein
pluraloderselectordinalab, dem ein nötiger Zweig fehlt oder das einen behält, den die Sprache nicht hat, auf jedem Schreibpfad, und nennt jeden falschen Zweig. - Zweige mit exaktem Wert wie
=0müssen alle erhalten bleiben, und eine Übersetzung darf weitere hinzufügen.select-Zweige sind die Keys deines Codes, eine Übersetzung behält also genau die der Quelle. - Für eine Locale, für die Node.js keine Pluralregeln hat, ist nur
otherPflicht.
Ein Wert, der vor dieser Prüfung geschrieben wurde, etwa ein französischer Plural ohne many, bleibt,
bis sich seine Quelle ändert; verbatra check --qa findet ihn
jetzt schon.
Inline-Markup-Parität
Ein weggelassenes oder kaputtes Inline-Tag (ein <b> in einem i18next-Trans-Block, ein
maskiertes <b> in einem Android-<string>, ein <a href> in gettext) zerbricht die
Darstellung, deshalb vergleicht das Gate Tag- und Attributnamen als Multimenge:
- Abgelehnt: ein weggelassenes, erfundenes oder umbenanntes Tag; eine geänderte Menge von
Attributnamen (auch ein hinzugefügtes
dir); unausgeglichenes oder falsch verschachteltes Markup; zwei Tags, die zu einem verschmolzen sind. - Angenommen: dieselben Tags in anderer Reihenfolge; ein übersetzter Attributwert wie
titleoderalt;<br>geschrieben als<br/>. - Geschützte Werte: Ein URL-Attribut muss Schema und Host behalten (
/docsdarf zu/de/docswerden, nie zuhttps://evil.example/docs), einejavascript:-URL wird abgelehnt, und Werte wiestyle, Event-Handler oder ein<meta content>müssen genau wie in der Quelle bleiben. - Nicht übersetzt: Der Inhalt von
script,styleund ähnlichen Elementen muss unverändert zurückkommen. Maskiere so ein Tag im Fließtext (<script>), um den Text drumherum zu übersetzen.
Markup, das in einen String ohne Markup erfunden wird, wird ebenfalls abgelehnt, während ein
gewöhnliches Wort in spitzen Klammern wie <Enter> als Text gelesen wird. Tags, die das Format
schon als Platzhalter meldet, überlässt es der Platzhalterprüfung. Kommentare, Rohtext und
fehlerhafte Quellen: siehe markup.
Review-Flags
Eine zweite, beratende Schicht markiert verdächtige Ergebnisse für einen Menschen. Ein Flag hält nie einen Key zurück: Der Wert wird geschrieben, gelockt und in die Review-Warteschlange gestellt.
| Grund | Markiert eine Übersetzung, die |
|---|---|
LENGTH_ | viel kürzer oder länger als ihre Quelle ist, gewichtet nach Schrift |
MAX_ | länger als das maxLength-Budget des Keys ist |
EQUALS_ | mit ihrem Quelltext identisch ist |
GLOSSARY_ | die Übersetzung eines Glossarbegriffs auslässt oder einen nicht zu übersetzenden Begriff verändert |
GLOSSARY_ | eine Wiedergabe verwendet, die das Glossar verbietet |
INTEGRITY_ | jeden Platzhalter behält, aber in anderer Reihenfolge |
PROVIDER_ | aus einem Batch stammt, den der Provider herabgestuft hat, etwa durch eine weggefallene Formalität |
FUZZY_ | von einer ähnlichen, bearbeiteten Quelle wiederverwendet wurde |
FOREIGN_ | ein platzhalterartiges Token verliert oder ändert, das ihr Format nicht interpoliert, etwa {name} in i18next |
BIDI_ | ein Richtungssteuerzeichen offen lässt oder eine Überschreibung hinzufügt, die Text umkehrt |
DeepL, Google und LibreTranslate bekommen so ein Token maskiert und halten einen Wert zurück, den sie
nicht maskieren oder wiederherstellen können (PLACEHOLDER_); die Markierung deckt LLMs und Menschen ab.
Cache-Treffer und geteilte Werte werden wie frische Übersetzungen markiert. Markierte Keys
erscheinen als needsReview in der Lauf-Zusammenfassung, in den Review-Spalten der Arbeitsmappe
und auf Studios Review-Seite, bis ein Mensch den Wert freigibt, ablehnt
oder neu schreibt (Review-Entscheidungen).
Das Token-Budget
maxTokens zählt die Tokens eines Laufs über jeden Aufruf und jede Locale; budgetBehavior: "stop"
hält den Rest des Laufs zurück, sobald die Obergrenze überschritten würde, für den nächsten Lauf
(Regeln).
Was das Budget garantiert: Arbeit, die vor der Obergrenze erledigt wurde, bleibt geschrieben und
gelockt, und nichts bleibt halb geschrieben zurück. Was es nicht garantiert: Ein Request unterwegs
kann mehr kosten als geschätzt, die Obergrenze begrenzt einen Lauf (keine watch-Sitzung), und
Retranslates aus Studio oder von Agenten sind nicht abgedeckt.
Fehler geben nichts preis
Scheitert ein Provider-Aufruf, wird der rohe SDK-Fehler (der Request-Header oder Zugangsdaten tragen kann) verworfen, nie geloggt oder erneut geworfen. verbatra erzeugt stattdessen einen strukturierten Fehler mit stabilem Code und fester, geheimnisfreier Meldung. Das Schwärzen von Keys steht unter Datenverarbeitung.
Wo du das siehst
Alles oben ist Daten in der Lauf-Zusammenfassung, pro Locale, und das Scheitern einer Locale hält die anderen nie auf.
Bereits eingecheckte Werte
verbatra check --qa lässt das Gate und die Review-Flags ohne
Provider-Aufruf über committete Werte laufen.
Siehe auch
- Wie ein Lauf funktioniert: wo jede Prüfung in der Pipeline sitzt.
- Datenverarbeitung und Datenschutz: was deinen Rechner verlässt.