Un sitio que habla decenas de idiomas, sin traductores
Traducido automáticamente del italiano · leer el original
Cómo construimos el sistema de traducción que funciona bajo estas páginas: IA cuando es necesario, caché siempre, cero espera percibida.
El problema de la i18n tradicional
Durante años, la internacionalización de un sitio web ha sido una pequeña odisea de flujo de trabajo: archivos .po, traductores humanos, claves olvidadas, despliegues retrasados porque "todavía falta el alemán". Agregar un idioma costaba tiempo y dinero; agregar diez estaba fuera de discusión para cualquier pequeña empresa.
Con los LLM de última generación, la calidad de la traducción automática ha llegado a un punto en el que —para un sitio corporativo, no para la literatura— es suficiente. La pregunta ya no es "¿podemos traducirlo automáticamente?", sino "¿cómo lo integramos sin romper la experiencia del usuario?"
La arquitectura, en resumen
El sitio se sirve estáticamente en italiano. Cuando un usuario elige otro idioma, entra en juego un pequeño motor sobre tres colecciones MongoDB:
i18n_base: los textos fuente en el idioma elegido (hoy italiano), cada uno con la declaración de su propio idioma, una descripción de dónde y por qué aparece en el sitio (esencial para la calidad de la traducción), tono y límite de caracteres. Esta descripción se convierte en parte del prompt al LLM, que así sabe si está traduciendo un botón o un párrafo.i18n_human: las traducciones revisadas a mano, cuando para alguna página queremos calidad editorial en lugar de la salida LLM. Tienen prioridad sobre la caché automática y se "desmarcan" automáticamente cuando el texto fuente cambia.i18n_cache: las traducciones ya generadas, indexadas por (campo, idioma). Cada entrada conserva el timestamp del texto base en el momento de la generación.articoli_i18n: misma lógica aplicada a los contenidos más largos, como este artículo.
En el primer acceso en un nuevo idioma, el sistema solicita al LLM solo los campos realmente faltantes, guarda la respuesta en la caché y la devuelve al navegador. En las visitas posteriores, el mismo idioma llega instantáneamente, sin más llamadas a la IA.
La invalidación que funciona
Una caché es una mentira ordenada: dice "mi verdad es esta" hasta que alguien la desmiente. El mecanismo de desmentido aquí es simple: cada traducción en caché almacena el timestamp del texto base que la generó. Cuando modificas el texto italiano y aumentas su updated_at, todas las traducciones de ese campo en todos los idiomas resultan automáticamente obsoletas y se regeneran según sea necesario. Cero cascadas manuales, ninguna caché que vaciar.
El usuario que no espera
La parte más interesante no es la traducción — es cómo se muestra. Al cambiar de idioma, el navegador tiene delante una página italiana con pequeños spinners junto a cada bloque de texto a actualizar. La tentación es hacer una sola llamada que traduzca todo junto: simple, limpio, y condena al usuario a esperar a que el LLM termine todo antes de ver cualquier cambio.
Hemos tomado la dirección opuesta. Los textos se agrupan por sección (navbar, cuerpo, footer) y se dividen en micro-batches de tres campos cada uno. Las llamadas parten en secuencia: primero los pocos campos de la navbar, que aparecen en pocos segundos — el usuario ve que algo está sucediendo y empieza a leer. Mientras lee, llega el primer trozo del cuerpo, luego el segundo, finalmente el footer.
El trabajo nocturno
Una caché tiene un solo verdadero enemigo: la primera visita. El primer usuario alemán paga el precio de todas las traducciones futuras, y su experiencia es la que le queda grabada en la mente. Para eliminar (o casi) el problema, una tarea en segundo plano se despierta cada minuto, elige el idioma más esperado entre los aún incompletos, toma un texto no traducido y lo hace pasar por el LLM. Al minuto siguiente, el próximo. En pocos días los idiomas más difundidos ya están listos.
La tarea nocturna también hace un segundo trabajo: revisa automáticamente las traducciones de calidad dudosa, intentándolas de nuevo con un modelo de IA diferente. Cuando la alineación entre idiomas es importante, una traducción mediocre no se queda así.
Si eres el primer alemán del día y llegas mientras el sistema aún está ultimando la caché, aún tienes la carga progresiva para mantenerte ocupado. Si eres el segundo, ni siquiera te das cuenta.
Qué se lleva uno
Un sitio multilingüe sin traductores, sin archivos que gestionar, sin despliegues para añadir un idioma. El usuario introduce un código — ja, ca, eu, el que quiera — y la página se traduce. La segunda vez es instantánea. A la tercera, muy probablemente ya hemos llegado nosotros, traducida al minuto justo por una tarea que no duerme nunca.
Esta misma página, si la estás leyendo en alemán, en español, en coreano, no ha sido escrita ninguna vez por un traductor. Ha sido traducida una sola vez, por un LLM, y desde entonces se ha servido desde la caché. La única cosa escrita a mano es lo que estás leyendo ahora si está en italiano.
¿Interesado en llevar esta arquitectura a tu sitio? Hablemos de ello.
Contáctanos
¿Tienes una observación? Escríbenos
El mensaje llega solo para nosotros. Si tu comentario es interesante, podríamos publicarlo al final del artículo, pero solo tras evaluarlo.
Mientras escribes, tu navegador resuelve un pequeño cálculo: es nuestra forma de evitar el correo automático sin usar servicios externos ni pedirte que identifiques semáforos. No se te solicita nada y ningún dato sale de este sitio.