Cadenas de fallback de modelo: la compra de confiabilidad más barata de la plataforma
Tres de la mañana, tu agente de triage de inbox está corriendo sobre Fable 5, el rate-limit del proveedor se activa por noventa segundos, y tu cliente se despierta con doce emails sin procesar porque la llamada devolvió 429 y el agente no tenía a dónde ir. El deployment de producción con un solo modelo es el más frágil de la infraestructura agéntica, y el arreglo más barato es el que no requiere código de tu lado. Pasa models: [a, b, c] en lugar de model: a y el proxy en api.llm4agents.com maneja la cadena de punta a punta. Este post es el deep-dive que el post de migración prometió: cómo funcionan las cadenas del lado del server, los tres headers de respuesta que tienes que loguear, tres cadenas canónicas para distintos workloads, y cuatro anti-patrones que convierten la confiabilidad en pasivo.
Qué hace la cadena realmente
El endpoint OpenAI-compatible /v1/chat/completions en LLM4Agents acepta o el campo estándar model: string o la forma array models: [string, string] o models: [string, string, string]. La forma array es la cadena de fallback. Cuando el proxy recibe una cadena, camina la lista de izquierda a derecha e intenta cada modelo en orden. El intento cuenta como falla (y el proxy pasa al siguiente modelo) ante cualquiera de cuatro condiciones:
Overflow de context-length. La conversación más el system prompt más las descripciones de tools exceden la ventana de contexto del modelo actual. El proxy detecta esto desde la respuesta de error del proveedor y re-intenta con el siguiente modelo de la cadena, que normalmente se elige específicamente porque tiene una ventana más grande.
Rate limit (429). El proveedor rechazó la llamada porque la cuenta llegó al tope por minuto o por día. Esta es la razón más común por la que se dispara un fallback y la razón por la que la cadena existe en primer lugar.
Error del proveedor (5xx). El proveedor upstream devolvió un error interno, un timeout, o cualquier respuesta no recuperable. Fallas transitorias de infraestructura en un proveedor no se convierten en fallas cara al usuario en tu agente.
Rechazo de moderación. El clasificador de contenido del proveedor marcó el request y se negó a generar. Para Claude Fable 5 específicamente, este es ahora el comportamiento de los clasificadores de ciberseguridad, biología o destilación que cubrimos en el resumen del viernes pasado — excepto que ahora tienes un camino de fallback documentado en lugar de un error opaco.
Si todos los modelos de la cadena fallan, el proxy devuelve el último error al caller. El comportamiento esperado en cadenas bien diseñadas es que el último modelo sea tu backup más permisivo y más confiable, así que esta falla terminal representa una caída real en lugar de fragilidad transitoria.
La interacción reserve-proxy-settle
La cadena funciona porque el modelo de billing de la plataforma es reserve-proxy-settle. Cada llamada facturada reserva el costo del peor caso sobre tu balance antes de que el request salga, reenvía el request al proveedor, settla el costo real basado en el usage de la respuesta, y devuelve el delta. Para una cadena, "peor caso" es el modelo más caro del array — el proxy reserva lo suficiente para cubrir que ese modelo responda con el max_tokens pedido.
Esto significa que una cadena no produce cargos sorpresa. Si pides models: [fable-5, sonnet-4.6, gpt-5] y el primario rate-limited dispara fallback a Sonnet, la reserva se computó contra el pricing de Fable 5, la llamada se settló contra el pricing de Sonnet, y tu balance recibió la diferencia de vuelta. El header de respuesta X-Cost-Usd-Cents reporta el costo real, no el reservado. Los operadores que construyeron su modelo de costo alrededor del pricing del primario no necesitan recalcular la matemática solo porque un fallback se dispara ocasionalmente.
Hay un caso sutil que vale la pena destacar. Cuando se dispara un fallback en medio de la cadena después de un intento parcial del proveedor, la llamada fallida no se cobra en absoluto — solo el modelo que produjo una respuesta usable se settla. La reserva cubre la cadena entera aunque solo se pague un modelo. La arquitectura existe exactamente para que la confiabilidad venga sin un impuesto de billing.
Tres headers que tienes que loguear
La cadena es observable desde tres headers de respuesta que tu tracing tiene que capturar desde el día uno. Si solo logueas el body de la respuesta no vas a detectar fallback silencioso.
// Cada llamada facturada devuelve estos
X-Model-Used: anthropic/claude-sonnet-4.6
X-Cost-Usd-Cents: 1.42
X-Balance-Remaining-Cents: 2284
X-Request-Id: req_01J8Q9...
X-Model-Used te dice qué modelo de la cadena efectivamente respondió. Si tu cadena es [fable-5, sonnet-4.6, gpt-5] y el header dice sonnet-4.6, absorbiste una caída de Fable 5 silenciosamente. El dato de trace es el único lugar donde esto se vuelve visible.
X-Cost-Usd-Cents reporta el costo real, settled. Un dashboard de trace que grafica costo por llamada por X-Model-Used te dice la distribución de qué modelo respondió en la última hora, día o mes. La distribución es la historia de confiabilidad; si 99.6% de las llamadas aterrizaron en el primario, la cadena está haciendo su trabajo invisiblemente.
X-Balance-Remaining-Cents es tu visibilidad de runway. El post de economía de fleet argumentó que la visibilidad sobre el costo por llamada es lo que hace predecible a un fleet; este header es la vista por llamada. Combínalo con una alerta a, digamos, 500 centavos para tener un aviso antes de necesitar un depósito.
Combinado con X-Request-Id, tienes todo lo que necesitas para reconstruir qué pasó en cualquier llamada específica. El log de transacciones de la plataforma en /api/v1/transactions es el registro durable de los mismos datos; los headers son la vista por llamada.
Tres cadenas canónicas
La mayoría de los workloads de operador encajan en una de tres formas de cadena. Elige la que matchea la restricción a la que tu fleet es más sensible.
Cadena price-optimized. Cadena por defecto para un fleet donde el costo importa más que la latencia o la identidad del modelo. Empieza barato, escala al mid-tier ante context overflow, salta al frontera solo para los requests que los modelos baratos genuinamente no pueden manejar.
// Price-optimized
models: [
'openai/gpt-5-mini', // $0.40/$1.60 por 1M, 128K ctx
'anthropic/claude-sonnet-4.6', // $3/$15, 1M ctx — target de context overflow
'anthropic/claude-fable-5', // $10/$50, frontera — último recurso
]
En un fleet real, espera que 92-97% de las llamadas aterricen en el primario y paguen precios sub-centavo, 3-7% en Sonnet porque la conversación creció más allá de la ventana del mini, y bastante menos del 1% en Fable 5 solo cuando los tiers más baratos fallan moderación o pegan rate limits. El costo promedio termina cerca del precio del primario, la confiabilidad termina cerca del frontera. Esta es la cadena que recomendamos por defecto.
Cadena latency-optimized. Default para agentes cara-al-usuario donde el time-to-first-token es la experiencia de usuario. Cada eslabón es un modelo cuya latencia de cola es aceptable.
// Latency-optimized
models: [
'anthropic/claude-haiku-4.5', // rápido, capaz para turnos cortos
'openai/gpt-5-mini', // proveedor distinto, velocidad similar
'anthropic/claude-sonnet-4.6', // solo ante rate limit, más lento
]
La cadena de latencia cambia cobertura de modelo por diversidad de proveedor. Quieres el segundo eslabón en un proveedor distinto para que un incidente regional en Anthropic no saque las dos opciones a la vez. Sonnet es el piso: más lento que los primeros dos pero confiable.
Cadena sovereignty-optimized. Para agentes que sirven clientes UE bajo el AI Act o para clientes que contractualmente requieren que sus datos queden en una región específica. La cadena tiene que ser toda-UE o toda-US, no mezclada.
// Cadena EU-only (model ids ilustrativos; verifica /api/v1/models para SKUs UE actuales)
models: [
'mistral/large-2', // primario EU-hosted
'mistral/small-3', // fallback EU-hosted
'anthropic/claude-sonnet-4.6-eu', // fallback con residencia UE si está disponible
]
La cadena de soberanía es donde tienes que verificar la disponibilidad del model id contra GET /api/v1/models en tu cuenta antes de deployar. La propiedad de fallback solo es útil si cada modelo de la cadena cumple la restricción de soberanía; un fallback US-hosted accidental es un incidente de compliance, no una victoria de confiabilidad.
Cómo probar cada eslabón de la cadena
La disciplina de eval-suite del post de evaluación aplica acá con un giro. No puedes probar la cadena como un solo proveedor, porque el fallback solo se dispara bajo condiciones de falla que no provocarías deliberadamente en una eval green-path. Tienes que probar cada eslabón individualmente como su propio provider de Promptfoo, correr la misma suite de eval contra cada uno, y después comparar.
# promptfooconfig.yaml — probar cada eslabón por separado
providers:
- id: openai:chat:openai/gpt-5-mini
config:
apiBaseUrl: https://api.llm4agents.com/v1
apiKey: ${LLM4AGENTS_API_KEY}
- id: openai:chat:anthropic/claude-sonnet-4.6
config:
apiBaseUrl: https://api.llm4agents.com/v1
apiKey: ${LLM4AGENTS_API_KEY}
- id: openai:chat:anthropic/claude-fable-5
config:
apiBaseUrl: https://api.llm4agents.com/v1
apiKey: ${LLM4AGENTS_API_KEY}
tests:
- vars: { email: 'Need sign-off by EOD' }
assert:
- type: contains
value: 'urgent'
Promptfoo va a correr cada test contra cada provider y producir una matriz de comparación. La lectura de la matriz no es "elige el mejor provider" — ya elegiste, el orden de la cadena es la respuesta elegida — sino "cada eslabón de la cadena es individualmente capaz de cumplir el umbral". Un caso de test que pasa en Fable 5 y falla en el primario más barato significa que el primario va a producir silenciosamente una peor respuesta en ese caso para el 96% de las llamadas, aunque la cadena "funcione". Ese es el tipo de regresión que la eval por-eslabón captura y la eval de cadena-como-un-provider no.
La economía, honestamente
El overhead de reserva por llamada es el único costo directo de la cadena. Si tu primario es GPT-5-mini a $0.40 input / $1.60 output y tu terminal es Fable 5 a $10 / $50, la reserva cubre el precio de Fable 5 incluso en llamadas que settlan en el primario. Esa reserva queda retenida hasta que la llamada se completa, luego se devuelve. El costo económico es cero excepto por la forma del cash-flow: necesitas un balance lo suficientemente grande para cubrir las llamadas concurrentes del peor caso.
Para un fleet haciendo 100 requests concurrentes con la cadena price-optimized de arriba, la reserva del peor caso es aproximadamente $1.50 por llamada concurrente (Fable 5 a 1K input + 2K output), así que $150 de float. El settlement real promedia más cerca de $0.005 por llamada porque el 96% aterriza en el primario. El float de reserva no es un costo; es un ejercicio de gestión de balance. Deposita cien dólares más de lo que crees que necesitas y la cadena absorbe todos los disparos de fallback sin que lo notes.
El costo indirecto es más difícil de ver y vale la pena tasarlo. Una cadena que dispara fallback seguido es una cadena cuyo primario está mal elegido — demasiado barato para el tamaño de contexto que efectivamente corres, demasiado rate-limited en el volumen que efectivamente pegas, demasiado agresivo en moderación para el workload que efectivamente sirves. La distribución de X-Model-Used es tu dato; si más del 10% de las llamadas aterrizan en el eslabón de fallback, la cadena está haciendo trabajo real pero el primario está mal configurado. Rotalo antes de que la factura se normalice hacia arriba.
Cuatro anti-patrones
Tres meses de observación de operadores nos dicen que la cadena se usa mal de cuatro maneras predecibles.
Uno. La cadena es demasiado larga. Tres modelos son suficientes; cuatro raramente sirve. Cada modelo adicional es un slot que tienes que probar, monitorear y actualizar independientemente. Las cadenas de dos modelos son perfectamente defensibles cuando el segundo es tu backup real. El proxy soporta hasta tres; pretender que necesitas más usualmente es señal de que el workload debería partirse en dos agentes.
Dos. El mismo modelo en distintos slots. Listar el mismo model id dos veces (o dos model ids respaldados por el mismo proveedor upstream) anula la cadena. Una caída del proveedor saca los dos slots. La propiedad de fallback solo te compra confiabilidad si los slots fallan independientemente. Usa un proveedor distinto para el segundo eslabón salvo que estés deliberadamente probando una condición de fallback en dev.
Tres. El fallback no es realmente un fallback. Una cadena como [fable-5, opus-4.8, sonnet-4.6] con tres modelos distintos de Anthropic no es una cadena de fallback, es una cadena de price-decay sobre el mismo proveedor. Úsala si eso es lo que quieres; no pretendas que te da redundancia de proveedor.
Cuatro. El eslabón terminal no está restringido. El último modelo de tu cadena es el que responde cuando todo lo demás falla. Tiene que ser tu más permisivo en moderación, más generoso en contexto, y más confiable en uptime — usualmente el frontera o el mid-tier más grande. Una cadena cuyo terminal es un modelo barato o con moderación pesada tiene el comportamiento frágil con el que empezaste, solo escondido bajo una capa de abstracción.
Cierre
Las cadenas de fallback de modelo son la compra de confiabilidad más barata de la plataforma. El proxy hace el trabajo, el billing reserve-proxy-settle previene sorpresas, los headers exponen el comportamiento, y los patrones son lo suficientemente chicos como para memorizarlos. El operador que corre con un solo modelo en 2026 está tomando una decisión que no tenía que tomar.
Si tienes un agente en producción hoy, el cambio es una línea en tu client config. Envuelve el model id en un array, agrega un segundo modelo creíble de un proveedor distinto, y observa la distribución de X-Model-Used por una semana. La semana siguiente es cuando decides si el tercer slot vale el cableado. El post de migración cubre todo lo demás que se lanza mejor en este stack; esta es la feature que no se lanza en ningún otro lado.
Agrega un segundo modelo. Eso es todo.
Una línea en tu config te compra confiabilidad que el deployment con un solo modelo nunca va a tener. Los headers y el dashboard te dicen el resto.
Registrar un agente