Un proveedor de LLM puede aceptar una petición y fallar antes de que tu aplicación reciba la respuesta. Si el runtime envía el mismo turno a otro proveedor sin comprobar el estado, la respuesta de respaldo puede producir una segunda tool call. Para un efecto externo, eso puede significar un cobro repetido, un mensaje duplicado o un cambio de estado aplicado dos veces.
El failover seguro separa tres cosas: el intento de obtener una decisión del modelo, la intención de acción de la aplicación y la ejecución del efecto externo. Esta separación es el complemento práctico de la ejecución durable para agentes de IA. Cada intento del modelo puede tener su propio identificador, pero la acción conserva una clave creada por la aplicación. El runtime clasifica el error, respeta un presupuesto de tiempo y coste, cambia solo cuando la capacidad es compatible y confirma el estado antes de repetir.

Respuesta corta
- Un retry repite un intento del modelo; el failover cambia de proveedor; detenerse registra que no hay evidencia suficiente para continuar.
- Un timeout después de enviar una petición es un estado desconocido, no una prueba de que la acción no ocurrió.
- La clave de acción pertenece a tu runtime y debe llegar al ejecutor cuando el efecto pueda repetirse.
- El proveedor de respaldo debe cumplir el contrato de capacidad, formato y autorización antes de tomar el control.
¿Qué debe decidir el failover?
El failover no es solo una lista de proveedores en orden. Es una política para cuatro estados: un error antes de que el modelo procese la petición, un error transitorio sin efecto externo conocido, una respuesta inválida y un resultado ambiguo después de que la aplicación pudo iniciar una acción. Cada estado necesita una salida distinta.
Si el fallo es transitorio y la operación sigue siendo solo un intento del modelo, el runtime puede reintentar dentro de su presupuesto. Si el proveedor no está disponible, puede cambiar a otro que cumpla el mismo contrato. Si la respuesta es inválida, el runtime debe validarla o detenerse. Si una tool call pudo ejecutarse, debe consultar el estado o esperar confirmación antes de repetir.
Ese límite entre decisión y efecto conecta el failover con la capa durable. Los checkpoints conservan lo que la ejecución sabe, pero no convierten automáticamente una operación externa en idempotente.
¿Cuándo permite el error un retry o un failover?
Empieza por el contrato del proveedor, no por un bloque catch que trate todo como retryable. La guía de códigos de error de OpenAI separa límites de tasa y fallos temporales de problemas de autenticación, configuración, facturación y cuota. La guía de troubleshooting de Gemini también recomienda backoff limitado para fallos transitorios y desaconseja reintentar automáticamente errores de petición o permisos.
Una clasificación inicial puede ser esta:
| Estado observado | Acción preferible | Qué falta confirmar |
|---|---|---|
| Límite de tasa o caída antes de una tool call | Retry limitado o failover | Presupuesto, plazo y capacidad del respaldo |
| Error de autenticación, permiso, schema o configuración | Detenerse y corregir la configuración | Si otra credencial está autorizada fuera del loop |
| Timeout mientras solo se esperaba la respuesta del modelo | Seguir la política y reintentar con límites | Si la petición fue aceptada y si el intento se factura |
| Timeout después de solicitar un efecto externo | No repetir a ciegas | Estado de la acción, clave de idempotencia o consulta de operación |
| Respuesta de respaldo sin la tool o el formato exigido | Detenerse o pedir otra decisión | Capacidad real, no un nombre de modelo parecido |
Los códigos de estado no son una política universal. Los SDK pueden aplicar sus propios retries, los proxies pueden ocultar respuestas y los proveedores pueden cambiar detalles. Registra la categoría original y la decisión para que un salto silencioso no parezca éxito.
¿Cómo separar la llamada del modelo de la tool call?
La respuesta del modelo es una propuesta. La aplicación debe convertirla en una intención de acción solo después de validar nombre, argumentos, autorización y estado de la tarea. La documentación de tool use de Anthropic expone un identificador para un bloque tool_use, pero ese identificador describe el mensaje del proveedor. No sustituye al identificador de acción de tu dominio.
Conserva dos identificadores:
modelAttemptIdidentifica un intento con un proveedor y modelo.actionIdidentifica la intención lógica, comoenviar-pedido-847, sin importar cuántas respuestas se obtuvieron.- El ejecutor registra
actionIdantes de aplicar el efecto y devuelve el resultado conocido cuando la misma acción llega otra vez. - Un timeout mantiene el estado como
unknownhasta que una consulta, callback o reconciliación cambie la evidencia.
El siguiente fragmento es ilustrativo. Muestra la frontera de decisión, no un router listo para producción, y no se ejecutó contra un proveedor real.
type ActionState = "not_started" | "running" | "succeeded" | "failed" | "unknown";
type ProviderResult = {
kind: "answer" | "tool_call" | "error";
retryable?: boolean;
actionState?: ActionState;
};
async function resolveTurn(actionId: string): Promise<ProviderResult> {
const existing = await actionStore.read(actionId);
if (existing?.state === "succeeded") {
return { kind: "answer", actionState: "succeeded" };
}
const attempt = await askProviderWithBudget();
if (attempt.kind === "error" && attempt.retryable && !attempt.actionState) {
return failoverOnceWithTheSameAction(actionId);
}
if (attempt.kind === "tool_call") {
return executeWithIdempotencyKey(actionId, attempt);
}
return attempt;
}
La parte importante no son los nombres de las funciones. Es impedir que failoverOnceWithTheSameAction repita una herramienta que ya pudo aceptarse. La herramienta debe conocer actionId, o el runtime debe consultar un servicio que conozca esa clave.
Para la frontera de schema y errores antes de ejecutar, consulta cómo validar tool calls en TypeScript. Validar la forma no demuestra que una acción no se haya ejecutado, pero reduce la posibilidad de enviar una respuesta incompatible al ejecutor.
¿Cómo limitar tiempo, coste e intentos?
Una política de failover sin presupuesto puede convertir una caída en una secuencia de llamadas caras y lentas. Define un deadline para el turno, un máximo de intentos y un techo de gasto que el runtime compruebe antes de llamar a otro proveedor. El límite debe compartirse por el turno y no reiniciarse en cada salto.
El backoff debe seguir la guía del proveedor y el tiempo restante. Un retry cuyo retraso supera el deadline no es resiliencia; es un error más tardío. Registra también proveedor, modelo, intento, clase de error y duración. Esa traza muestra si el failover evitó un error o solo acumuló coste.
Si una tool call se queda colgada, la cancelación tiene su propia frontera. Cancelar un agente de IA cuando una tool se bloquea puede liberar el worker, pero no borra un efecto que ya llegó al sistema externo. El siguiente paso debe ser reconciliación, no repetición automática.
¿Cómo validar el proveedor de respaldo?
Dos modelos pueden devolver una forma general parecida y aun así ofrecer capacidades distintas. Antes de cambiar, compara las tools permitidas, los schemas de argumentos, los límites de contexto, el streaming, las políticas de seguridad y la representación de errores. Si el respaldo no puede ejecutar la herramienta necesaria, devolver texto no es un failover exitoso.
Valida en dos capas. Primero, confirma que la respuesta cumple el contrato sintáctico. Después, confirma que la decisión puede avanzar la regla de negocio. La guía de validación de tool calls explica por qué un tipo de TypeScript o un JSON válido no demuestra que el resultado sea seguro para el siguiente paso.
El failover también debe conservar el contexto relevante y descartar material que aumente el riesgo sin ayudar a la decisión. No envíes secretos de una integración a un proveedor que no está autorizado a operar esa tool. Cuando la capacidad no sea equivalente, la salida honesta es detenerse o pedir aprobación, no adaptar la acción en silencio.
¿Cómo registrar un salto de proveedor sin ocultarlo?
Usa una identidad para la ejecución lógica y una lista de intentos dentro de ella. Cada intento debe registrar proveedor, modelo, motivo de salida, duración, uso de tokens cuando esté disponible, estado de la tool y siguiente decisión. Evita guardar prompts o argumentos sensibles solo para demostrar que hubo failover.
Una métrica de éxito aislada puede engañar. Observa cuántos turnos terminaron, cuántos necesitaron un salto, cuántos quedaron desconocidos y cuántos efectos exigieron reconciliación. La guía de observabilidad de agentes de código aplica la misma idea de separar la ejecución lógica de los eventos que la componen.
En flujos largos, uso RemoteCode como mi herramienta para trabajar con sesiones de agentes y mantener visible este contexto operativo. Esto describe mi uso de la herramienta, no un benchmark de este artículo ni una recomendación de un proveedor concreto.
¿Cómo probar el camino de fallo?
No empieces probando solo si el proveedor de respaldo respondió. Prueba si el runtime conserva la identidad de la acción y se detiene cuando no puede demostrar el estado. Un proveedor falso y un ejecutor falso permiten probar las decisiones sin enviar mensajes ni cobros reales.
| Escenario | Resultado esperado |
|---|---|
| El principal devuelve límite de tasa antes de decidir | Un retry limitado o un salto registrado |
| El principal falla y el respaldo no tiene la tool necesaria | Parada explícita por incompatibilidad |
| Timeout antes de la respuesta del modelo, sin acción iniciada | Retry limitado dentro del deadline |
Timeout después de enviar una acción con actionId |
Consulta de estado o unknown, nunca duplicación ciega |
| La respuesta de respaldo tiene argumentos inválidos | Rechazo antes del ejecutor |
| Todos los intentos superan el deadline | Fallo observable con motivo original y estado de la acción |
La prueba más valiosa es la ambigüedad: permite que el ejecutor acepte la acción, descarta la respuesta y simula un timeout. Un segundo intento con el mismo actionId debe devolver el resultado guardado o exigir reconciliación. Si crea un efecto nuevo, el failover todavía está acoplado al retry del mensaje.
Preguntas frecuentes
¿El failover siempre debe cambiar de proveedor?
No. Un error de configuración, permiso, schema o regla de negocio no se corrige cambiando de proveedor. Cambia solo cuando el error coincide con la política, el deadline lo permite y el respaldo cumple el contrato del turno.
¿Puedo repetir una tool call después de un timeout?
No sin evidencia adicional. Trata el efecto como desconocido, consulta su estado o usa una clave de idempotencia que el sistema externo realmente respete. Un timeout local informa lo que vio tu cliente, no lo que completó el servidor.
¿Una clave de idempotencia lo resuelve todo?
No. La guía de AWS sobre APIs idempotentes explica que el servicio debe registrar la intención y la operación de forma consistente para reconocer una repetición. La guía de Well-Architected también trata la clave como parte del contrato del servicio, no como un campo decorativo enviado por el cliente.
Conclusión
Un failover confiable empieza con una pregunta simple: ¿qué pudo ocurrir exactamente antes del cambio? Si la respuesta es solo un intento del modelo, un retry o failover limitado puede bastar. Si una tool call es desconocida, conserva la acción, consulta el efecto y decide después el siguiente paso.
Este diseño no depende de un proveedor concreto. Exige políticas explícitas para errores, presupuesto, capacidad, validación, idempotencia y observabilidad. Sin esas fronteras, el failover puede mejorar la disponibilidad en un panel y debilitar la integridad del sistema.
Fuentes consultadas
- OpenAI Developers, Error codes, consultada el 27/08/2026.
- Google AI for Developers, Troubleshooting, consultada el 27/08/2026.
- Anthropic, Implement tool use, consultada el 27/08/2026.
- AWS Builders' Library, Making retries safe with idempotent APIs, consultada el 27/08/2026.
- AWS Well-Architected, Prevent interaction failure with idempotent APIs, consultada el 27/08/2026.