Problema
La solicitud parece estándar: verificar el pago y confirmar el estado del pedido.
En los traces se ve otra cosa: en 9 minutos, un run hizo 29 llamadas de herramienta
(billing.get_invoice - 18, payments.verify - 11), y la mayoría terminó en timeout o 5xx.
Para este tipo de tarea, puede costar ~$2.50 en lugar de los ~$0.12 habituales.
El servicio formalmente no está "muerto": parte de las llamadas devuelve 200.
Pero el usuario no recibe respuesta final, y crecen la cola de runs y la latencia.
El sistema no se cae.
Simplemente se atasca entre errores de herramientas y retries, acumulando lentamente latencia y cola de runs.
Analogía: imagina a un repartidor que llega a un almacén cerrado, llama otra vez, espera, vuelve a llamar y regresa una y otra vez a la misma puerta. Está siempre "en proceso", pero el pedido no avanza. El tool failure en agentes se ve igual: hay acciones, no hay resultado.
Por qué pasa
El tool failure no aparece solo por una API inestable.
Normalmente el problema central es que la runtime no tiene una estrategia clara para clasificar y manejar errores de herramientas.
En producción suele pasar así:
- un servicio externo devuelve
timeout,5xxo payload inestable; - runtime o tool gateway repite la llamada sin clasificación clara de error;
- errores non-retryable también entran en bucles de retries;
- sin circuit breaker ni fallback, el run se cuelga o quema presupuesto.
El problema no es un error API aislado. El problema es que el sistema no detiene la ola de fallos antes de que se convierta en incidente.
Este tipo de incidente suele llamarse agent tool failure -
cuando un sistema de agentes no puede operar de forma estable
por inestabilidad o errores de herramientas externas.
Fallos más frecuentes
Para mantenerlo práctico, en producción se ven sobre todo cuatro patrones de tool failure.
Transient failures
La herramienta devuelve 408/429/5xx de forma intermitente.
Si el control de retries es débil, una caída corta se convierte en retry storm.
Causa típica: falta de backoff+jitter y retry budget.
Wrong retry classification
401, 403, 404, 409, schema validation errors o policy denials entran en retries,
aunque deberían terminarse de inmediato.
Causa típica: retryable y non-retryable no están separados en un solo punto.
Tool contract drift
La herramienta cambia el formato de respuesta o la estructura de error. El agente no puede interpretar resultados de forma estable y empieza a "preguntar" al mismo servicio otra vez.
Causa típica: no hay versionado de contrato ni validación de payload en gateway.
Cascading failure
Una herramienta problemática sube la latencia de todo el sistema: workers ocupados esperando, cola en crecimiento, otros runs también se ralentizan.
Causa típica: falta de circuit breaker y fallback para degraded dependencies.
Cómo detectar estos problemas
El tool failure se ve bien con la combinación de métricas de runtime y gateway.
| Métrica | Señal de tool failure | Qué hacer |
|---|---|---|
tool_error_rate | subida brusca de 4xx/5xx/timeout | activar degraded mode y revisar dependencia |
retry_attempts_per_call | demasiados retries por llamada | limitar retry budget y agregar backoff+jitter |
non_retryable_retry_rate | retries sobre 401/403/404/409/422 | terminar run de inmediato con stop reason explícito |
circuit_open_rate | circuit breaker se abre con frecuencia | revisar SLA de la herramienta y escenario de fallback |
queue_backlog | la cola crece con tráfico normal | limpiar runs colgados y bajar fan-out |
Cómo distinguir tool failure de un error lógico del agente
No todo fallo de run significa que el agente "razona mal". El criterio clave: dónde exactamente se rompe el loop.
Normal si:
- el error está localizado en una herramienta externa;
- stop reason apunta directamente a la dependencia (
tool_timeout,tool_5xx,circuit_open); - después de fallback, el usuario recibe un resultado parcial pero correcto.
Peligroso si:
- el agente retría errores non-retryable como si fueran retryable;
- no hay stop reasons claros en tool gateway;
- el fallo de una herramienta arrastra todo el workflow.
Cómo detener estos fallos
En la práctica se ve así:
- clasificar errores de herramienta en retryable y non-retryable;
- mantener retry policy en un solo tool gateway (backoff+jitter + budget);
- poner circuit breaker frente a olas de fallos;
- cuando la herramienta no esté disponible, devolver fallback/partial y stop reason.
Guard mínimo para errores de herramientas:
from dataclasses import dataclass
import time
RETRYABLE = {408, 429, 500, 502, 503, 504}
NON_RETRYABLE = {400, 401, 403, 404, 409, 422}
@dataclass(frozen=True)
class ToolFailureLimits:
max_retry: int = 2
open_circuit_after: int = 3
circuit_cooldown_s: int = 20
class ToolFailureGuard:
def __init__(self, limits: ToolFailureLimits = ToolFailureLimits()):
self.limits = limits
self.fail_streak = 0
self.circuit_open_until = 0.0
def before_call(self) -> str | None:
if time.time() < self.circuit_open_until:
return "tool_unavailable:circuit_open"
return None
def on_result(self, status_code: int, attempt: int) -> str | None:
if status_code in NON_RETRYABLE:
self.fail_streak = 0
return "tool_failure:non_retryable"
if status_code in RETRYABLE:
self.fail_streak += 1
if self.fail_streak >= self.limits.open_circuit_after:
self.circuit_open_until = time.time() + self.limits.circuit_cooldown_s
return "tool_unavailable:circuit_open"
if attempt >= self.limits.max_retry:
return "tool_failure:retry_exhausted"
return "tool_retry:allowed"
self.fail_streak = 0
return None
Este es un guard base.
En producción normalmente se complementa con límites por herramienta y backoff exponencial con jitter.
attempt aquí suele ser 1-based (1, 2, 3...), y el estado del guard normalmente se mantiene por tool o por run.
Dónde se implementa en la arquitectura
En producción, el control de tool failure casi siempre se reparte entre tres capas del sistema.
Tool Execution Layer es el punto principal de control: validación de args y payload, retry policy, clasificación de errores, circuit breaker. Si esta capa es débil, incluso un problema simple de API se vuelve rápido una cascade.
Agent Runtime gestiona el ciclo de vida del run: stop reasons, timeout, cierre controlado y respuesta de fallback. Aquí es clave no continuar el run a cualquier costo.
Policy Boundaries define qué herramientas están permitidas y en qué condiciones el run debe terminar en fail-closed. Esto es especialmente importante para write-tools y errores de permisos.
Checklist
Antes de shippear un agente a producción:
- [ ] errores retryable/non-retryable separados explícitamente;
- [ ] retries implementados en un único gateway, no en varias capas;
- [ ]
max_retry, backoff+jitter y retry budget definidos; - [ ] circuit breaker y cooldown configurados para cada tool crítico;
- [ ] stop reasons cubren
timeout,5xx,non_retryable,circuit_open; - [ ] respuesta fallback/partial definida antes del incidente;
- [ ] alertas sobre
tool_error_rate,retry_attempts_per_call,queue_backlog; - [ ] runbook para degraded mode y rollback de dependencias.
FAQ
Q: ¿Basta con subir el timeout para la herramienta problemática?
A: No. Eso normalmente solo enmascara el problema y aumenta latencia. Necesitas error classification, retry budget y circuit breaker.
Q: ¿Dónde deben vivir los retries?
A: En un único choke point, normalmente en tool gateway. Retries en varias capas casi siempre generan amplification.
Q: ¿Qué errores suelen ser non-retryable?
A: 401, 403, 404, 409, 422, schema validation errors y policy denials. Estos runs normalmente se terminan de inmediato con stop reason explícito.
Q: ¿Qué mostrar al usuario cuando una herramienta no está disponible?
A: Motivo de parada, qué ya se verificó y siguiente paso seguro: fallback, resultado parcial o escalación manual.
El tool failure casi nunca parece una gran caída única. Más bien es una serie de fallos pequeños que se acumulan en bucles de retries y cola. Por eso los agentes de producción necesitan no solo herramientas, sino disciplina estricta de ejecución.
Páginas relacionadas
Si este problema aparece en producción, también conviene revisar:
- Por qué fallan los agentes de IA - mapa general de fallos en producción.
- Tool spam - cómo llamadas repetidas convierten fallos de herramienta en incidentes.
- Partial outage - cómo degradación parcial de dependencias rompe workflow.
- Budget explosion - cómo retry storms inflan costos en silencio.
- Agent Runtime - dónde controlar stop reasons y ciclo de vida del run.
- Tool Execution Layer - dónde mantener retries, validación y circuit breaker.