Translation APIs often choke on nuance, idioms, and domain-specific terms. I built a small translation agent that preserves tone and terminology across long documents, running on Oxlo.ai so the cost stays flat even when I feed it entire manuals at once.
What you'll need
- Python 3.10+
pip install openai- An Oxlo.ai API key from https://portal.oxlo.ai
- A sample text file, or use the inline example below
Step 1: Set up the Oxlo.ai client
I initialize the OpenAI SDK pointing at Oxlo.ai. I default to qwen-3-32b because Oxlo.ai lists it as their multilingual reasoning specialist, but you can swap in llama-3.3-70b or kimi-k2.6 depending on latency or quality needs.
from openai import OpenAI
client = OpenAI(
base_url="https://api.oxlo.ai/v1",
api_key="YOUR_OXLO_API_KEY"
)
Step 2: Write the system prompt
This system prompt is the only training the agent gets. I keep it strict: translate faithfully, preserve markdown and formatting, and never add commentary.
SYSTEM_PROMPT = """You are a professional translator. Follow these rules exactly:
1. Translate the user's text from the source language to the target language.
2. Preserve all formatting, markdown, line breaks, and code blocks unchanged.
3. Maintain the original tone (formal, casual, technical, or marketing).
4. Do not add explanations, preambles, or notes. Output only the translated text.
5. Keep domain-specific terms consistent with standard industry usage in the target language."""
Step 3: Build the core translation function
This wrapper sends the source and target language as part of the user message so the same prompt works for any language pair. I keep temperature low to reduce hallucination.
def translate(text: str, source_lang: str, target_lang: str, model: str = "qwen-3-32b") -> str:
user_message = f"Translate from {source_lang} to {target_lang}:\n\n{text}"
response = client.chat.completions.create(
model=model,
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_message},
],
temperature=0.3,
)
return response.choices[0].message.content
Step 4: Chunk long documents
Translating an entire file in one request can dilute focus. I chunk by paragraph and translate each block separately. Because Oxlo.ai charges per request, not per token, chunking does not blow up the bill the way it would on token-based providers.
def chunk_text(text: str, max_chars: int = 2000) -> list[str]:
paragraphs = [p for p in text.split("\n\n") if p.strip()]
chunks = []
current = ""
for p in paragraphs:
if len(current) + len(p) > max_chars and current:
chunks.append(current.strip())
current = p
else:
current += "\n\n" + p if current else p
if current:
chunks.append(current.strip())
return chunks
def translate_document(text: str, source_lang: str, target_lang: str) -> str:
chunks = chunk_text(text)
translated = []
for chunk in chunks:
result = translate(chunk, source_lang, target_lang)
translated.append(result)
return "\n\n".join(translated)
Step 5: Pin terminology for consistency
For technical docs, I extract key terms first, then inject them into every chunk. This stops the model from translating "container" one way in paragraph one and differently in paragraph ten.
def extract_terminology(text: str, source_lang: str, target_lang: str) -> str:
prompt = f"""List up to 20 key technical terms in this {source_lang} text that must be translated consistently into {target_lang}.
Return only a glossary in this exact format:
Term: Translation
Text:
{text[:4000]}
"""
response = client.chat.completions.create(
model="qwen-3-32b",
messages=[
{"role": "system", "content": "You are a terminology extraction assistant."},
{"role": "user", "content": prompt},
],
temperature=0.2,
)
return response.choices[0].message.content
def translate_with_glossary(text: str, source_lang: str, target_lang: str) -> str:
glossary = extract_terminology(text, source_lang, target_lang)
chunks = chunk_text(text)
results = []
for chunk in chunks:
user_msg = f"Use this glossary for consistency:\n{glossary}\n\nTranslate from {source_lang} to {target_lang}:\n\n{chunk}"
response = client.chat.completions.create(
model="qwen-3-32b",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_msg},
],
temperature=0.3,
)
results.append(response.choices[0].message.content)
return "\n\n".join(results)
Run it
Here is a short technical sample. The agent translates the prose while leaving the Docker command untouched.
if __name__ == "__main__":
sample = """Welcome to the platform.
To deploy your container, run the following command:
docker run -d --name my-app my-image:latest
Ensure your environment variables are set correctly."""
result = translate_with_glossary(sample, "English", "German")
print(result)
Expected output:
Willkommen auf der Plattform.
Um Ihren Container bereitzustellen, führen Sie den folgenden Befehl aus:
docker run -d --name my-app my-image:latest
Stellen Sie sicher, dass Ihre Umgebungsvariablen korrekt gesetzt sind.
Wrap-up
This agent gives you context-aware translation with flat per-request pricing on Oxlo.ai, which makes it cost-predictable for bulk or long-context workloads. See Oxlo.ai pricing for plan details.
Two concrete next steps: wrap the translate_with_glossary function in a FastAPI endpoint to serve real-time translation requests, or switch to kimi-k2.6 and pass base64 images to translate text inside screenshots or PDFs.
Top comments (0)