Document Translation
Translate extracted documents into any language for normalized downstream processing. Extracted text, formatted markup, and chunks all translate together, keeping your search and retrieval indices in a single language.
When to Use
Section titled “When to Use”- You ingest documents in mixed languages and want a single normalised language for downstream search or analytics.
- You need per-chunk translation aligned with retrieval-augmented generation (RAG) indexes.
- You need Markdown/HTML preserved through translation (
preserve_markup = true).
When Not to Use
Section titled “When Not to Use”- You only need machine-translation of short user queries. Call the LLM provider directly.
- You need a deterministic, network-free pipeline. Translation always calls an LLM.
Configuration
Section titled “Configuration”import asynciofrom xberg import ExtractInput, extract, ExtractionConfig, TranslationConfig, LlmConfig
async def main() -> None: config = ExtractionConfig( translation=TranslationConfig( target_lang="de", preserve_markup=True, llm=LlmConfig(model="openai/gpt-4o-mini"), ), ) result = await extract(ExtractInput(uri="contract.pdf"), config) if result.results[0].translation: print(result.results[0].translation.content)
asyncio.run(main())import { extract } from '@xberg-io/xberg';
const output = await extract({ kind: "uri", uri: "contract.pdf",}, { translation: { targetLang: "de", preserveMarkup: false, llm: { model: "openai/gpt-4o-mini" }, },});if (output.results[0].translation) { console.log(output.results[0].translation.content);}use xberg::{extract, ExtractionConfig, ExtractInput, TranslationConfig, LlmConfig};
#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> { let config = ExtractionConfig { translation: Some(TranslationConfig { target_lang: "de".to_string(), source_lang: None, preserve_markup: false, llm: LlmConfig { model: "openai/gpt-4o-mini".to_string(), ..Default::default() }, }), ..Default::default() }; let output = extract(ExtractInput::from_uri("contract.pdf"), &config).await?; if let Some(translation) = &output.results[0].translation { println!("{}", translation.content); } Ok(())}[translation]target_lang = "de"preserve_markup = false
[translation.llm]model = "openai/gpt-4o-mini"Preserve Markup
Section titled “Preserve Markup”Set preserve_markup = true to translate formatted_content (Markdown / HTML) without losing formatting. The LLM is prompted to keep code fences, links, lists, and tables intact.
from xberg import ExtractionConfig, TranslationConfig, LlmConfig
config = ExtractionConfig( translation=TranslationConfig( target_lang="de", source_lang="en", preserve_markup=True, llm=LlmConfig(model="openai/gpt-4o"), ),)Language Codes
Section titled “Language Codes”target_lang is a BCP-47 tag. Common values:
| Tag | Language |
|---|---|
en |
English |
de |
German |
fr |
French |
fr-CA |
French (Canada) |
es |
Spanish |
zh |
Chinese |
ja |
Japanese |
ar |
Arabic |
pt-BR |
Portuguese (Brazil) |
source_lang follows the same format; leave None for auto-detection.
Output Shape
Section titled “Output Shape”{ "translation": { "target_lang": "de", "source_lang": "en", "content": "Der Vertrag legt eine dreijährige Supportvereinbarung mit vierteljährlicher Abrechnung fest.", "formatted_content": "# Vertrag\n\nDie Laufzeit beträgt drei Jahre…" }}Chunks (when chunking is enabled) carry the translated text in place — result.chunks[i].content holds the translated chunk, not the source.
Provider Setup
Section titled “Provider Setup”Pick any liter-llm provider — see LLM Integration. For high-quality translation, gpt-4o, claude-3-5-sonnet, and google/gemini-2.5-pro are typical picks; gpt-4o-mini works for short documents.
API-key precedence:
TranslationConfig.llm.api_keyXBERG_LLM_API_KEY- Per-provider env var
Related
Section titled “Related”- LLM Integration — provider matrix
- Document Summarisation — sibling LLM post-processor
- Configuration Reference