0Pricing
AI Engineering Academy · Lección

Clasificación de los modos de fallo de los agentes

Construya una taxonomía de fallos de los agentes: errores de herramientas, salidas con formato incorrecto, bucles de razonamiento, agotamiento del contexto y falta de disponibilidad de servicios externos, y diseñe estrategias de recuperación para cada caso.

Clasificación de los modos de fallo de los agentes es una lección gratuita de AI Engineering Academy en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de AI Engineering Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de AI Engineering Academy incluye 4 lecciones en total.

Partes de esta lección aún no han sido traducidas y se muestran en inglés.

Why Agents Fail in Distinctive Ways

Agents fail differently from simple LLM calls. A single-turn call either returns an answer or throws an error. An agent executing a multi-step task can fail at any point — and the failure might not be obvious from the final output. Understanding the taxonomy of agent failure modes is the first step toward building agents that detect, diagnose, and recover from their own failures.

Failure Mode 1: Tool Errors

Tool errors occur when the agent calls a tool with invalid arguments, the tool raises an exception, or the tool returns an empty or malformed result. Examples include: calling a search API with a malformed query, querying a database with invalid SQL, or invoking a code executor that times out. Tool errors are the easiest to detect because they produce explicit exception signals that can be caught and handled.

class ToolError(Exception):
    def __init__(self, tool_name: str, args: dict, error: Exception):
        self.tool_name = tool_name
        self.args = args
        self.original_error = error
        super().__init__(f'Tool {tool_name} failed: {error}')

def safe_tool_call(tool_func, args: dict) -> str:
    try:
        result = tool_func(**args)
        if not result:
            return 'Tool returned empty result. Try a different approach.'
        return str(result)
    except Exception as e:
        raise ToolError(tool_func.__name__, args, e)

Failure Mode 2: Malformed Outputs

Malformed outputs happen when the agent generates text that does not match the expected format — for example, returning natural language when the next step expects JSON, or calling a tool with arguments in the wrong structure. This often happens when the agent confuses its current step with a previous one. Validate the format of every agent output before using it and re-prompt when the format is wrong.

import json

def validate_agent_output(raw_output: str, expected_format: str) -> dict:
    if expected_format == 'json':
        try:
            return json.loads(raw_output)
        except json.JSONDecodeError as e:
            return {
                'valid': False,
                'error': f'Expected JSON but got invalid JSON: {e}',
                'raw': raw_output[:200]
            }
    return {'valid': True, 'data': raw_output}

Failure Mode 3: Reasoning Loops

Reasoning loops occur when an agent repeats the same action or thought indefinitely without making progress. The agent might call the same search query 10 times in a row, getting the same empty result and not knowing what to try next. Detect loops by tracking recent actions and checking for repeats. When a loop is detected, inject a meta-prompt telling the agent to try a different approach.

from collections import Counter

class LoopDetector:
    def __init__(self, window: int = 5, threshold: int = 3):
        self.recent_actions = []
        self.window = window
        self.threshold = threshold

    def record(self, action: str) -> bool:
        self.recent_actions.append(action)
        if len(self.recent_actions) > self.window:
            self.recent_actions.pop(0)
        counts = Counter(self.recent_actions)
        most_common_count = counts.most_common(1)[0][1] if counts else 0
        return most_common_count >= self.threshold  # True = loop detected

Failure Mode 4: Context Exhaustion

Context exhaustion happens when the agent's accumulated history (tool calls, observations, thoughts) exceeds the model's context window. The model either truncates the history silently (losing critical information) or raises a token limit error. Prevent this by tracking token usage across steps and compressing the history (summarizing old steps) before it reaches the limit.

import tiktoken

CONTEXT_LIMIT = 100_000  # tokens
COMPRESS_AT = 80_000     # trigger compression with headroom

enc = tiktoken.encoding_for_model('gpt-4o')

def total_tokens(messages: list) -> int:
    return sum(len(enc.encode(str(m))) for m in messages)

def check_context(messages: list) -> str:
    tokens = total_tokens(messages)
    if tokens > COMPRESS_AT:
        return 'compress'
    if tokens > CONTEXT_LIMIT:
        return 'critical'
    return 'ok'

Failure Mode 5: External Service Unavailability

External service failures occur when a tool's underlying service is down, rate-limited, or returns unexpected errors. An agent that cannot reach the database it needs to query is stuck. Unlike reasoning loops (agent's fault), external failures are environment failures. Handle them with retry + exponential backoff, and have fallback tools that can approximate the result using different data sources.

import asyncio

async def resilient_tool_call(tool_func, args: dict, max_retries: int = 3) -> str:
    for attempt in range(max_retries):
        try:
            return await tool_func(**args)
        except (ConnectionError, TimeoutError) as e:
            if attempt == max_retries - 1:
                return f'Service unavailable after {max_retries} attempts. Error: {e}'
            wait = 2 ** attempt  # 1s, 2s, 4s
            await asyncio.sleep(wait)
    return 'Unexpected error in resilient_tool_call'

Failure Mode 6: Goal Misunderstanding

Goal misunderstanding is when the agent misinterprets the task and pursues a subtly different objective. This is the hardest failure to detect because the agent may complete successfully — just not the task the user intended. Mitigate it by asking the agent to restate the goal in its own words at the start, and by implementing a final verification step that checks whether the result actually answers the original question.

async def confirm_goal_understanding(original_task: str) -> str:
    resp = await client.chat.completions.create(
        model='gpt-4o',
        messages=[
            {'role': 'system', 'content': 'Restate the task in your own words. Be specific about what the final deliverable should be.'},
            {'role': 'user', 'content': f'Task: {original_task}'}
        ]
    )
    return resp.choices[0].message.content

