El día que se te cae el proveedor de LLM | AI Agent Builder
Volver al blog
  • arquitectura
  • operaciones

El día que se te cae el proveedor de LLM

Synaptic Links11 min de lectura

Casi toda conversación sobre resiliencia de proveedores de LLM imagina el incidente equivocado. El imaginado es una caída total e inequívoca de unos minutos, durante la cual los pedidos fallan limpio con un error de conexión y todo el mundo entiende qué está pasando.

El real es más lento y mucho más difícil de manejar. El 10 de junio de 2025, de 06:36 a 22:00, la status page de OpenAI registró tasas de error elevadas en diez componentes de la API — unas quince horas y media. No caído. Elevado. Algunos pedidos salían bien, otros fallaban, la latencia se movía, y cualquier sistema cuyo manejo de fallas asumiera un binario se pasó el día oscilando entre estados.

Esto es un teardown de qué tiene que existir para que ese día sea intrascendente, recorrido en el orden en que los minutos llegan de verdad, y —porque es la parte que se saltea— qué te cuesta la maquinaria los días en que funciona.

Minuto 0 a 2: las fallas son indistinguibles de la carga

El primer síntoma no es un error. Es una distribución de latencia que se ensanchó. El P50 casi no se mueve, el P95 se duplica, y algunos pedidos empiezan a devolver 500 a una tasa que parece ruido si nunca mediste tu tasa de error de base.

Casi todo handler ingenuo toma la misma decisión acá y reintenta. Lo cual es correcto — para una falla transitoria. Es exactamente lo contrario de lo que corresponde con un proveedor degradado, porque reintentar contra un upstream que sufre le agrega carga a la cosa que sufre, y si todos los clientes lo hacen a la vez la degradación parcial del proveedor se vuelve total. Las tormentas de reintentos no son hipotéticas; son el segundo acto estándar.

El mecanismo que distingue los dos casos es un circuit breaker por conexión de proveedor, que rastrea tres señales en vez de una:

  • Fallas consecutivas por encima de un umbral — atrapa la rotura dura y rápida.
  • Tasa de error sobre una ventana móvil — atrapa la forma del 10 de junio, donde la mayoría de los pedidos sigue saliendo bien y ningún contador de fallas consecutivas se dispara nunca.
  • Latencia sostenida por encima de un límite — atrapa el caso en que no falla nada y cada pedido tarda once segundos, que para una superficie conversacional es una caída con pasos extra.

La segunda señal es la que la gente omite, y es la que importó el 10 de junio.

Minuto 2: el circuito abre, y la máquina de estados tiene tres estados

Dos estados no alcanzan. Closed deja pasar tráfico. Open lo bloquea y rutea a otro lado de inmediato, sin pagar primero el timeout. El tercer estado es el que hace al sistema recuperable: half-open, donde después de un enfriamiento se deja pasar un único pedido de prueba. Si sale bien, el circuito cierra y el tráfico normal vuelve; si falla, el circuito vuelve a abrir y el enfriamiento se reinicia.

Sin half-open construiste un interruptor, no un breaker, y alguien tiene que volver a subirlo a mano — lo que en un incidente de quince horas significa alguien mirando una status page todo el día. Con él, la recuperación es una propiedad del sistema. La perilla de ajuste es el intervalo de sondeo, y es un compromiso real: sondeás muy seguido y sos parte de la tormenta de reintentos, sondeás muy poco y servís desde tu fallback una hora después de que el proveedor se recuperó.

Minuto 2, sigue: el failover necesita a dónde ir

Acá es donde la mayoría de las arquitecturas descubre que directamente no puede hacer esto, por una razón que no tiene nada que ver con ingeniería de resiliencia.

Si el modelo está nombrado adentro de la definición del workflow —un nodo de OpenAI, con gpt-4.1 en su configuración— entonces "usá otro proveedor" no es una decisión de ruteo. Es una edición sobre cada workflow, desplegada en condiciones de incidente, por quien esté despierto. El failover que querés no es expresable, y ningún circuit breaker ayuda, porque no hay a dónde rutear.

