Error Recovery en AI Agents 2026: El 95% se Rompe en el Primer Error Real — y No, un Try-Catch No Va a Salvarlos
El 95% de los AI Agents se rompen en el primer error. Aprende a implementar Error Recovery real con clasificación de errores, checkpoints de estado y decoradores de validación en Python.
El 95% de los AI Agents Que Construyes Hoy se Van a Romper en Producción
No es culpa del modelo. Es culpa de tu try-catch.
La mayoría de los desarrolladores tratáis los AI Agents como software determinista. Escribís código que asume que el LLM va a devolver JSON válido. Que la tool call va a funcionar. Que el contexto va a caber en la ventana.
Y cuando falla, ponéis un try-catch.
*El problema no es que los agents fallen. Es que los tratáis como funciones puras cuando son sistemas probabilísticos con estado corrupto. *
En software tradicional, un error es un evento. Ocurre, lo capturas, lo manejas, y sigues. El estado del programa no se modifica por el mero hecho de que ocurra un error.
En un AI Agent dirigido por LLMs, el error es el estado. Cuando el modelo devuelve un JSON malformado, ese output ya está en el contexto. Cuando haces retry, el LLM ahora ve su propio error. Contexto contaminado. El siguiente intento arrastra el fallo anterior.
Hagamos los números: el 95% de los AI Agents que se lanzan a producción se rompen en el primer error real que encuentran. No en tests. No en desarrollo. En producción, donde el error ya no es un evento controlado.
La razón no es que los LLMs sean malos. Es que estáis usando la herramienta de recovery equivocada.
El Problema de Fondo: Estado vs Evento
En una API REST tradicional, si una request falla, capturas el error con un bloque catch, devuelves un 500, y el servidor sigue funcionando. El estado interno del sistema nunca se vio afectado por esa request fallida.
*En un AI Agent, el output del LLM se convierte en el estado interno de la próxima iteración. *
Cada vez que el modelo genera texto, ese texto pasa a formar parte del historial de conversación. El agente lo lee. Lo procesa. Toma decisiones basadas en él.
Si ese output contenía un error — un JSON mal parseado, una alucinación, una contradicción lógica — ese error ya está dentro del sistema. Hacer retry no lo borra. El LLM ve su propio fallo en el historial y reacciona de formas impredecibles.
❌ Try-catch tradicional: Captura el error, reintenta sobre el mismo contexto corrupto. El LLM corrige en exceso o refuerza el error original.
✅ Recovery compensatorio: Detecta el error antes de que mute el estado, clasifica el tipo de fallo, y aplica la estrategia correcta según la categoría.
Esto no es un problema de prompts bien escritos. Es un problema de arquitectura.
Por Qué LangChain y AutoGPT No Resuelven Esto
"Pero si uso LangChain, ya tiene error handling integrado."
No. Lo que tiene es retry logic con parsing fallback. Todo determinista. No tiene concepto de "el error ya contaminó el contexto". Su approach es: "falló el parser, reintenta la misma llamada con el mismo contexto".
El problema es que el reintento ocurre sobre el mismo contexto potencialmente corrupto. No hay checkpoints de estado. No hay clasificación de errores. No hay rollback parcial. Es try-catch con otro nombre.
"Pero si pongo temperature=0 y prompts muy específicos, los errores son mínimos."
Eso asume que el error es evitable. Los modelos probabilísticos siempre tienen una tasa de error no nula. Es diseño, no bug. Minimizar errores no es lo mismo que tener un sistema robusto ante ellos. Un agente que funciona el 95% de las veces en tests unitarios puede fallar catastróficamente en producción cuando el error que no esperabas ocurre.
La analogía correcta no es try-catch. Es manejo de errores en sistemas distribuidos. Ahí un error en un nodo puede corromper el estado global, por eso usáis Sagas, Circuit Breakers, y patrones de compensación.
Los AI Agents necesitan el mismo approach: un error no se "maneja", se "compensa".
La Evidencia: 3 Casos de Contaminación que Matan Agents
Caso 1 — Error de formato: El LLM devuelve `{"resultado": "valor"}` con una coma extra. El parser lanza excepción. Haces retry. Ahora el LLM ve su JSON fallido en el historial y decide "voy a ser más explícito". Devuelve un chunk Markdown explicando el JSON. Segundo error. Tercer retry. El contexto ahora tiene 3 entradas rotas. El agente ya no se recupera.
Caso 2 — Error de alucinación: El agente consulta una API de precios. El LLM alucina un precio que no existe. Ese precio se guarda en la base de datos temporal del agente. La siguiente tool call usa ese precio alucinado para calcular totales. El error se propaga a 3 pasos más. Cuando el usuario pregunta "¿cuánto cuesta?", el agente responde con datos falsos con total confianza.
Caso 3 — Error de consistencia: El agente lleva 15 pasos ejecutando un workflow. En el paso 8, el LLM contradice una decisión del paso 3. El historial ahora contiene dos verdades incompatibles. El agente no sabe cuál mantener. Sigue ejecutando, acumulando contradicciones. El output final es incoherente.
En los tres casos, el error no fue el problema. La falta de validación antes de mutar el estado fue el problema.
El Sistema de Clasificación que Cambia Todo: 3 Tipos de Error, 3 Estrategias
No todos los errores son iguales. Tratarlos igual es el error.
Aquí está la clasificación que necesitas:
| Tipo de error | Ejemplo | Estrategia de recovery |
|---|---|---|
| Formato | JSON inválido, schema mismatch | Reparación local (regex, post-processing, re-prompting con instrucciones estrictas) |
| Estado/Consistencia | Contradicción con historial, lógica rota | Rollback parcial al último checkpoint válido |
| Alucinación | Información factual incorrecta | Reinicio guiado con nuevo contexto + validación externa (otro LLM o grounding en fuentes) |
Los errores de formato son los más fáciles. Un simple post-procesamiento con regex o un re-prompt con instrucciones más estrictas suele bastar. No necesitas tocar el estado del agente.
Los errores de estado requieren rollback. Necesitas un checkpoint del contexto antes de la acción que falló. Restauras ese checkpoint y reintentas con condiciones corregidas.
Las alucinaciones son las más peligrosas. El LLM no sabe que está alucinando. No puedes fiarte de que se auto-corrija. Necesitas validación externa: otro LLM como validador, grounding en fuentes externas (bases de datos, APIs), o ambos.
El Framework: 5 Pasos para Error Recovery Real
Vamos a construir esto paso a paso. Llamémosle el Sistema de Recuperación de 3 Capas para AI Agents.
Paso 1: Implementa el Error Classifier
Primero necesitas un clasificador que categorice cada fallo del LLM antes de que toque el estado del agente.
```python
from enum import Enum
from typing import Any, Dict, Optional
import json
import re
class ErrorType(Enum):
FORMAT = "format_error"
STATE = "state_error"
HALLUCINATION = "hallucination_error"
class ErrorClassifier:
"""Clasifica errores de output de LLM en 3 categorías."""
@staticmethod
def classify(output: str, expected_schema: Optional[Dict] = None) -> ErrorType:
1. Error de formato: JSON inválido, schema mismatch
if ErrorClassifier._is_format_error(output, expected_schema):
return ErrorType.FORMAT
2. Error de alucinación: información factual incorrecta
if ErrorClassifier._is_hallucination(output):
return ErrorType.HALLUCINATION
3. Por defecto, si no hay error clasificable, no hay error
Los errores de estado se detectan a nivel de agente (consistencia con historial)
return None
@staticmethod
def _is_format_error(output: str, schema: Optional[Dict]) -> bool:
if schema is None:
return False
try:
parsed = json.loads(output)
Validación básica de schema
for key in schema.get("required", []):
if key not in parsed:
return True
return False
except (json.JSONDecodeError, ValueError):
return True
@staticmethod
def _is_hallucination(output: str) -> bool:
Detección heurística de alucinaciones
En producción, usarías otro LLM o grounding en datos reales
hallucination_markers = [
"según mis datos internos",
"basado en información no verificada",
"no tengo acceso a esa información pero"
]
return any(marker in output.lower() for marker in hallucination_markers)
```
Paso 2: Construye el CheckpointStateManager
Necesitas un sistema de checkpoints que guarde el estado después de cada paso exitoso, no al inicio de la ejecución.
```python
from typing import Any, Dict, List, Optional
from dataclasses import dataclass, field
from datetime import datetime
@dataclass
class AgentCheckpoint:
step_id: int
context: List[Dict[str, Any]]
agent_state: Dict[str, Any]
timestamp: datetime
action_description: str
class CheckpointStateManager:
"""Guarda snapshots del estado interno después de cada paso exitoso."""
def __init__(self):
self._checkpoints: List[AgentCheckpoint] = []
self._current_step = 0
def save_checkpoint(self, context: List[Dict], state: Dict, description: str):
checkpoint = AgentCheckpoint(
step_id=self._current_step,
context=[msg.copy() for msg in context],
agent_state=state.copy(),
timestamp=datetime.now(),
action_description=description
)
self._checkpoints.append(checkpoint)
self._current_step += 1
def rollback_to_last(self) -> Optional[AgentCheckpoint]:
"""Recupera el último checkpoint válido."""
if not self._checkpoints:
return None
return self._checkpoints[-1]
def rollback_to_step(self, step_id: int) -> Optional[AgentCheckpoint]:
"""Recupera un checkpoint específico por step_id."""
for cp in reversed(self._checkpoints):
if cp.step_id == step_id:
return cp
return None
def clear(self):
self._checkpoints.clear()
self._current_step = 0
```
Paso 3: Implementa el Validation Decorator
Esta es la pieza crítica. Un decorador que intercepta todo output del LLM antes de que actualice el estado del agente.
```python
from functools import wraps
from typing import Any, Callable, Dict, Optional, Type
from pydantic import BaseModel, ValidationError
def validate_output(schema: Optional[Type[BaseModel]] = None):
"""
Decorador que valida el output del LLM antes de que
actualice el estado del agente.
Si el output no pasa la validación, ejecuta la estrategia
de recovery correcta según el tipo de error.
"""
def decorator(func: Callable) -> Callable:
@wraps(func)
def wrapper(args, *kwargs):
Ejecuta la función del LLM
result = func(args, *kwargs)
1. Clasifica el error
error_type = ErrorClassifier.classify(
result,
expected_schema=schema.model_json_schema() if schema else None
)
if error_type is None:
No hay error, actualiza el checkpoint
return result
2. Aplica estrategia de recovery según tipo
if error_type == ErrorType.FORMAT:
Reparación local: post-procesamiento
return _repair_format_error(result, schema)
elif error_type == ErrorType.HALLUCINATION:
Reinicio guiado: nuevo contexto con instrucciones corregidas
checkpoint_manager = _get_checkpoint_manager(args, kwargs)
return _guided_restart(checkpoint_manager, func, args, kwargs)
3. Si no se pudo recuperar, lanza error controlado
raise AgentRecoveryError(
message=f"Error no recuperable: {error_type}",
error_type=error_type,
original_output=result
)
return wrapper
return decorator
class AgentRecoveryError(Exception):
def __init__(self, message: str, error_type: str, original_output: str):
self.error_type = error_type
self.original_output = original_output
super().__init__(message)
```
Paso 4: Diseña Estrategias de Recovery Diferenciadas
Cada tipo de error necesita su propia estrategia. No uses el mismo approach para todo.
```python
def _repair_format_error(output: str, schema: Optional[Type[BaseModel]]) -> str:
"""Repara errores de formato con regex y post-procesamiento."""
Intenta extraer JSON de texto con markdown
json_match = re.search(r'```(?:json)?\s([\s\S]?)\s*```', output)
if json_match:
output = json_match.group(1)
Intenta parsear y arreglar comas extra
try:
Elimina trailing commas
cleaned = re.sub(r',\s*}', '}', output)
cleaned = re.sub(r',\s*]', ']', cleaned)
json.loads(cleaned)
return cleaned
except:
Si no se puede reparar, re-prompt con instrucciones más estrictas
return _re_prompt_with_strict_format(output)
def _guided_restart(
checkpoint_manager: CheckpointStateManager,
func: Callable,
args: tuple,
kwargs: dict
) -> str:
"""Reinicio guiado: restaura checkpoint y reintenta con contexto limpio."""
last_checkpoint = checkpoint_manager.rollback_to_last()
if last_checkpoint is None:
Sin checkpoint disponible, reinicia desde cero
return func(args, *kwargs)
Restaura el contexto del checkpoint
Añade instrucciones corregidas al contexto limpio
corrected_context = last_checkpoint.context.copy()
corrected_context.append({
"role": "system",
"content": "Nota: El intento anterior falló por alucinación. "
"Usa SOLO datos verificados de las fuentes proporcionadas. "
"Si no tienes un dato, responde 'No disponible'."
})
Reintenta con el contexto restaurado
kwargs['context'] = corrected_context
return func(args, *kwargs)
```
Paso 5: Añade Logging Estructurado con Clasificación Automática
Sin métricas, estás ciego. Necesitas saber qué errores ocurren, con qué frecuencia, y en qué contexto.
```python
from dataclasses import dataclass, field
from typing import List
from datetime import datetime
@dataclass
class ErrorLogEntry:
timestamp: datetime
agent_id: str
error_type: ErrorType
error_message: str
step_id: int
recovery_successful: bool
recovery_strategy: str
class ErrorLogger:
"""Logging estructurado con clasificación automática."""
def __init__(self):
self._logs: List[ErrorLogEntry] = []
def log_error(self,
agent_id: str,
error_type: ErrorType,
error_message: str,
step_id: int,
recovery_successful: bool,
recovery_strategy: str):
entry = ErrorLogEntry(
timestamp=datetime.now(),
agent_id=agent_id,
error_type=error_type,
error_message=error_message,
step_id=step_id,
recovery_successful=recovery_successful,
recovery_strategy=recovery_strategy
)
self._logs.append(entry)
def get_error_patterns(self) -> Dict[str, int]:
"""Identifica patrones de fallo para mejorar prompts."""
patterns = {}
for log in self._logs:
key = f"{log.error_type.value}_{log.recovery_strategy}"
patterns[key] = patterns.get(key, 0) + 1
return patterns
def get_agents_by_failure_rate(self) -> List[tuple]:
"""Ranking de agents por tasa de fallo."""
Implementación simplificada
return sorted(
self._logs,
key=lambda x: x.timestamp,
reverse=True
)
```
Cómo Usar Esto en tu Próximo Agent
El workflow completo es simple:
1. Cada vez que el LLM genera un output, el Error Classifier lo clasifica antes de que toque el estado.
2. Si no hay error, el CheckpointStateManager guarda el estado actual.
3. Si hay error, el Validation Decorator aplica la estrategia correcta según el tipo.
4. El Error Logger registra todo para que puedas iterar y mejorar.
```python
Ejemplo de uso completo
class MyAgent:
def __init__(self):
self.checkpoint_manager = CheckpointStateManager()
self.error_logger = ErrorLogger()
self.context = []
self.state = {}
@validate_output(schema=MyExpectedOutputSchema)
def run_step(self, user_input: str) -> str:
"""Ejecuta un paso del agente con validación de output."""
Añade input del usuario al contexto
self.context.append({"role": "user", "content": user_input})
Llama al LLM
llm_output = self._call_llm(self.context)
Si llegamos aquí, el output pasó la validación
Guardamos checkpoint
self.checkpoint_manager.save_checkpoint(
context=self.context,
state=self.state,
description=f"Step after user input: {user_input[:50]}"
)
Actualizamos estado
self.state["last_output"] = llm_output
self.context.append({"role": "assistant", "content": llm_output})
return llm_output
```
Lo Que Está en Juego
El 95% de los AI Agents que se despliegan hoy en producción no tienen recovery real. Tienen try-catch con esteroides. Y cuando llega el error real — el que no esperabas, el que no cubriste en tests — el agente no se recupera. Acumula errores. Produce outputs incoherentes. Y el usuario pierde confianza.
*La validación de output del LLM no es un lujo. Es la pieza crítica de infraestructura que falta en todos los frameworks actuales. *
Sin ella, tu agente es un sistema que incorpora ciegamente cualquier cosa que el LLM devuelva. Es como ejecutar SQL generado por usuario sin sanitizar. En algún momento, explota.
La buena noticia es que la solución es conocida. No necesitas un framework nuevo. Necesitas aplicar patrones que los sistemas distribuidos llevan usando 20 años: checkpoints, compensación, clasificación de errores, validación antes de mutación.
El Sistema de Recuperación de 3 Capas para AI Agents que te he mostrado — Error Classifier + CheckpointStateManager + Validation Decorator — es el mínimo que cualquier agente en producción debería tener.
Los agents que sobrevivan en producción no serán los más inteligentes. Serán los que sepan recuperarse de sus propios errores sin romperse.
Y eso empieza por dejar de tratar un sistema probabilístico como si fuera determinista.
Lee el artículo completo en brianmenagomez.com
Más sobre mis servicios en brianmenagomez.com
Herramientas: Conversor IAE CNAE · Gestorias cerca de ti · Calculadora IRPF

