Un artículo en 19 idiomas: estructura de archivos, prompt de traducción, 5 trampas reales, cómo hacer POST de una vez.
La documentación oficial de Anthropic y OpenAI está solo en inglés. Es una enorme laguna en el ecosistema de contenido global para desarrolladores de IA. how2claude está llenando ese hueco — cada artículo sale en 19 idiomas a la vez: zh / en / zh-TW / ja / ko / es / pt-BR / id / vi / tr / ar / fr / de / it / ru / uk / pl / he / th.
Contratar humanos no es viable (20 traducciones por artículo, miles de dólares cada una). Dejar que Claude lo haga reduce el coste marginal casi a cero — pero lanzar "tradúcelo al japonés" por encima de la valla te devuelve texto con sabor a traducción automática y la voz del autor desaparecida. Lo que sigue es el flujo completo para hacerlo bien: estructura de archivos, cómo escribir el prompt de traducción, dónde Claude seguro que falla, cómo hacer POST de 19 idiomas más tuits por idioma a la API en una sola llamada.
Dos cosas muy distintas.
Traducción mueve significado de idioma A a B — lo que hace Google Translate. Se lee "correcto" pero "plano".
Localización preserva el registro, ritmo y nivel técnico del autor, reescribiendo con la "voz de blog técnico" propia del idioma objetivo. Se lee como si hubiera sido escrito nativamente.
Traducir es un trabajo de 5 minutos para Claude; la localización requiere que el prompt deletree:
El comando /write-article de how2claude lleva incorporado un requisito de estilo por idioma:
| Archivo de idioma | Requisito de estilo |
|---|---|
ja.md |
Voz de blog técnico, japonés natural |
ko.md |
Voz de blog técnico, coreano natural |
zh-TW.md |
Uso taiwanés, caracteres tradicionales |
ar.md |
Árabe estándar moderno (escrito) |
id.md |
Indonesio estándar |
Parece una línea más. Pero para Claude es decisiva — sin ella, por defecto produce "traducción de libro de texto".
Un directorio por borrador, 20 archivos:
docs/drafts/let-claude-translate-articles/
├── meta.json # title + summary de los 19 idiomas
├── zh.md # chino (fuente, escrito primero)
├── en.md # inglés (primera tanda de traducciones)
├── zh-TW.md
├── ja.md
├── ko.md
├── ...(14 más)
└── th.md
meta.json:
{
"category_slug": "use-cases",
"series_slug": "writing",
"free": true,
"title": {
"zh": "让 Claude 把一篇文章翻译成 19 种语言",
"en": "Letting Claude Translate One Article Into 19 Languages",
"es": "Dejar que Claude traduzca un artículo a 19 idiomas",
"...": "..."
},
"summary": {
"es": "Un artículo en 19 idiomas: estructura de archivos, prompt de traducción, 5 trampas reales, cómo hacer POST de una vez.",
"...": "..."
}
}
La primera línea de cada archivo .md es # título, lo demás es cuerpo. El title no se saca de la primera línea del md — se saca de meta.json, así cada idioma tiene un título pulido en lugar de la frase inicial del artículo que puede haberse alargado al traducir.
Dos flujos a evitar:
Mal: traducción encadenada. zh → en → ja → ko → ...
Problema: ja se basa en en, ko en ja — cada salto pierde un poco de significado. Para cuando llegas a th (tailandés), es información de cuarta mano.
Bien: traducción radial. Finalizar zh → generar en / ja / ko / ar / id / ... directamente desde la fuente.
Todos los idiomas salen del original, sin saltos intermedios.
Forma del prompt (empaquetada dentro de /write-article):
Este es un artículo de blog técnico sobre X, fuente en chino:
[zh.md completo]
Tradúcelo a estos idiomas, con estos requisitos por idioma:
- ja.md: voz de blog técnico, japonés natural
- ko.md: voz de blog técnico, coreano natural
- ar.md: árabe estándar moderno (escrito)
...
Reglas:
1. Preserva el registro directo, profesional y ligeramente autoirónico del autor
2. No traducir bloques de código, comandos, nombres de API, URLs
3. Títulos, subtítulos y flujo de párrafos pueden recomponerse
4. Produce un title separado por idioma — corto, con gancho, no traducción literal
Traducir 18 idiomas en paralelo, una sesión de Claude. Un detalle clave: hazlo en la misma sesión / misma versión de modelo — la voz se desvía entre sesiones y generaciones de modelo.
X cuenta los caracteres CJK (chino/japonés/coreano) más estrictamente. Hice que Claude generara tuits con esta restricción:
En la primera pasada, tres tuits chinos se pasaron (160, 164, 152). Claude había traducido los tuits en inglés literalmente — un tuit inglés de 260 caracteres se convierte en chino justo en el límite.
Regla: los tuits en chino hay que reescribirlos, no traducirlos. Requisitos: tope 140 caracteres, gancho obligatorio, se permite perder algún detalle.
zh → zh-TW invita a la pereza: pasarlo por un conversor simplificado-a-tradicional. Los caracteres coinciden, el vocabulario no:
| zh | zh-TW (mal) | zh-TW (bien) |
|---|---|---|
| 文件 | 文件 | 檔案 |
| 信息 | 信息 | 資訊 |
| 软件 | 軟件 | 軟體 |
| 视频 | 視頻 | 影片 |
Al pedir zh-TW a Claude, di las dos cosas: "uso taiwanés, caracteres tradicionales". "Solo tradicional" te da una conversión de caracteres.
Árabe y hebreo se leen de derecha a izquierda. En Rails necesitas <html dir="rtl"> y las variantes rtl: de Tailwind. Pero la traducción en sí tiene trampas:
unicode-bidi: isolate o el código queda "absorbido" por el flujo RTL، en vez de ,, ؟ en vez de ?. Claude por defecto usa puntuación inglesa; hay que explicitarlo2026) dentro de un párrafo de derecha a izquierda. Los navegadores lo manejan, pero Claude a menudo lo mezcla al escribir texto crudoLas frases coloquiales del original ("te lo metes de un viaje", "meter la pata", "pillar un hostión") Claude las traduce a japonés/coreano como formas escritas formales (「一気に実装」「落とし穴」「失敗」) — el significado coincide, el tono se evapora.
Arreglo: ponlo por escrito — "preserva la voz de blog técnico directa, ligeramente autoirónica e informal; no academices". Aun así, algunos idiomas (alemán, ruso) van a aterrizar algo más "formal" que la fuente — los propios idiomas tienen sesgo al registro escrito.
Las cadenas en código están en dos cubos — texto UI (traducir) y placeholders/nombres de variables (no):
t("pricing.page_title") # no traducir (i18n key)
"user_id" # no traducir (nombre de variable)
"Monthly subscription" # mostrado como ejemplo en el texto → no traducir
Para cualquier cosa adyacente a código, "no traducir" es el valor por defecto más seguro. Traducir archivos de locale i18n (config/locales/xx.yml) es otro trabajo aparte.
/publish-article hace POST del borrador a how2claude.com/api/articles:
{
"category_slug": "use-cases",
"series_slug": "writing",
"free": true,
"thread": true,
"title": { "zh": "...", "en": "...", "ja": "...", ... },
"summary": { "zh": "...", "en": "...", ... },
"content": { "zh": "<md>", "en": "<md>", ... },
"tweets": { "en": ["...", "..."], "zh": [...], ... }
}
Una petición son ~300KB (19 idiomas × ~15KB). El servidor reparte por tablas:
articles, title / summary / content son jsonb con clave por localex_queue_tweets, por locale + cuenta, despachada a una cola de programaciónLos tuits solo salen a los locales con cuenta de X conectada (actualmente en/zh/ja/ko/ar/id — 6). Los idiomas sin cuenta mandan []. Consultando cuentas:
Account.all.each { |a| puts "#{a.locale}: #{a.name}" }
# en: @how2claude
# zh: @howtoclaude
# ja: @how2claude_ja
# ko: @how2claude_ko
# ar: @how2claude_ar
# id: @how2claude_id
Dejar que Claude traduzca un artículo a 19 idiomas — checklist completo:
dir="rtl" + variantes rtl: de Tailwind en el lado Rails. Puntuación mixta y aislamiento de bloques de código se manejan por separado.El cuello de botella real no es la calidad de la traducción — los modelos clase Claude 4 traducen a japonés/coreano/árabe/ruso con calidad casi nativa. El cuello de botella es si estás dispuesto a poner un artículo frente a lectores de 19 idiomas. Técnicamente son 5 minutos. A nivel de contenido, hace falta voluntad para servir a 200x la audiencia a la vez.