Agentes IA Multilingüe en Producción: sin perder el contexto
El agente procesa el mensaje del cliente en español. Llama a una herramienta que devuelve datos en inglés. El agente sigue respondiendo... en inglés.
Nadie lo programó así. Ocurre porque el modelo infiere el idioma de su contexto inmediato, no de la configuración del sistema. Cuando el contexto se contamina, arrastra la respuesta. Este es el problema central de los agentes IA multilingüe en producción: no es un problema de traducción, es un problema de arquitectura.
Por qué detectar el idioma en el input no es suficiente
La solución habitual es detectar el idioma del usuario con una librería y configurar el modelo para que responda en ese idioma. Funciona en conversaciones simples. Se rompe en cuanto hay herramientas de por medio.
Tres escenarios concretos donde falla:
El agente llama a una tool que devuelve texto en inglés. El historial de conversación contiene ahora mensajes en español y resultados de herramienta en inglés. El modelo, que equilibra la atención entre todo el contexto, puede deslizarse al inglés en la siguiente respuesta.
El formato de las herramientas no respeta el locale. Una herramienta de facturación devuelve "date": "11/02/2026". Para un usuario en España, eso es el 11 de febrero. Para el modelo con contexto anglosajón, es el 2 de noviembre. El agente usa ese dato sin convertirlo.
El nivel de formalidad no está configurado. En español existe tú y usted. En alemán du y Sie. Sin instrucción explícita sobre formalidad, el modelo elige según sus defaults de entrenamiento, que suelen ser informales en español y formales en inglés.
El resultado: un agente que mezcla idiomas, usa fechas incoherentes y tutea cuando debería tratar de usted. En producción, esto se percibe como un agente roto aunque su razonamiento sea correcto.
Locale ≠ Language: la distinción que importa
Un locale es es-ES, no es. Contiene idioma, región y convenciones de formato. La arquitectura correcta separa tres capas:
- Detección de locale — determina
es-ES,en-US,fr-FR, etc. - Inyección de contexto — pasa el locale al system prompt con instrucciones explícitas
- Normalización de tool outputs — convierte resultados de herramientas a formatos coherentes antes de que el modelo los procese
interface AgentLocale {
language: string; // "es"
region: string; // "ES"
formality: "formal" | "informal";
dateFormat: string; // "DD/MM/YYYY"
currency: string; // "EUR"
currencySymbol: string; // "€"
}
function buildSystemPrompt(basePrompt: string, locale: AgentLocale): string {
return `${basePrompt}
LOCALE CONFIGURATION:
- Respond always in: ${locale.language}-${locale.region}
- Use ${locale.formality} address forms
- Format dates as: ${locale.dateFormat}
- Currency: ${locale.currencySymbol} (${locale.currency})
- Do not change language regardless of tool output language`;
}
La instrucción Do not change language regardless of tool output language es la clave. Sin ella, el modelo no tiene un ancla explícita y deja que el contenido de las tools influya en su idioma de salida.
Normalizar el output de las herramientas antes de que el modelo lo vea
Las herramientas devuelven datos en el formato que tienen. Normalizarlos es tu responsabilidad, no del modelo.
Un wrapper que aplica el locale al output de cualquier herramienta:
function wrapToolWithLocale<T extends Record<string, unknown>>(
toolFn: () => Promise<T>,
locale: AgentLocale
): () => Promise<T> {
return async () => {
const result = await toolFn();
return normalizeToLocale(result, locale) as T;
};
}
function normalizeToLocale(
data: Record<string, unknown>,
locale: AgentLocale
): Record<string, unknown> {
const normalized: Record<string, unknown> = {};
for (const [key, value] of Object.entries(data)) {
if (isISODate(value)) {
normalized[key] = formatDate(value as string, locale.dateFormat);
} else if (isUSDollarAmount(value)) {
normalized[key] = convertCurrency(value as string, locale);
} else if (typeof value === "string" && isEnglishText(value)) {
normalized[key] = `[${value}]`; // mark for model: don't switch language
} else {
normalized[key] = value;
}
}
return normalized;
}
Este patrón funciona con cualquier herramienta sin modificarla. El locale es una capa de la integración, no una responsabilidad de cada tool individual.
Detección de locale en el pipeline de entrada
La detección no debe ser solo del idioma del texto. Un usuario puede escribir en inglés desde España — en ese caso el locale relevante puede ser en-ES (inglés, con formatos europeos) o es-ES según el contexto de negocio.
async function detectLocale(
userMessage: string,
userProfile?: { country?: string; language?: string }
): Promise<AgentLocale> {
// Preferir configuración explícita del perfil de usuario
if (userProfile?.language && userProfile?.country) {
return buildLocale(userProfile.language, userProfile.country);
}
// Detectar desde el mensaje
const detectedLang = await detectLanguage(userMessage);
// Cadena de fallback: idioma del mensaje → Accept-Language del navegador → default
const region = userProfile?.country ?? getRegionFromBrowser() ?? "ES";
return buildLocale(detectedLang, region);
}
La clave es el fallback chain: no asumir que el idioma del mensaje determina el locale completo. Un cliente español que escribe en inglés sigue esperando fechas en formato europeo y tratamiento formal.
Testing de coherencia de idioma
El test más básico que deberías tener: para cada locale soportado, verifica que el agente responde en ese idioma incluso cuando las herramientas devuelven datos en inglés.
const localeTests = [
{ locale: "es-ES", input: "¿Cuándo vence el contrato?", expected: "es" },
{ locale: "fr-FR", input: "Quand expire le contrat?", expected: "fr" },
{ locale: "de-DE", input: "Wann läuft der Vertrag ab?", expected: "de" },
];
for (const test of localeTests) {
const response = await runAgent(test.input, { locale: test.locale });
const responseLang = detectLanguage(response.text);
expect(responseLang).toBe(test.expected);
}
Este test falla con frecuencia en agentes que no tienen la inyección de locale configurada. Cuando pasa verde de forma consistente —incluyendo casos donde las tools devuelven datos en inglés— el agente es genuinamente multilingüe y no solo "detecta el idioma".
Cómo afecta esto a la calidad percibida en producción
Un agente que mezcla idiomas se percibe como poco fiable aunque su razonamiento sea correcto. Para un cliente de empresa, un agente que responde en inglés cuando escribió en español es un agente roto.
Y el problema escala: si operas en varios mercados europeos, cada mercado tiene sus expectativas de formato, formalidad y convención. Un agente configurado solo para inglés-americano comete errores de forma consistente en todos los demás.
En nuestros proyectos de integración de IA para empresas con operaciones internacionales, construimos la capa de locale como parte del diseño del agente desde el día uno — no como un parche posterior. La diferencia entre hacerlo bien desde el inicio y arreglarlo en producción cuando hay usuarios reales es habitualmente varias semanas de trabajo de depuración.
Si estás construyendo un agente que atiende clientes en varios idiomas o planeas expandir a nuevos mercados, esta arquitectura evita una clase entera de bugs que no aparecen en staging pero sí con usuarios reales.
¿Quieres que revisemos cómo está configurado el tuyo y qué necesita para ser genuinamente multilingüe?