KI-Übersetzungen
Ein Übersetzungsdurchlauf nimmt das bereits in Ihrem Repository vorhandene Markdown, rendert es genau so, wie die Live-Seite es rendert, teilt es auf, übersetzt die menschenlesbaren Teile und speichert das Ergebnis pro Seite und Sprache. Es gibt keine Übersetzungsdateien, keine Nachrichtenschlüssel und keinen Exportschritt. Diese Seite beschreibt den Mechanismus auf der Ebene dessen, was der Code tatsächlich tut.
Was startet einen Durchlauf#
Es gibt fünf Auslöser, und jeder Lauf erfasst, welcher davon es war – damit das Panel Ausgelöst durch Commit a1b2c3d anzeigen kann, anstatt einen Push dir zuzuschreiben.
| Auslöser | Was ihn auslöst |
|---|---|
language_enabled |
Du hast eine Sprache aktiviert. |
commit |
Der Scanner des automatischen Modus hat festgestellt, dass sich der Repository-Head verschoben hat. |
manual |
Du hast Jetzt übersetzen gedrückt, oder jemand anderes hat dies über das Dashboard getan. |
agent |
Ein Agent namens run_translation_pass. Der Schlüssel und die Lauf-ID des Agents werden in der Jobzeile eingetragen. |
| Der Fortsetzungs-Runner | Alle 2 Minuten räumt ein Cron-Tick Läufe auf, deren Heartbeat 15 Minuten lang ausgeblieben ist, gibt deren Sperren frei und bearbeitet bis zu drei aktive Jobs, die seit 90 Sekunden untätig sind. |
Der Scanner prüft nur einen Arbeitsbereich, den er seit 15 Minuten nicht mehr geprüft hat, und pro Tick nur vier Arbeitsbereiche – geordnet danach, welcher am längsten ohne Scan geblieben ist. Er bricht frühzeitig ab, wenn der Repository-Head unverändert ist – und der Wasserstand, mit dem er vergleicht, wird nur dann weitergesetzt, wenn bei diesem Commit jede aktivierte Sprache synchron vorgefunden wurde. Dadurch kann ein Lauf, der wegen des Budgets angehalten wurde, einen Arbeitsbereich nicht bei einer unvollständigen Übersetzung einfrieren, sodass er nie wieder geprüft wird.
Ein Durchlauf startet nie mehr als drei Sprachen gleichzeitig, zuerst die dringendsten: Jeder Lauf umfasst minutenlange kostenpflichtige Modellarbeit, und ein Agent-Schritt, der zehn davon öffnet, würde das Monatsbudget für einen einzigen Auslöser aufbrauchen. Die übrigen werden als over_language_cap gemeldet und beim nächsten Mal aufgegriffen – das ist die ehrliche Version von „nicht jetzt“.
Wie eine Seite in Abschnitte aufgeteilt wird#
Die Übersetzungseinheit ist nicht die Seite. Sie ist ein Abschnitt.
- Ihr Markdown wird vorverarbeitet und über dieselbe Pipeline wie die Live-Seite gerendert, einschließlich Ihrer Widget-Blockliste. Die Übersetzung sieht daher die Seite, die ein Leser sieht, und nicht eine zweite Interpretation der Quelle.
- Das gerenderte HTML wird an
<h2>- und<h3>-Grenzen aufgeteilt. Der Inhalt vor der ersten Überschrift wird zu einem eigenen führenden Abschnitt. - Ein Abschnitt mit mehr als 9.000 Zeichen wird erneut aufgeteilt — jedoch nur an Blockgrenzen der obersten Ebene (
</p>,</li>,</table>,</pre>,</figure>,</h1>…</h6>), sodass ein Fragment niemals mitten in einem Tag getrennt wird. - Jeder Abschnitt wird anhand seines eigenen Inhalts gehasht. Der Hash zusammen mit der Sprache ist der Cache-Schlüssel.
- Die Abschnitte werden höchstens 3 gleichzeitig übersetzt, jeweils mit einem Upstream-Timeout von 30 Sekunden, und anschließend in der ursprünglichen Reihenfolge wieder zusammengefügt.
Aus diesem Design ergeben sich zwei Dinge, und genau deshalb ist es so aufgebaut:
- Wenn ein Absatz bearbeitet wird, wird ein Abschnitt erneut übersetzt. Der Hash jedes anderen Abschnitts bleibt unverändert, sodass er aus dem Cache bereitgestellt wird. Die Korrektur eines Tippfehlers kostet einen Abschnitt, nicht eine Seite. Die Aufteilung — wie viele Abschnitte wiederverwendet und wie viele an das Modell gesendet wurden — wird einmal pro Seite im Ausgabenprotokoll erfasst, sodass die Einsparung eine gemessene Zahl und keine Behauptung ist.
- Die Terminologie kann bei Texten, die Sie nicht bearbeitet haben, nicht abweichen. Ein unbearbeiteter Abschnitt ist byte-identisch mit dem letzten Übersetzungsergebnis, da es sich buchstäblich um dieselbe gecachte Zeichenfolge handelt.
Anfragen werden mit Temperatur 0 gesendet, und das Budget für Ausgabetoken wird anhand der Eingabelänge berechnet, statt pauschal reserviert zu werden — mit einem Multiplikator von 2,6, der gewählt wurde, weil Kyrillisch und CJK weit mehr Token pro Zeichen kosten als die englische Quelle und ein Budget von 1,5× zu abgeschnittenen Seiten führte.
Was ist vor dem Modell geschützt#
Hier gibt es zwei verschiedene Arten des Schutzes, und ihre Vermischung führt dazu, dass die Dokumentation letztlich mehr verspricht, als der Code tatsächlich leistet.
Strukturell geschützt – das Modell sieht es nie#
| Element | Mechanismus |
|---|---|
| Codeblöcke mit Begrenzungsmarkierungen | Vor der Anfrage extrahiert und durch __CODE_BLOCK_N__ ersetzt; anschließend Byte für Byte wiederhergestellt. |
Inline-Code (`like this`) |
Dieselbe Extraktion, dieselbe bytegenaue Wiederherstellung. |
| Frontmatter-Schlüssel und -Werte | Erreichen das Modell überhaupt nicht: Die Übersetzung erfolgt auf gerendertem HTML, und das Frontmatter wurde zum Zeitpunkt des Renderns verarbeitet. |
Widget-Markierungen (<!-- widget:name -->) |
Erreichen das Modell ebenfalls nie: Widgets werden von der Rendering-Pipeline vor der Aufteilung in HTML erweitert. Es bleibt keine Markierung zurück, die beschädigt werden könnte. Der sichtbare Text innerhalb eines Widgets – beispielsweise der Titel einer Karte – ist Prosa und wird übersetzt. |
Dies sind Garantien. Ein Modell kann ein Codebeispiel, das ihm nie übergeben wurde, weder verändern noch neu umbrechen oder „übersetzen“.
Durch Anweisung geschützt — diese überprüfen, nicht als gegeben annehmen#
Die Eingabe weist das Modell als absolute Regeln an, HTML-Tags, Attribute, Klassennamen, IDs, href-Werte oder Datenattribute weder zu übersetzen noch zu ändern, die HTML-Struktur nicht zu ändern, Code-Bezeichner und Variablennamen nicht zu übersetzen, keinen Kommentar hinzuzufügen und __CODE_BLOCK_N__-Platzhalter exakt wiederzugeben. Das ist eine starke Anweisung an ein Modell, das mit Temperatur 0 läuft, und sie funktioniert in der Praxis – aber es ist eine Anweisung, kein Mechanismus, und das ehrliche Wort dafür ist meistens.
Drei wissenswerte Folgen:
- Links behalten ihre Ziele.
hrefist ein Attribut, und Attribute stehen auf der Nicht-verändern-Liste. Der Text des Links ist Prosa und wird übersetzt. - Überschriftenanker bleiben in der Ausgangssprache. Die
id-Attribute der Überschrift werden vor der Übersetzung festgelegt und sollen unverändert bleiben, sodass ein Deeplink zu einem englischen Überschriftenanker auf der übersetzten Seite weiterhin funktioniert. - Der Text
altvon Bildern wird nicht übersetzt. Er ist ein HTML-Attribut, und die Regel, diehrefschützt, schützt damit auchalt. Wenn barrierefreier Alternativtext in der Sprache des Lesers für Sie wichtig ist, handelt es sich dabei um eine Lücke und nicht um ein Feature.
Als Gruppen übersetzt, nicht einzeln#
Die Navigationsbeschriftungen werden als eine Gruppe in einer einzigen Anfrage übersetzt, die dieselbe Anzahl von Beschriftungen in derselben Reihenfolge zurückgeben muss; bei einer fehlerhaften oder nicht übereinstimmenden Antwort werden die Originale beibehalten, anstatt zu raten. Wenn jede zurückgegebene Beschriftung mit dem Original identisch ist – das Zeichen dafür, dass keine Übersetzung stattgefunden hat –, wird das Ergebnis verworfen, anstatt zwischengespeichert zu werden, damit der nächste Versuch erneut durchgeführt werden kann, anstatt englische Beschriftungen dauerhaft festzuschreiben. Der Titel und die Beschreibung einer Seite werden gemeinsam als Paar übersetzt, sodass sie niemals auseinanderlaufen können.
Wie eine veraltete Übersetzung erkannt wird#
Durch den Vergleich mit Git, nicht anhand eines Status-Flags.
Jede gespeicherte Übersetzungszeile enthält source_hash — den Git-Blob-SHA der Quelldatei zum Zeitpunkt ihrer Übersetzung. Die Abdeckung wird berechnet, indem der Repository-Baum bei HEAD gelesen und pro Pfad verglichen wird:
| Status | Bedeutung |
|---|---|
current |
Eine maschinelle Übersetzung ist vorhanden und ihr gespeicherter SHA entspricht dem SHA der Datei bei HEAD. |
behind |
Eine maschinelle Übersetzung ist vorhanden, stammt jedoch aus einer älteren Version dieser Seite. |
missing |
Die Seite ist im Repository vorhanden und wurde noch nie in diese Sprache übersetzt. |
manual |
Von Hand geschrieben oder hochgeladen. Ob sie aktuell ist, entscheidet der Autor, daher wird sie niemals als veraltet gezählt. |
orphaned |
Eine Übersetzung, deren Quelldatei bei HEAD nicht mehr vorhanden ist. |
Die Abdeckung ist (current + manual) / total, und eine Sprache ist auf dem aktuellen Stand, wenn behind und missing beide null sind. Wenn das Repository nicht gelesen werden kann, ist die Abdeckung null — niemals eine verlässliche Null, und jede Oberfläche meldet „unbekannt“, statt eine gesunde Sprache rot darzustellen.
Die Spalte status = 'outdated' in der Datenbank wird dafür absichtlich nicht verwendet. Nichts im Produkt schreibt automatisch in sie, daher steht sie in jedem Arbeitsbereich auf null; eine darauf basierende Aktualitätsprüfung würde für immer einen perfekten Zustand melden.
Ein anhand dieses Vergleichs geordneter Durchlauf übersetzt zuerst veraltete, dann fehlende Inhalte. Eine veraltete Übersetzung vermittelt einem Leser aktiv etwas, das in Ihrer Dokumentation nicht mehr steht; bei einer fehlenden Übersetzung wird auf das Original zurückgegriffen, und sie hilft lediglich nicht weiter.
Der Prüf- und Genehmigungsablauf#
Eine gespeicherte Übersetzung kann aus drei Quellen stammen, die bewusst unterschiedlich behandelt werden.
| Herkunft | Erstellt von | Für Leser bereitgestellt | Bei einem späteren Durchlauf überschrieben |
|---|---|---|---|
docsbook_ai |
Ein Übersetzungsdurchlauf | Ja | Ja |
manual_upload |
Von Ihnen über den Panel-Editor oder upload_translation |
Lesen Sie dies zuerst | Nein — ein automatischer Durchlauf ersetzt sie nicht |
external_api |
Ihre eigene Pipeline im external-Modus |
Lesen Sie dies zuerst | Nein |
Uploads werden standardmäßig als Entwurf gespeichert. list_pending_translations gibt die Entwürfe zurück, approve_translation verschiebt einen davon in den veröffentlichten Status, und das Bearbeiten des Inhalts einer Übersetzung markiert die Zeile als manuellen Upload, sodass ein späterer Durchlauf sie unverändert lässt. Im external-Modus läuft der Vorgang folgendermaßen ab: Docsbook gibt translation.needed aus, wenn eine Seite übersetzt werden soll, Ihre Pipeline erledigt die Arbeit, und upload_translation übermittelt das Ergebnis zurück.
Maschinelle Übersetzungen gelangen nicht in diese Warteschlange. Ein Durchlauf schreibt Zeilen mit dem Status auto, nicht draft, daher listet list_pending_translations sie nie auf. Der Genehmigungsablauf ist eine Schleuse für Übersetzungen, die von außen hereinkommen, kein menschlicher Prüfschritt vor der KI-Ausgabe. Wenn Sie die KI-Ausgabe prüfen lassen möchten, bevor Leser sie sehen, ist der external-Modus dafür vorgesehen; der standardmäßige auto-Modus veröffentlicht die Ergebnisse sofort.
Was passiert, wenn eine Ausführung fehlschlägt#
Jeder der unten beschriebenen Fehlerfälle ist eine bewusste Entscheidung, das Original auszuliefern, statt etwas Fehlerhaftes zu speichern.
| Fehler | Was passiert |
|---|---|
Das Modell erreicht seine Obergrenze für Ausgabetoken (finish_reason: length) |
Wird als schwerwiegender Fehler behandelt und abgelehnt, nicht gespeichert. Ein abgeschnittener Abschnitt führte einmal dazu, dass eine halbe Seite für immer als Übersetzung im Cache blieb. |
| Das Modell gibt leeren Inhalt zurück | Ebenfalls ein schwerwiegender Fehler. Eine leere Zeichenfolge, die als Erfolg weitergereicht wurde, war der Grund dafür, dass sich in einem Projekt einst 808 leere Übersetzungszeilen ansammelten. |
| Ein Abschnitt schlägt fehl | Die Seite wird mit dem Originaltext für diesen Abschnitt zusammengestellt und nur für diese Anfrage ausgeliefert. Sie wird weder in Redis noch in Postgres geschrieben und auch nicht indiziert. |
| Die zusammengestellte Seite ist leer, obwohl die Quelle nicht leer ist | Wird nicht gespeichert; stattdessen wird die Quelle ausgeliefert. |
| Ein Abschnitt ist kürzlich fehlgeschlagen | Ein negativer Cache für 10 Minuten verhindert eine Anfragelawine bei Wiederholungsversuchen. Beim nächsten Besuch nach Ablauf werden nur die fehlenden Abschnitte erneut übersetzt. |
| Der Anbieter gibt für den gemeinsam genutzten Schlüssel von Docsbook 402/403 zurück | Eine globale Pause wird für 4 Stunden gesetzt, und jeder ausstehende Lauf wird sofort beendet, anstatt ein erschöpftes Konto weiter zu belasten. Arbeitsbereiche mit einem eigenen Schlüssel sind davon nicht betroffen. |
| Das Kontingent deines eigenen Schlüssels ist erschöpft | Nur der Lauf deines Projekts schlägt fehl. Das erschöpfte Kontingent einer anderen Person hält dich niemals an, und deines hält sie niemals an. |
| Das Ausgabenbudget des Projekts ist erschöpft | Der Lauf wird mit diesem Grund im Klartext angehalten, und die verbleibenden Seiten werden bei einem späteren Lauf übersetzt, sobald das Guthaben dies zulässt. Nichts, wofür bereits bezahlt wurde, geht verloren. |
| Der Aufruf wird während des Laufs beendet | Der Auftrag speichert einen Cursor und einen Heartbeat. Der Runner, der alle 2 Minuten läuft, räumt einen Auftrag auf, der 15 Minuten lang stumm war, gibt seine Sperre frei und startet ihn ab der nächsten noch nicht übersetzten Seite neu. |
Ein teilweise abgeschlossener Lauf ist normal und kein Fehlerzustand: Eine große Website benötigt mehr als einen Aufruf, jeder Aufruf arbeitet so lange, wie es seine Laufzeit erlaubt, und beim nächsten Intervall wird fortgesetzt. Was du niemals sehen solltest, ist eine Seite, die halb auf Englisch und halb in einer anderen Sprache ist, denn genau diese Zusammenstellung verweigert der Code dauerhaft zu speichern.
Solange für eine Seite noch keine Übersetzung vorliegt, wird dem Leser das Original angezeigt – ohne Ladeanzeige, ohne Fehler und ohne Banner, das eine Übersetzung für diese Anfrage verspricht, die nicht geliefert wird. Wenn nur eine ältere Übersetzung vorhanden ist, erhält der Leser diese ältere Übersetzung sofort, anstatt auf das Original zurückzufallen: Lesbarer Inhalt in der richtigen Sprache ist besser, als zu warten.
Beschränkungen#
- Die Konsistenz der Terminologie wird nicht durch ein Glossar unterstützt. Es gibt keine Terminologiedatenbank, keine Liste mit Begriffen, die Sie als nicht zu übersetzen angeben können, und keine seitenübergreifende Konsistenzprüfung. Die vorhandene Konsistenz ergibt sich aus Temperatur 0, daraus, dass nicht bearbeitete Abschnitte unverändert aus dem Cache bereitgestellt werden, sowie daraus, dass Beschriftungen und Titel/Beschreibung als Einheiten übersetzt werden. Zwei verschiedene Seiten, auf denen derselbe Begriff verwendet wird, wurden unabhängig voneinander übersetzt und stimmen möglicherweise nicht überein.
- „Bezeichner nicht übersetzen“ ist eine Anweisung, keine Garantie. Code innerhalb von Codeblöcken und Backticks ist mechanisch geschützt. Ein alleinstehender Bezeichner, der als normaler Fließtext geschrieben ist – etwa ein Parametername in einem Satz ohne Backticks – wird nur durch die Anweisung geschützt. Bezeichner in Backticks zu schreiben, ist das Wertvollste, was Sie für Ihre eigenen Übersetzungen tun können.
- Der Text von
altin Bildern bleibt in der Ausgangssprache. Siehe oben; dies ist eine Folge des umfassenden Schutzes von HTML-Attributen. - Eine zwischengespeicherte Übersetzung wurde unter der zum Zeitpunkt ihrer Erstellung geltenden Widget-Sperrliste gerendert. Das Ausschalten eines Widgets schreibt bereits übersetzte Seiten nicht neu; sie übernehmen die Änderung bei ihrem nächsten Durchlauf. Den Cache anhand der Sperrliste neu zu verschlüsseln, würde für eine Darstellungsoption jede Seite in jeder Sprache erneut übersetzen.
- Der Automatikmodus reagiert auf eine Abfrage, nicht auf Ihren Push. Siehe Übersetzungseinstellungen.
Verwandte Themen#
- Übersetzungseinstellungen — Aktivieren einer Sprache, das Modell, der Modus und URLs für Regionen
- Übersetzungsqualität und SEO — was gemessen wird, wie eine Übersetzung korrigiert wird,
hreflangund wie Suchmaschinen mit übersetzten Seiten umgehen - Bericht zu Besucherregionen — aus welchen Regionen Besucher kommen, für die Sie bisher noch keine Übersetzung anbieten