[🛠] Por qué el Codex Goal del blog multilingüe pasó de 13 horas
✨ Resumen de GPT-5.5
Registro de la ejecución del Codex Goal que llevó hyuk.blog de una versión inglesa /en/ a reglas de operación para ocho locales, revisando calidad de traducción, cambio de idioma, vistas compartidas, la regla p y el costo de uso.
Al principio pensé que solo había que elegir /en/
La primera pregunta era simple.
¿Sería mejor en.hyuk.blog?
¿Sería mejor /en/?
Después de sopesar SEO, operación en GitHub Pages, la conexión entre original y traducciones, las vistas compartidas y la estructura de idiomas para futuras expansiones, la conclusión fue /en/.
No quería operar la versión inglesa como un producto completamente separado. Este blog parte de textos originales en coreano y añade traducciones. En ese caso, separar las URL de idioma dentro del mismo dominio y conectarlas con hreflang es más sencillo.
Pero no terminó ahí.
En cuanto elegí /en/, la home, About, categorías, búsqueda, sitemap, language switcher, conteos de vistas, calidad de traducción y la forma de hacer push de futuros posts empezaron a moverse juntas.
No era un archivo traducido, era un límite de collection
Los posts en inglés no podían mezclarse dentro de _posts.
En Jekyll, _posts entra en site.posts. Si los posts en inglés se mezclan ahí, la home coreana, el feed, la paginación y los related posts también los consumen en silencio. Parece un post más, pero en realidad contamina todo el índice del blog.
Por eso los posts traducidos se separaron en collections por locale.
_posts/... -> /daily-review/.../
_en_posts/... -> /en/daily-review/.../
_ja_posts/... -> /ja/daily-review/.../
_zh_hans_posts/... -> /zh-Hans/daily-review/.../
La primera lección fue clara.
Un blog multilingüe no consiste en añadir archivos traducidos. Consiste en definir límites de collection.
Archivo del Goal de aquella ejecución
El trabajo empezó el 7 de junio de 2026 y continuó hasta el 8 de junio de 2026.
Al principio parecía que solo estaba añadiendo una versión inglesa. El Goal creció enseguida hasta esto.
Convertir hyuk.blog en un blog multilingüe operable con ko como locale base y en, ja, zh-Hans, es, pt-BR, fr e id como locales extendidos.
No detenerse en la traducción. Alinear UI, routing, SEO, sitemap, search, language switcher, vistas compartidas y today dedupe.
Elegir idiomas considerando Tadak Bible, valor de portfolio, población cristiana y capacidad de expansión.
No usar APIs de traducción pagas.
Usar el estándar de workers/subagents GPT más reciente para traducción.
No confiar en traducciones locales de baja calidad.
No traducir antes de confirmar el original coreano.
Al modificar un post y ejecutar p, sincronizar también las traducciones de active locales.
Ejecutar build al final, no después de cada batch de traducción.
El Goal en sí no estaba mal.
El problema fue que no se redujo a reglas ejecutables. Reportes de estado, puntos de revisión y alcance de traducción siguieron pegándose hasta hacerlo demasiado grande.
La calidad de traducción golpeó fuerte
La traducción fue el primer lugar donde se rompió la confianza.
Al principio pensé que bastaba con traducir muchos posts en bloque. Pero en una muestra apareció un archivo con instrucciones del prompt mezcladas como contenido traducido.
Return only the translated content. Do not add notes or fences.
Eso no era un par de frases raras. Significaba que no podía confiar en la ruta de generación.
Entonces revisé con muestras si convenía salvar traducciones malas mediante revisión o regenerarlas. La conclusión fue regenerar. Salidas locales de herramientas como Ollama o Argos no eran lo bastante confiables para posts públicos. Importaba menos la velocidad que el modelo usado y la puerta de revisión superada.
La regla que quedó es clara.
En traducción, la ruta de confianza va antes que el porcentaje completado.
No traducir antes de confirmar la fuente.
No rellenar traducciones públicas con MT local de baja calidad.
También se movieron el cambio de idioma y las vistas
Las páginas en inglés abrían por URL directa.
Pero el usuario no encontraba el cambio coreano/inglés.
Al principio puse English / Korean dentro del menú normal. Existía en el HTML, pero el usuario no lo veía. En móvil era peor. De ahí salió la regla: el cambio de idioma no es un ítem de menú, sino un global control.
Las vistas tampoco eran tan simples.
Un post en inglés no es otro post. Es la traducción del mismo post. /daily-review/x/ y /en/daily-review/x/ no deben usar claves de vista distintas. Por eso el data-page-view-path del HTML, el JS del cliente y el Cloudflare Worker cuentan las vistas por canonical path después de quitar el locale prefix.
Aquí el trabajo también creció. No bastaba con corregir el código del Worker. Había que desplegarlo con Wrangler CLI, y el dry-run mostró una señal de que el binding D1 DB podía faltar. Así que fijé el entrypoint del Worker y el binding D1 en wrangler.toml, confirmé que el binding estaba presente y solo entonces desplegué.
La parte importante era today dedupe.
Leer el mismo post en coreano y luego cambiarlo a inglés no debe incrementar today dos veces. Si la canonical page es la misma, la dedupe key también debe ser la misma.
Por qué completar el Goal en Codex pasó de 13 horas
Esto no significa que el desarrollo puro por sí solo haya tomado 13 horas.
El problema fue que el Goal abierto en Codex tardó más de 13 horas en llegar al estado de completado.
No fue solo por la cantidad de trabajo. Hubo juicios que se movieron.
Intenté sostener la traducción completa y la revisión al mismo tiempo. El criterio osciló entre “generar todo primero y revisar después” y “revisar mientras avanzamos”. Confié en la calidad antes de confirmar el modelo del worker, y cuando aparecieron malas traducciones hubo que rehacerlas.
Traducir antes de confirmar la fuente también fue un problema.
Si el post coreano público sigue cambiando, las traducciones hechas antes obviamente se desalinean. Eso llevó a reescribir la fuente, tirar traducciones existentes y traducir otra vez.
El criterio de build también se movió.
Si se ejecuta build después de cada batch de traducción, el trabajo no termina. Build es una verificación importante, pero no un ritual para repetir cada vez. Primero hay que fijar la fuente y el alcance de traducción; después, cerca del final, correr las verificaciones necesarias.
El significado de p también quedó claro tarde.
Ahora, si hay cambios de post, p no es solo commit y push. Significa sincronizar las traducciones de active locales para la fuente confirmada y luego hacer push.
El uso también fue costo
Este trabajo de traducción no se resolvía solo evitando APIs pagas.
La asignación semanal Pro x20, que había pagado apenas el día anterior, bajó de 100% a 50% en dos días.
Ese consumo fue el costo de generar traducciones en paralelo sin fijar criterios, regenerar traducciones fallidas y traducir de nuevo después de cambiar la fuente. No usar APIs de traducción pagas no vuelve el costo cero. Uso de modelo, tiempo, concentración y fatiga de revisión también son costos.
Por eso primero hay que fijar esto.
confirmación de la fuente
alcance de traducción
método de revisión
momento del build
criterio de push
Si esos cinco puntos están borrosos, el trabajo multilingüe crece otra vez muy rápido.
Las reglas operativas que quedaron
Las reglas que quedaron importan más que la función.
Las URL de idioma se separan dentro del mismo dominio.
Los posts traducidos viven en locale collections.
En traducción, la ruta de confianza va antes que el porcentaje completado.
No traducir antes de confirmar la fuente.
El cambio de idioma debe ser un global control siempre visible.
Las vistas y today dedupe se basan en la canonical page.
Al ejecutar p para posts, incluir la sincronización de active locales.
Ejecutar build al final para el alcance necesario, no después de cada batch.
Los Goals deben reducirse a reglas ejecutables, no crecer como reportes de estado largos.
Añadir la versión inglesa importó.
Pero el resultado más importante fue el estándar para mantener el blog operable mientras se vuelve multilingüe.
Lo aprendí caro.
Pero era un estándar necesario.
Deja un comentario