# Use the restatement as the first step of the agent
# to catch misunderstandings before any tools are called

Building a Failure Classification System

Create a structured failure classifier that labels every agent exception with its type. This enables automatic routing to the appropriate recovery strategy. Store failure logs with type labels so you can analyze which failure modes are most common and prioritize which to address first. Tool errors and loops are typically most frequent and most fixable.

from enum import Enum
from dataclasses import dataclass

class FailureType(Enum):
    TOOL_ERROR = 'tool_error'
    MALFORMED_OUTPUT = 'malformed_output'
    REASONING_LOOP = 'reasoning_loop'
    CONTEXT_EXHAUSTION = 'context_exhaustion'
    EXTERNAL_SERVICE = 'external_service'
    GOAL_MISUNDERSTANDING = 'goal_misunderstanding'
    MAX_ITERATIONS = 'max_iterations'
    UNKNOWN = 'unknown'

@dataclass
class AgentFailure:
    failure_type: FailureType
    step: int
    tool_name: str | None
    error_message: str
    recoverable: bool

Mapping Failures to Recovery Actions

Each failure type has an appropriate recovery action. Tool errors warrant a retry with adjusted arguments. Loops warrant a diversity prompt telling the agent to try something new. Context exhaustion warrants compression. External service failures warrant fallback tools. Goal misunderstanding warrants a clarification request. Map these explicitly in a recovery router that the agent runtime invokes when failures occur.

RECOVERY_ACTIONS = {
    FailureType.TOOL_ERROR:           'retry_with_corrected_args',
    FailureType.MALFORMED_OUTPUT:     'reformat_output',
    FailureType.REASONING_LOOP:       'inject_diversity_prompt',
    FailureType.CONTEXT_EXHAUSTION:   'compress_history',
    FailureType.EXTERNAL_SERVICE:     'use_fallback_tool',
    FailureType.GOAL_MISUNDERSTANDING:'request_clarification',
    FailureType.MAX_ITERATIONS:       'escalate_to_human',
    FailureType.UNKNOWN:              'escalate_to_human'
}

Setting Maximum Iteration Limits

Every agent must have a maximum iteration limit as a hard safety boundary. Without it, a looping agent runs indefinitely, consuming tokens and money. Set the limit based on expected task complexity: a simple question-answering agent might cap at 5 steps, while a complex research agent might allow 20. When the limit is reached, log the failure, save the partial results, and escalate to a human or return a partial answer.

MAX_ITERATIONS = 15

async def run_agent(task: str) -> str:
    messages = [{'role': 'user', 'content': task}]
    loop_detector = LoopDetector()
    for iteration in range(MAX_ITERATIONS):
        response = await get_agent_action(messages)
        if response.is_final:
            return response.answer
        action_key = f'{response.tool}:{response.args}'
        if loop_detector.record(action_key):
            messages.append({'role': 'system', 'content': 'You are repeating yourself. Try a completely different approach.'})
            continue
        result = await execute_tool(response.tool, response.args)
        messages.append({'role': 'tool', 'content': result})
    return 'Task exceeded maximum iterations. Partial results: ' + get_partial_result(messages)

Logging Failures for Post-Mortem Analysis

Log every agent failure with enough context to diagnose it after the fact: the full task description, the complete action history up to the failure point, the failure type and error message, the iteration count, and the token usage. Store this in a failures table with an index on failure_type and task_id. Regularly review failure logs to identify which task types are most prone to specific failure modes and prioritize fixes accordingly.

import json
from dataclasses import asdict

async def log_agent_failure(task_id: str, failure: AgentFailure, history: list, pool):
    async with pool.acquire() as conn:
        await conn.execute('''
            INSERT INTO agent_failures
            (task_id, failure_type, step, tool_name, error_message,
             recoverable, action_history, failed_at)
            VALUES ($1, $2, $3, $4, $5, $6, $7, NOW())
        ''',
            task_id,
            failure.failure_type.value,
            failure.step,
            failure.tool_name,
            failure.error_message,
            failure.recoverable,
            json.dumps(history)
        )

Quick Check

Test your understanding of agent failure mode classification.

Lesson Recap

In this lesson you learned: six major agent failure modes include tool errors, malformed outputs, reasoning loops, context exhaustion, external service failures, and goal misunderstanding, loop detection via action history catches repetitive patterns before they exhaust the iteration budget, and mapping failure types to recovery actions enables automated self-healing. Next up we implement self-correction and reflective prompting.

Preguntas frecuentes

¿La lección «Clasificación de los modos de fallo de los agentes» es gratis?

Sí — el texto completo de «Clasificación de los modos de fallo de los agentes» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de AI Engineering Academy, actualiza a CoddyKit PRO. El curso de AI Engineering Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Clasificación de los modos de fallo de los agentes»?

Construya una taxonomía de fallos de los agentes: errores de herramientas, salidas con formato incorrecto, bucles de razonamiento, agotamiento del contexto y falta de disponibilidad de servicios exte… Practicas AI Engineering Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar AI Engineering Academy?

No se requiere experiencia previa. AI Engineering Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.

¿Cuánto tiempo toma la lección «Clasificación de los modos de fallo de los agentes»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de AI Engineering Academy?

Sí. Cada lección de AI Engineering Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Clasificación de los modos de fallo de los agentes
  2. Autocorrección y prompting reflexivo
  3. Puntos de control y reanudación de tareas
  4. Escalado con intervención humana
← Volver a AI Engineering Academy