I needed to localize product announcements for five markets without hiring five copywriters. In this tutorial I will walk you through the multilingual copy generator I shipped using Oxlo.ai. It benchmarks multiple open models against the same prompt so you can pick the best fit for each language pair.
What you'll need
- An Oxlo.ai API key from https://portal.oxlo.ai
- Python 3.10 or newer
- The OpenAI SDK:
pip install openai
Step 1: Initialize the Oxlo.ai client
I started by pointing the OpenAI SDK at Oxlo.ai. Because the platform is fully OpenAI API compatible, this single line change is all it takes.
from openai import OpenAI
client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")
response = client.chat.completions.create(
model="qwen-3-32b",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Say hello in Japanese, Spanish, and German."},
],
)
print(response.choices[0].message.content)
Step 2: Define the system prompt
The system prompt is the only part I tweak more than the code. It constrains tone, prevents literal translation, and enforces cultural adaptation. Here is the version I shipped.
SYSTEM_PROMPT = """You are a multilingual marketing copywriter.
Rules:
- Do not translate literally. Adapt the tone for the target culture.
- Keep the same character limit ratio as the English source.
- Output only the requested copy, no explanations."""
Step 3: Benchmark models against the same prompt
Oxlo.ai carries several strong multilingual models. Rather than guessing, I wrote a small router that sends identical prompts to Qwen 3 32B, Llama 3.3 70B, Kimi K2.6, and DeepSeek V3.2 so I can compare fluency for a given target language. Because Oxlo.ai uses request-based pricing, adding a longer system prompt or testing across multiple models does not inflate costs based on token count. You pay per call, which makes this kind of benchmarking cheap and predictable.
def benchmark_models(prompt, models=None):
if models is None:
models = ["qwen-3-32b", "llama-3.3-70b", "kimi-k2.6", "deepseek-v3.2"]
results = {}
for model in models:
resp = client.chat.completions.create(
model=model,
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": prompt},
],
temperature=0.7,
max_tokens=512,
)
results[model] = resp.choices[0].message.content
return results
benchmark_prompt = (
"English: 'Introducing Oxlo.ai. Flat per-request pricing for LLM inference.'\n"
"Generate a catchy one-liner in Brazilian Portuguese."
)
scores = benchmark_models(benchmark_prompt)
for model, text in scores.items():
print(f"\n--- {model} ---\n{text}")
Step 4: Generate structured, localized copy
After running the benchmark, I locked in Qwen 3 32B for CJK languages and Llama 3.3 70B for Romance languages. I then switched the agent to JSON mode so it returns a predictable object containing headline, body, and CTA.
import json
def generate_localized_copy(source_text, target_language, model):
user_msg = (
f"Source (English): {source_text}\n"
f"Target language: {target_language}\n\n"
"Respond with a JSON object containing exactly these keys: "
"headline, body, cta."
)
resp = client.chat.completions.create(
model=model,
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_msg},
],
response_format={"type": "json_object"},
temperature=0.7,
max_tokens=1024,
)
return json.loads(resp.choices[0].message.content)
Step 5: Batch process multiple locales
Finally, I wrapped the generator in a batch processor. It accepts a source English string and a list of target languages, then fans out requests sequentially. In production you could parallelize this with asyncio, but sequential keeps the example readable.
def batch_localize(source_text, locales):
# Map locales to the model that benchmarked best for my workload.
locale_model_map = {
"ja": "qwen-3-32b",
"zh": "qwen-3-32b",
"es": "llama-3.3-70b",
"pt": "llama-3.3-70b",
"de": "kimi-k2.6",
"fr": "deepseek-v3.2",
}
outputs = {}
for locale in locales:
model = locale_model_map.get(locale, "llama-3.3-70b")
outputs[locale] = generate_localized_copy(source_text, locale, model)
return outputs
Run it
Here is the complete entry point and the output I received when localizing a product launch blurb.
if __name__ == "__main__":
source = (
"Ship AI features faster with Oxlo.ai. "
"One flat price per request, no matter how long the prompt."
)
targets = ["ja", "es", "de"]
localized = batch_localize(source, targets)
for locale, content in localized.items():
print(f"\n=== {locale} ===")
print(json.dumps(content, ensure_ascii=False, indent=2))
Example output:
=== ja ===
{
"headline": "Oxlo.aiでAI機能を迅速に展開",
"body": "リクエストごとの均一価格で、プロンプトの長さを気にせず開発を加速。",
"cta": "今すぐ始める"
}
=== es ===
{
"headline": "Lanza funciones de IA más rápido con Oxlo.ai",
"body": "Un precio fijo por solicitud, sin importar la longitud del prompt.",
"cta": "Comienza ahora"
}
=== de ===
{
"headline": "AI-Funktionen schneller mit Oxlo.ai bereitstellen",
"body": "Ein fester Preis pro Anfrage, unabhängig von der Prompt-Länge.",
"cta": "Jetzt starten"
}
Wrap-up and next steps
Two concrete ways to extend this. First, wire the script into a GitHub Action that auto-generates locale files on every pull request. Second, add a feedback loop where native speakers vote results back into a dataset, which you can later use for fine-tuning on Oxlo.ai.
Top comments (0)