El failover requiere que el workflow declare un tipo de pensamiento en vez de un modelo, y que algo resuelva esa declaración en el momento de la llamada. Los nodos piden un nivel — low, normal, high, más los especializados para voz y embeddings — y un control plane por tenant mapea cada nivel a una conexión y un modelo concretos. Esa indirección merece su propio argumento, y la resiliencia es la razón más clara para pagarla: una vez que el mapeo es dato y no código, puede sostener una lista ordenada en vez de un solo par.

El nivel "normal" resuelve a:
  1. connection=openai-prod    model=gpt-4.1        ← circuito OPEN
  2. connection=anthropic-prod model=claude-sonnet  ← circuito CLOSED, sirviendo
  3. connection=google-prod    model=gemini-pro

Tres fallbacks es un tope razonable, y el tope no es arbitrario: cada salto adicional es latencia que el usuario espera mientras el runtime descubre que la próxima opción también está caída. Una cadena de ocho es un error lento.

Minuto 3: el fallback no es tan independiente como dice el diagrama

Esta es la parte que hace que las cadenas se vean mejor en el papel que en producción.

El 19 y 20 de octubre de 2025, AWS publicó un resumen post-evento de un incidente en la región US-EAST-1 que corrió desde las 11:48 PM PDT del 19 de octubre hasta las 2:20 PM PDT del 20 — unas catorce horas y media. La causa raíz fue una race condition latente en el sistema de gestión de DNS de DynamoDB que produjo un registro DNS vacío e incorrecto para el endpoint regional, que la automatización no pudo reparar por su cuenta. El radio de impacto alcanzó a EC2, Lambda, ECS, STS, la autenticación de la consola de IAM y más.

Una cadena de failover que lista tres proveedores distintos son tres proveedores. Si son tres dominios de falla depende de dónde corre cada uno realmente, y de si tu propio runtime, tu secret store, tu base de sesiones y tu cola están en la misma región que alguno. La profundidad no es independencia. La pregunta a responder antes de un incidente, en papel, es qué evento único te saca dos filas de la cadena a la vez — y la respuesta honesta seguido es que hay uno.

Una cadena de failover que lista tres proveedores, resuelta a los dominios de falla de los que realmente depende
Una cadena de failover que lista tres proveedores, resuelta a los dominios de falla de los que realmente depende

Minuto 3, todavía: los rate limits son otra falla con la misma ropa

Un 429 parece una caída para código que solo chequea si la llamada salió bien, y necesita la respuesta opuesta. Una caída significa rutear a otro lado. Un rate limit significa esperar — el proveedor te está diciendo, en un header Retry-After, exactamente cuánto.

Hacer failover ante un 429 es un error con factura diferida: empujás tráfico a un fallback que puede tener otro precio, y como funciona, nadie se entera hasta la facturación. La distinción vale codificarla, y vale saber cuál de tus límites estás tocando. Los límites se apilan en cuatro niveles, y fallan distinto:

NivelQué protegeQué significa tocarlo
Conexión de proveedorLa cuota del upstreamBackoff y reintento; failover solo si persiste
Por API keyUna integración portándose malAlgo de tu lado está en loop — no lo esquives
Por tenantLa porción justa de un clienteFunciona como se diseñó; el cliente necesita más techo, no un fallback
GlobalLa capacidad total de la plataformaLa caída sos vos

Rutear alrededor de tus propios límites anula el sentido de tenerlos.

Hora 4: qué compra realmente la capa

Tres cosas, y vale nombrarlas por separado porque los equipos seguido construyen la maquinaria para la primera y nunca cobran las otras dos.

El usuario no ve el incidente. El tráfico se corre adentro de un mismo pedido. La conversación sigue en otro modelo y a nadie se le avisa, que es todo el objetivo.

El incidente se vuelve reportable. El estado del circuito por conexión, el tiempo en cada estado, la cantidad de failovers, los percentiles de latencia y la tasa de error por ventana son todas cosas que ahora medís porque el breaker las necesitaba. Esa es la diferencia entre decirle a un cliente "hubo un problema con nuestro proveedor de IA" y decirle "entre las 06:40 y las 22:00 servimos el 4% de tus conversaciones desde un modelo secundario, sin pedidos fallidos".

