Model Routing en Agentes IA: Elige el Modelo por Tarea
La semana pasada revisé los logs de un equipo que llevaba cuatro meses con su agente en producción. Cada llamada pasaba por Claude Opus. Clasificaciones de intención, formateo de respuestas, validaciones simples: todo al modelo más caro.
El resultado: 2.300€ mensuales en API. Y más del 70% de esas llamadas eran tareas que Haiku habría resuelto igual de bien en una décima del tiempo y a un 80% menos de coste. El problema no era la IA. Era la arquitectura.
El error más caro en producción: un modelo para todo
Cuando un equipo empieza a construir agentes, la decisión lógica es usar el modelo más potente disponible. La calidad es alta, los resultados son buenos, el cliente está contento. Pero nadie se pregunta qué porcentaje de las llamadas realmente necesitan ese nivel de potencia.
Un agente típico de gestión de clientes hace, por ejemplo:
- Clasificar la intención del mensaje entrante → trivial
- Extraer el número de pedido del texto → trivial
- Validar si la respuesta cumple el formato esperado → trivial
- Resumir un hilo largo de emails → medio
- Redactar una propuesta personalizada de resolución → complejo
Las tres primeras representan el 75-80% del volumen. Si todas van al mismo modelo que la última, estás multiplicando por 10 el coste de operaciones que no lo requieren.
Qué es el model routing y cómo se implementa
El model routing es el patrón arquitectónico que asigna cada llamada LLM al modelo óptimo según su complejidad real. En su forma más simple, hay un clasificador — a menudo el propio modelo más ligero — que evalúa la tarea entrante y decide qué ruta tomar.
type TaskComplexity = 'low' | 'medium' | 'high';
const COMPLEXITY_SIGNALS: Record<TaskComplexity, string[]> = {
low: ['extract', 'classify', 'format', 'validate', 'check', 'parse'],
medium: ['summarize', 'translate', 'rewrite', 'compare', 'filter'],
high: ['generate', 'analyze', 'design', 'reason', 'strategize'],
};
function detectComplexity(taskDescription: string): TaskComplexity {
const normalized = taskDescription.toLowerCase();
for (const [level, signals] of Object.entries(COMPLEXITY_SIGNALS) as [TaskComplexity, string[]][]) {
if (signals.some(s => normalized.includes(s))) return level;
}
return 'medium';
}
const MODEL_MAP: Record<TaskComplexity, string> = {
low: 'claude-haiku-4-5-20251001',
medium: 'claude-sonnet-4-6',
high: 'claude-opus-5',
};
async function routedCall(taskDescription: string, prompt: string) {
const complexity = detectComplexity(taskDescription);
const model = MODEL_MAP[complexity];
const response = await anthropic.messages.create({
model,
max_tokens: complexity === 'low' ? 256 : 1024,
messages: [{ role: 'user', content: prompt }],
});
return { response, model, complexity };
}
Esto no es magia: es software de clasificación aplicado a decisiones de infraestructura. Igual que no usas una base de datos distribuida para guardar diez filas de configuración, no uses tu modelo más caro para extraer un número de un texto.
Las matemáticas que nadie hace hasta que la factura duele
Con 10.000 llamadas diarias y un mix realista de tareas:
| Complejidad | % del volumen | Modelo | Coste/MTok input |
|---|---|---|---|
| Bajo | 65% | Haiku | $0,80 |
| Medio | 25% | Sonnet | $3,00 |
| Alto | 10% | Opus | $15,00 |
Sin routing, todo en Sonnet: ~$35/día → ~1.050€/mes
Con routing: ~$12/día → ~360€/mes
Diferencia: 690€ al mes, sin cambiar una línea de lógica de negocio. Y sin contar la latencia. Haiku responde en ~0,3s promedio. Opus puede tardar 8-12 segundos en razonamientos complejos. Un routing correcto reduce el tiempo de respuesta percibido en toda la aplicación, no solo en el coste.
Si tienes agentes en producción con coste o latencia que no entiendes, el servicio de integración IA incluye auditoría de arquitectura de llamadas y diseño del patrón de routing desde el día uno.
Dónde NO aplicar model routing
El routing no es gratis: añade una capa de decisión y puede clasificar mal. Hay contextos donde es mejor no usarlo:
Decisiones de seguridad. Si el agente decide si un usuario puede acceder a datos sensibles, no enrutes. Usa siempre tu modelo más robusto.
Generación visible para el usuario final. Si el output del LLM va directamente al cliente como respuesta oficial, la calidad no es negociable.
Volúmenes bajos. Por debajo de 2.000-3.000 llamadas diarias, el ahorro no justifica la complejidad de mantener el router.
Cuando el coste de un error supera el ahorro. Si una mala clasificación envía una tarea compleja a Haiku y el resultado es incorrecto, el coste operativo del error puede superar el beneficio.
Versión avanzada: router basado en LLM
Una vez tienes el router básico funcionando, la siguiente evolución es usar el propio Haiku para clasificar la complejidad. Cuesta fracciones de céntimo extra por llamada pero es mucho más robusto ante variaciones en el lenguaje:
async function llmRouter(taskDescription: string): Promise<TaskComplexity> {
const response = await anthropic.messages.create({
model: 'claude-haiku-4-5-20251001',
max_tokens: 10,
messages: [{
role: 'user',
content: `Classify this task as "low", "medium", or "high" complexity. Reply with one word only.\n\nTask: ${taskDescription}`,
}],
});
const result = (response.content[0] as { text: string }).text.trim().toLowerCase();
return (['low', 'medium', 'high'].includes(result) ? result : 'medium') as TaskComplexity;
}
Con un fallback automático: si Haiku falla o su output no supera un umbral de confianza, reintenta con Sonnet. Así el routing es transparente para el resto del sistema.
El servicio de AI Driven Development cubre exactamente este tipo de patrones: diseño de arquitecturas de agentes que escalan sin que la factura escale con ellas.
Qué medir una vez que el router está en producción
El router necesita su propia telemetría. Como mínimo:
- Distribución de complejidades por hora — ¿está derivando hacia más llamadas "alto"?
- Tasa de errores por nivel — ¿Haiku falla más en ciertos tipos de tarea?
- Latencia p50/p95 por modelo — valida que el beneficio de latencia es real
- Coste diario desglosado — la métrica que justifica el patrón ante cualquier stakeholder
Sin esos datos, el router se convierte en otra caja negra. Y eso es exactamente lo que intentas evitar.
Conclusión
El model routing es uno de esos cambios arquitectónicos que muchos equipos posponen porque "ya funciona así". Pero es exactamente por eso que se acumulan costes de API que nadie justifica y tiempos de respuesta que nadie entiende.
No es un refactor complejo. Es añadir una capa de clasificación y un mapa de modelos. El retorno aparece en la factura del mes siguiente.
Si tienes agentes en producción y no sabes cuánto te cuesta cada tipo de llamada ni cuánto de ese coste es necesario, hablamos en 30 minutos.