Referenz / Konfiguration
Maschinell übersetzte Seite
Provider
Alle KI- und Maschinenübersetzungs-Provider, die verbatra unterstützt, mit ihren Optionen und API-Key-Variablen, dazu das Verhalten, das sie alle teilen.
Wähle einen Provider über die id im provider-Block deiner Konfiguration. Anthropic, OpenAI, Gemini, OpenCode und openai-compatible sind Sprachmodelle; DeepL, Google Cloud Translation und LibreTranslate sind Maschinenübersetzungsdienste; none schaltet maschinelle Übersetzung ab. Die Sprachabdeckung steht unter Sprachen und Locales, und was jeder Provider bekommt, unter Datenverarbeitung und Datenschutz.
Welchen soll ich nehmen?
Jeder Provider funktioniert mit jedem Format und jedem Befehl, und ein späterer Wechsel heißt, eine id zu ändern.
| Wenn du willst | Nimm |
|---|---|
| Kostenlos, für ein kleines Projekt mit nicht vertraulichen Strings | Gemini: ein kostenloses API-Kontingent, dessen Anfragen Google außerhalb von EWR, Schweiz und Vereinigtem Königreich von Menschen prüfen lassen darf (Bedingungen). |
| Die beste Qualität für eine Produktions-App | Anthropic oder OpenAI, beide bezahlt. |
| Hohes Volumen, ein natives Glossar, kein LLM | DeepL, kostenloses oder bezahltes Kontingent. |
| Die breiteste Abdeckung mit einem API-Schlüssel auf Google Cloud | Google Cloud Translation (Basic, v2). |
| Offline, kostenfrei, nichts verlässt dein Netzwerk | openai-compatible mit LM Studio, Ollama oder vLLM. |
| Kein Sprachmodell, aber selbst gehostet | LibreTranslate auf deinem eigenen Server. |
| Gar keine maschinelle Übersetzung | none: nur Translation Memory und Menschen. |
Keys kommen aus der Umgebung
verbatra liest nie einen Key aus der Konfiguration. Jeder gehostete Provider liest eine Variable:
| Provider-Id | Umgebungsvariable |
|---|---|
anthropic | ANTHROPIC_ |
openai | OPENAI_ |
gemini | GEMINI_ |
deepl | DEEPL_ |
google-translate | GOOGLE_ |
opencode | OPENCODE_ |
Setze sie in .env (das verbatra init in .gitignore einträgt), in deiner Shell oder in deinem CI-Secret-Store, und committe sie nie. Eine ungesetzte oder leere Variable scheitert mit MISSING_, das die Variable nennt, aber nie einen Wert. openai-compatible und libretranslate brauchen meist keinen Key.
Anthropic
provider: {
id: "anthropic",
options: {
model: "claude-sonnet-4-6", // example model id
maxTokens: 4096,
},
}| Option | Typ | Default | Wirkung |
|---|---|---|---|
model | String | erforderlich | Die Modell-Id. |
maxTokens | positive Ganzzahl | erforderlich | Begrenzt die Ausgabe-Tokens einer Antwort (Limits); hat nichts mit dem Top-Level-Budget zu tun. |
requestTimeoutMs | positive Ganzzahl | 120000 | Begrenzt jeden Anfrageversuch (Anfrage-Timeout). |
localeMap | Zuordnung von Locale zu Code | keine | Überschreibt den gesendeten Code pro Locale (Locale-Codes). |
Liest ANTHROPIC_.
OpenAI
provider: {
id: "openai",
options: {
model: "gpt-5.4-mini", // example model id
maxOutputTokens: 4096,
},
}| Option | Typ | Default | Wirkung |
|---|---|---|---|
model | String | erforderlich | Die Modell-Id. |
maxOutputTokens | positive Ganzzahl | erforderlich | Begrenzt die Ausgabe-Tokens einer Antwort. |
requestTimeoutMs | positive Ganzzahl | 120000 | Begrenzt jeden Anfrageversuch. |
localeMap | Zuordnung von Locale zu Code | keine | Überschreibt den gesendeten Code pro Locale. |
Liest OPENAI_.
Gemini
provider: {
id: "gemini",
options: {
model: "gemini-2.5-flash", // example model id
maxOutputTokens: 4096,
},
}| Option | Typ | Default | Wirkung |
|---|---|---|---|
model | String | erforderlich | Die Modell-Id. |
maxOutputTokens | positive Ganzzahl | erforderlich | Begrenzt die Ausgabe-Tokens einer Antwort. |
requestTimeoutMs | positive Ganzzahl | 120000 | Begrenzt jeden Anfrageversuch. |
localeMap | Zuordnung von Locale zu Code | keine | Überschreibt den gesendeten Code pro Locale. |
Liest GEMINI_.
Das kostenlose Kontingent und seine Limits
Ein Key aus dem Google AI Studio braucht keine Zahlungsdaten, aber seine Grenzen pro Minute und pro Tag können einen ersten Lauf über viele Locales stoppen: Übersetze eine Locale nach der anderen oder senke maxBatchSize und starte erneut, um den Rest aufzugreifen.
DeepL
provider: {
id: "deepl",
options: {
glossaryId: "<your-glossary-id>",
},
}| Option | Typ | Default | Wirkung |
|---|---|---|---|
glossaryId | String | keine | Ein Glossar, das du in DeepL angelegt hast, nativ angewendet. |
requestTimeoutMs | positive Ganzzahl | 120000 | Die Mindestwartezeit pro Versuch, bis zu sechs Versuche. |
localeMap | Zuordnung von Locale zu Code | keine | Überschreibt den gesendeten Code pro Locale. |
Liest DEEPL_; options darf {} sein. DeepL hat kein Modell und kein Ausgabe-Token-Limit und stuft mit einem Hinweis herab, statt fehlzuschlagen:
- Platzhalter reisen als nummerierte Markierungen in einem ignorierten Tag (
Hello {{name}}alsHello <x>{0}</x>) und werden wieder eingesetzt.PLACEHOLDER_hält einen Wert mit nicht wörtlichem Platzhalter oder mitUNSUPPORTED <,>,{oder}im übrigen Text zurück, und ein Ergebnis mit verlorener, wiederholter, geänderter oder bloßer Markierung, unbekannter Entity oder fremdem Tag. Reines Markup geht als Klartext hinaus. - Tonfall wird auf Formalität abgebildet (
formalformeller,informalinformeller,neutralweggelassen). Ein Key aus dem kostenlosen Kontingent sendet gar keine Formalität und meldetFORMALITY_. Ein bezahlter Key fragt mitDOWNGRADED prefer_odermore prefer_an, sodass eine Sprache ohne Formalität wie Schwedisch mit demselben Hinweis zurückfällt statt zu scheitern. Das Glossar wird nicht angewendet.less
verbatra liefert DeepLs datierte Sprachtabelle mit und lehnt eine nicht aufgeführte Sprache mit LOCALE_ ab, bevor etwas ausgegeben wird. Eine glossaryId funktioniert nur, wenn beide Sprachen auf DeepLs Glossarliste stehen (etwa DE, EN, FR, JA, ZH).
Google Cloud Translation
provider: {
id: "google-translate",
options: {},
}| Option | Typ | Default | Wirkung |
|---|---|---|---|
requestTimeoutMs | positive Ganzzahl | 120000 | Begrenzt den ganzen Aufruf (keine Wiederholungen). |
localeMap | Zuordnung von Locale zu Code | keine | Überschreibt den gesendeten Code pro Locale. |
Liest GOOGLE_, einen API-Schlüssel für ein Google-Cloud-Projekt mit aktivierter Cloud Translation API. Nur Basic (v2) funktioniert: Advanced (v3) braucht einen Service-Account.
- Platzhalter werden wie bei DeepL maskiert, in
<span translate="no">; Zeilenumbrüche, Tabs und doppelte Leerzeichen werden ebenfalls zurückgehalten. - Codes. Jeder gesendete Code wird vor jedem Aufruf als wohlgeformtes BCP 47 geprüft (
en_scheitert mitUS INVALID_). Regionale Codes sind erlaubt; ein Paar, das Google ablehnt, scheitert mitREQUEST INVALID_von der API.REQUEST
verbatra liefert Googles datierte Sprachtabelle mit und lehnt eine nicht aufgeführte Sprache ab, bevor etwas ausgegeben wird. Ein regionaler Code, dessen Sprache nur als Ganzes aufgeführt ist, etwa de-AT, wird mit einer Warnung so gesendet, wie er geschrieben ist.
OpenCode
Hier funktionieren nur Modelle von OpenCode Zen, die über /chat/completions laufen (die Modelltabelle nennt den Endpunkt jedes Modells). OpenCode behält Go und die kostenlosen Zen-Modelle seinen eigenen Clients vor.
provider: {
id: "opencode",
options: {
model: "glm-5.3", // example: a Zen model served over Chat Completions
maxOutputTokens: 4096,
},
}| Option | Typ | Default | Wirkung |
|---|---|---|---|
model | String | erforderlich | Die Modell-Id. |
maxOutputTokens | positive Ganzzahl | erforderlich | Begrenzt die Ausgabe-Tokens einer Antwort. |
requestTimeoutMs | positive Ganzzahl | 120000 | Begrenzt jeden Anfrageversuch. |
localeMap | Map von Locale zu Code | keiner | Überschreibt den je Locale gesendeten Code. |
Fester Endpunkt, kein baseUrl. Liest OPENCODE_.
openai-compatible
Jeder Server, der die OpenAI-Chat-Completions-API spricht: LM Studio, Ollama, vLLM oder eine gehostete API.
Der Server muss Chat Completions unter <baseUrl>/chat/completions mit striktem JSON-Schema-Output bereitstellen. Gateways, die nur ihre eigenen Client-Apps bedienen, funktionieren nicht.
provider: {
id: "openai-compatible",
options: {
baseUrl: "http://192.168.178.74:1234/v1",
model: "qwen2.5-14b-instruct", // example: whatever your server exposes
maxOutputTokens: 1024,
},
}| Option | Typ | Default | Wirkung |
|---|---|---|---|
baseUrl | http- oder https-URL | erforderlich | Die API-Wurzel, meist mit /v1 am Ende. Eine URL, die auf /chat/completions oder /completions endet, wird abgelehnt; eine ohne /v1 besteht die Validierung und scheitert erst bei der Anfrage. |
model | String | erforderlich | Das Modell, das dein Server anbietet. |
maxOutputTokens | positive Ganzzahl | erforderlich | Begrenzt die Ausgabe-Tokens einer Antwort. |
apiKeyEnvVar | Variablenname | keine | Die Variable mit dem Key dieses Servers. |
requestTimeoutMs | positive Ganzzahl | 120000 | Begrenzt jeden Anfrageversuch. |
localeMap | Zuordnung von Locale zu Code | keine | Überschreibt den gesendeten Code pro Locale. |
Für eine gehostete API wie Mistral:
provider: {
id: "openai-compatible",
options: {
baseUrl: "https://api.mistral.ai/v1",
model: "mistral-large-latest", // example: check Mistral's current model list
maxOutputTokens: 4096,
apiKeyEnvVar: "MISTRAL_API_KEY",
},
}Die Antwort nutzt dasselbe strikte Schema wie openai; das erste balancierte JSON-Objekt wird aus umgebender Prosa oder einem Code-Fence genommen und validiert. verbatra init --provider openai-compatible --base-url <url> --model <name> schreibt diesen Block (init), und --api-key-env-var <NAME> ergänzt den Namen der Variable.
Keys sind optional
Der Key wird der Reihe nach aufgelöst:
apiKeyEnvVar: Wenn gesetzt, muss seine Variable einen Key enthalten, sonst scheitert der Lauf mitMISSING_.API_ KEY OPENAI_: wird verwendet, wenn sie gesetzt und nicht leer ist.COMPATIBLE_ API_ KEY "local": ein fester, nicht geheimer Platzhalter, der einen Server ohne Key funktionieren lässt.
apiKeyEnvVar kann nicht die Variable eines gehosteten Providers nennen, und der Client liest nie OPENAI_, ein gehosteter Key erreicht also nie eine eigene baseUrl.
Ein echter Key über Klartext-http reist unverschlüsselt
Mit einem Key und einer http://-URL zu einem Nicht-Loopback-Host geht der Key unverschlüsselt und ohne Warnung durch dein Netzwerk, verwende also https:// für einen Server, der einen Key braucht.
Ein lokales Modell wählen
Bevorzuge ein instruktionsoptimiertes, mehrsprachiges Modell ohne Reasoning, so groß, wie deine Hardware es gut ausführt, etwa qwen2.5-14b-instruct. Reasoning-Modelle und stark quantisierte Builds neigen dazu, die Antwort zu verpacken oder abzuschneiden, was als INVALID_ oder OUTPUT_ scheitert.
LibreTranslate
Ein selbst gehosteter LibreTranslate-Server (Argos Translate, kein Sprachmodell). verbatra ruft nur seine HTTP-API auf, die AGPL-3.0-Lizenz des Servers erstreckt sich also nicht auf dein Projekt.
provider: {
id: "libretranslate",
options: {
baseUrl: "http://localhost:5000",
},
}| Option | Typ | Default | Wirkung |
|---|---|---|---|
baseUrl | http- oder https-URL | erforderlich | Die API-Wurzel, ohne /translate. |
requestTimeoutMs | positive Ganzzahl | 120000 | Begrenzt den ganzen Aufruf (keine Wiederholungen). |
localeMap | Zuordnung von Locale zu Code | keine | Überschreibt den gesendeten Code pro Locale. |
Seine Sprachen sind die auf deinem Server installierten Modelle:
docker run -p 5000:5000 libretranslate/libretranslate --load-only en,de,fr- Key.
LIBRETRANSLATE_wird nur alsAPI_ KEY api_gesendet, wenn sie gesetzt ist. Ein mitkey --api-keysgestarteter Server lässt den Lauf mitMISSING_scheitern, wenn sie nicht gesetzt ist, und mitAPI_ KEY AUTH_, wenn er sie ablehnt.FAILED - Platzhalter werden wie bei DeepL maskiert, als bloße
{0}-Markierungen; Markup bleibt erhalten, daher zählen nur geschweifte Klammern neben einem Platzhalter. - Markup. Ein Wert mit HTML-artigen Tags wird im
html-Format gesendet: Der Text in den Tags wird übersetzt, die Tags bleiben (eine Formulierung über ein Tag hinweg kann leiden), und veränderte Tags werden abgelehnt. - Sprachprüfung. Jedes Ziel warnt bei jedem Lauf
LOCALE_;UNVERIFIED_ BY_ PROVIDER verbatra doctor --locales --liveprüft sie gegen den Server.
verbatra init --provider libretranslate --base-url <url> schreibt diesen Block.
none
Schaltet maschinelle Übersetzung per Richtlinie ab, für eine Regel, die verbietet, Strings an irgendeinen Dienst zu senden.
provider: { id: "none" }options darf fehlen oder {} sein. Es wird kein Provider erzeugt, kein Key gelesen und keine Anfrage gestellt; was jeder Befehl stattdessen tut, steht unter Ohne maschinelle Übersetzung arbeiten.
Tonfall und Glossar über die Provider hinweg
Eine Anfrage enthält nur die Glossarbegriffe ihrer Ziel-Locale, und jede Ausgabe wird gegen sie geprüft.
| Provider | tone | glossary |
|---|---|---|
| Anthropic, OpenAI, Gemini, OpenCode, openai-compatible | gesendet und eingehalten | Übersetzungen, verbotene Wiedergaben, doNotTranslate-Begriffe und Notizen als bindende Daten gesendet |
| DeepL | auf Formalität abgebildet | GLOSSARY_; nur glossaryId wird angewendet |
| Google Cloud Translation, LibreTranslate | FORMALITY_ bei formal oder informal | GLOSSARY_ |
Verhalten, das jeder Provider teilt
Batching
Die Arbeit einer Locale geht in sequenziellen Sub-Batches von höchstens maxBatchSize Einträgen hinaus. Ein fehlgeschlagener Sub-Batch wird zurückgehalten und beim nächsten Lauf erneut versucht, während der Rest weiter vorankommt. DeepL und Google Cloud Translation teilen einen Sub-Batch zusätzlich auf, damit er in ihre eigenen Anfragegrenzen passt.
Wiederholungen
Rate-Limits und Serverfehler werden mit Backoff wiederholt, bei OpenAI, OpenCode, openai-compatible, Anthropic und DeepL vom Client und bei Gemini von verbatra. Google Cloud Translation und LibreTranslate wiederholen nicht. Gemini hält eine genannte Wartezeit von bis zu 5 Sekunden ein und lässt eine längere, etwa bei erschöpftem Tageskontingent, sofort mit RATE_ scheitern, das die Wartezeit nennt.
Anfrage-Timeout
requestTimeoutMs (Default 120000 ms) verhindert, dass ein Server, der nie antwortet, einen Lauf blockiert und die Schreibsperre einer Locale hält. Erhöhe ihn für ein langsames lokales Modell oder eine große maxBatchSize.
provider: {
id: "openai-compatible",
options: {
baseUrl: "http://192.168.178.74:1234/v1",
model: "qwen2.5-14b-instruct",
maxOutputTokens: 1024,
requestTimeoutMs: 300000, // 5 minutes
},
}- Pro Versuch. Jede Wiederholung bekommt den vollen Timeout. Die LLM-Provider wiederholen auch einen Versuch im Timeout, und alle außer Gemini einen Verbindungsfehler, ein hängender Server braucht also bis zu drei Timeouts plus Backoff.
- Der Fehler nennt die Ursache.
TIMEOUTheißt, dass ein Versuch rechtzeitig keine Antwort bekommen hat; wiederholt abgelehnte Verbindungen scheitern alsPROVIDER_.ERROR - DeepL kann eine laufende Anfrage nicht abbrechen, ein unterbrochener Lauf lässt sie also bei DeepL zu Ende laufen.
An den Provider gesendete Locale-Codes
Dateien, Lock-Datei und Translation Memory verwenden immer die Codes deiner Konfiguration. Nur die Anfrage wird in das übersetzt, was der Provider erwartet:
| Provider | Quell-Locale | Ziel-Locale |
|---|---|---|
| DeepL | Nur die Sprache: en-US als EN, zh-Hant-TW als ZH. | zh-Hant, zh-TW, zh-HK, zh-MO als ZH-HANT; zh-Hans, zh-CN, zh-SG als ZH-HANS. DeepL-Varianten bleiben (EN-GB, EN-US, PT-BR, PT-PT, ES-419, FR-CA, FR-FR, DE-CH, DE-DE). Spanisch mit einer lateinamerikanischen oder karibischen Region (MX, AR, CO, CL, PE, VE, EC, GT, CU, BO, DO, HN, PY, SV, NI, CR, PA, UY, PR, US, 419) als ES-419. Andere Regionen und Schriften fallen weg: de-AT als DE. |
| Google Cloud Translation | zh-Hant (zh-HK, zh-MO) als zh-TW, zh-Hans (zh-SG) als zh-CN, nb als no; alles andere so, wie es geschrieben ist. | Wie bei der Quelle. |
| LibreTranslate | Nur die Sprache (de-AT als de), außer dass pt-BR bleibt und Chinesisch als zh-Hans oder zh-Hant geht (zh-TW als zh-Hant). | Wie bei der Quelle. |
| Anthropic, OpenAI, Gemini, OpenCode, openai-compatible | So, wie er geschrieben ist. | Wie bei der Quelle. |
Ein LLM bekommt zusätzlich die Namen von Sprache, Schrift und Region. DeepL hat kein allgemeines Englisch oder Portugiesisch als Ziel, ein Ziel, das am Ende ein bloßes en oder pt ist (etwa en-AU), wird deshalb vor dem Lauf abgelehnt: Bilde es auf EN-GB, EN-US, PT-BR oder PT-PT ab.
localeMap überschreibt den Code pro Locale:
provider: {
id: "deepl",
options: {
localeMap: {
"en-AU": "EN-GB",
"fr-BE": "FR-FR",
},
},
}- Keys müssen
sourceLocaleoder eine Ziel-Locale wie konfiguriert sein, sonst scheitert die Konfiguration mitCONFIG_. Die Zuordnung gehört unterINVALID options, bei jedem Provider außernone. - Werte sind nicht leere Strings mit höchstens 64 Zeichen und werden unverändert gesendet: an einen Maschinenübersetzungs-Provider als Sprachcode, an ein LLM anstelle des Codes (
"pt-BR (Brazilian Portuguese)"funktioniert), dessen Sprachnamen trotzdem aus dem Key kommen. Ein bloßesENoderPTfür DeepL scheitert mitINVALID_; ein Wert, den der Provider ablehnt, lässt seinen Sub-Batch scheitern.REQUEST - Wirkung auf das Translation Memory. Nur neue und geänderte Strings gehen mit einem neuen Code hinaus. Ein nicht leeres
localeMapist Teil des Fingerprints im Translation Memory, eine Änderung beginnt also einen eigenen Bereich.
Die Sprachunterstützung eines Providers prüfen
Jede konfigurierte Locale wird beurteilt, bevor etwas ausgegeben wird:
| Provider | Beurteilt gegen | Vor dem Lauf abgelehnt | Gewarnt bei |
|---|---|---|---|
| DeepL | Seine mitgelieferte Sprachtabelle, mit Glossar- und Formalitätsunterstützung je Sprache | Eine nicht aufgeführte Quell- oder Zielsprache | Einem Glossar für ein Paar außerhalb der Glossarsprachen, einem Tonfall ohne Formalität, einem nur teilweise aufgeführten Code |
| Google Cloud Translation | Seine mitgelieferte Sprachtabelle | Eine nicht aufgeführte Sprache | Jedem Glossar, einem Tonfall formal oder informal, einem regionalen Code, der nur als Sprache aufgeführt ist |
| LibreTranslate | Nichts vor einem Lauf; mit doctor --live das /languages des Servers | Nie | Jeder Ziel-Locale bei jedem Lauf, jedem Glossar, einem Tonfall formal oder informal |
| Anthropic, OpenAI, Gemini, OpenCode, openai-compatible | Nichts: Ein LLM akzeptiert jede Sprache | Nie | Einer Sprache außerhalb der gut getesteten Liste |
| none | Entfällt | Nie | Nie |
Eine nicht unterstützte Locale wird mit LOCALE_ (Exit 2) abgelehnt, bevor ein Provider erzeugt wird; eine Warnung lehnt nie ab und erscheint als Hinweis. verbatra doctor meldet jedes Urteil, und sein Flag --live prüft gegen die aktuelle Liste des Providers, aber translate verwendet immer die mitgelieferte Tabelle. Für eine seitdem ergänzte Sprache bilde die Locale in localeMap ab: Ein expliziter Code wird mit einer Warnung gesendet, nicht abgelehnt.
Strukturierte Fehler
Ein Provider-Fehlschlag erscheint als strukturierter, geheimnisfreier Fehler, der nur seinen eigenen Sub-Batch betrifft. Ein PROVIDER_ nennt nur Host und Port einer baseUrl von openai-compatible oder LibreTranslate, und bei Google nur translation.googleapis.com, nie den Query-String mit seinem Key.
Ausgabe-Token-Limits
Die LLM-Provider begrenzen die Tokens jeder Antwort; ein Modell, das an der Grenze stoppt, erzeugt OUTPUT_. verbatra teilt einen abgeschnittenen Sub-Batch in Hälften, bis hinunter zu einem Eintrag, und hält nur einen Eintrag zurück, der weiterhin überläuft. Um das dauerhaft zu beheben, senke maxBatchSize oder erhöhe maxTokens (Anthropic) beziehungsweise maxOutputTokens. Ein Reasoning-Modell verbraucht verborgene Reasoning-Tokens aus demselben Budget, gib ihm also reichlich Spielraum.
Review-Flags
Eine verdächtige Übersetzung wird bei jedem Provider zum Review markiert, nicht abgelehnt. Siehe Review-Gründe und In Studio prüfen.
Auf GitHub bearbeiten