La dependencia se vuelve negociable. Una plataforma que puede mover proveedores con un cambio de configuración durante un incidente también puede moverlos durante una negociación de contrato. No es una propiedad de resiliencia, pero se compra con el mismo código.

Cuándo no construir esto

Un solo proveedor con retry y backoff es la respuesta correcta más seguido de lo que la literatura de resiliencia admite, y hay tres casos distintos.

Cuando tu volumen es bajo y tu tolerancia es real. Si servís unos cientos de conversaciones por día a usuarios internos, una caída es una disculpa, no un evento de negocio. Reintento con backoff exponencial y jitter, un error honesto en pantalla, y el tiempo de ingeniería a algo que el cliente pueda ver. El failover multi-proveedor tiene costo de operación — una segunda relación con un vendor, una segunda clave para rotar, un segundo juego de cuotas, un segundo modelo cuyo comportamiento hay que seguir.

Cuando igual no podés cambiar. Si el contrato de un cliente o un regulador fija el procesamiento a un proveedor o a una jurisdicción, el failover entre vendors no está disponible. La historia de resiliencia ahí es degradación elegante: soltar primero los niveles caros, encolar lo que se pueda responder tarde, y decirle al usuario la verdad, que es un problema de diseño antes que de ruteo.

Cuando el fallback sería peor que la caída. Este es el que se subestima. Hacer failover cambia el modelo, y el modelo no es una pieza commodity.

Ese último punto merece su propio párrafo, porque es el costo real de que el mecanismo funcione. Los prompts afinados sobre un modelo no son igual de buenos en otro. Los esquemas de salida estructurada que un primario respeta con confianza pueden volver malformados desde un fallback, y la falla va a ser un error de parseo en tu propio código y no un error del proveedor. El tono se corre, así que una conversación de soporte puede cambiar de voz a mitad del hilo. Tus evaluaciones se corrieron contra el primario; durante el failover estás sirviendo una configuración que nunca mediste. Y el precio por token del fallback probablemente no sea el del primario, así que la unidad económica se mueve en silencio en la dirección que nadie está mirando — que es un problema lo bastante grande como para tener su propia aritmética.

La mitigación no tiene glamour: corré tu suite de evaluación contra cada modelo de cada cadena, no solo contra los primarios, y tratá a un fallback que no evaluaste como código sin testear que solo se ejecuta durante incidentes. Que es el peor momento posible para enterarte.

Preguntas para responder antes del próximo incidente

Portables, neutrales respecto del vendor, y respondibles en una tarde con un pizarrón.

  1. ¿Cuál es tu tasa de error de base y tu P95? Si no podés decir las dos, no podés detectar degradación — solo falla total.
  2. ¿Tu breaker abre por tasa de error sobre una ventana, o solo por fallas consecutivas? La forma del 10 de junio derrota a la segunda.
  3. ¿Existe un estado half-open, y cuál es el intervalo de sondeo?
  4. ¿Podés cambiar qué modelo sirve un nivel sin editar un workflow? Si no, todo lo que está debajo de esta línea no está disponible para vos.
  5. Dibujá el grafo de dependencias de tu cadena de failover hasta región y nube. ¿Qué evento único te saca dos filas?
  6. ¿Un 429 rutea a otro lado o hace backoff? Mirá el código, no la intención.
  7. ¿Corriste tus evaluaciones contra los modelos de fallback? Si no, poné la fecha en que lo vas a hacer.
  8. Después de un failover, ¿quién se entera, y cómo? Un failover transparente que después nadie puede ver es un cambio no detectado en lo que estás sirviendo.

Quince horas y media el 10 de junio. Catorce y media el 19 de octubre. No son eventos raros en la cola de una distribución — son el comportamiento observable de la infraestructura sobre la que todo el mundo construye, publicado en las status pages de los propios operadores. La pregunta de diseño no es si el proveedor va a tener un mal día. Es qué está haciendo tu sistema en la hora nueve de ese día.

Seguir leyendo