Debugging de ejecuciones de agentes

El debugging de runs ayuda a entender por qué un agente tomó una decisión específica.
En esta página
  1. Idea en 30 segundos
  2. Problema principal
  3. Cómo funciona
  4. Señales típicas de producción para debugging de runs
  5. Cómo leer el debugging-layer
  6. Cuándo usarlo
  7. Ejemplo de implementación
  8. Investigación
  9. Errores típicos
  10. Empezar análisis con "cualquier" error del log
  11. Sin correlación trace + logs + metrics
  12. Ignorar repeated calls y stop_reason
  13. No comparar con el release anterior
  14. Cerrar incidente sin replay ni verificación
  15. Autoevaluación
  16. FAQ
  17. Páginas relacionadas

Idea en 30 segundos

El debugging de runs de agentes ayuda a pasar del síntoma a la causa: qué se rompió, en qué paso y por qué.

Para eso, hay que correlacionar tracing, logs y métricas de un run problemático.

Sin esa correlación, el equipo suele ver solo el error final y no el camino completo que llevó hasta él.

Problema principal

En sistemas de agentes, un incidente rara vez tiene una sola causa obvia.

El error final puede ser solo una consecuencia: el problema real pudo empezar antes, por ejemplo con un tool call lento, un retry fallido o una regresión después del release. Sin debugging sistemático, esto es difícil de localizar rápido.

Ahora veamos cómo leer estas señales y encontrar root cause de forma estable.

En producción, esto suele verse así:

  • en logs hay muchos eventos, pero sin secuencia clara;
  • la causa se mezcla con errores secundarios;
  • el incidente fue "arreglado", pero vuelve después del release;
  • el MTTR sube porque el equipo reconstruye el contexto del incidente desde cero cada vez.

Por eso, el debugging de un run debe ser un proceso operativo separado, no una búsqueda manual del "primer error".

Cómo funciona

Un debugging run práctico normalmente tiene tres niveles:

  • contexto del run (run_id, trace_id, release, workflow);
  • evidence -> análisis (spans, logs, metrics, stop_reason);
  • decisión (hipótesis -> fix -> verificación con replay y tests).

Estos niveles responden: dónde está el problema, por qué apareció y si el fix realmente lo elimina. Tracing muestra el camino, logs muestran eventos y métricas muestran escala y tendencia.

Muchos logs != debugging rápido. La velocidad no aparece por la cantidad de datos, sino por su correlación alrededor de un run.

Señales típicas de producción para debugging de runs

SeñalDónde mirarPara qué sirve
first_error_spantracingencontrar el punto donde apareció primero el error
slowest_spantracing + métricascandidato a bottleneck (requiere verificación)
stop_reasonlog run_finishedentender cómo terminó el run
error_classlogs tool_result / llm_resultseparar timeout de error lógico
repeated_tool_callslogs tool_call + tool metricsdetectar llamadas repetidas (loops, retries, tool spam)
run_latency_p95métricasvalidar si el incidente ya es sistémico
release_diffdashboard de comparación de releasesdetectar regresión tras cambios
synthetic_run_statushealth checksverificar impacto en workflow crítico

Para mantener estable el debugging, estas señales normalmente se segmentan por release, workflow, model y tool.

Importante: no agregues labels de alta cardinalidad (run_id, request_id, user_id) en métricas. Para eso, usa logs y tracing.

Cómo leer el debugging-layer

Qué run falló -> en qué paso -> por qué exactamente pasó. Estos tres niveles siempre deben leerse juntos.

Es clave mirar tendencias y diferencias entre releases, no solo un evento aislado.

Combinaciones típicas de señales:

  • first_error_span=tool_call + tool_error_rate sube -> problema en un tool-layer específico;
  • run_latency_p95 sube + tool_latency_p95 estable -> probable problema en LLM o lógica runtime;
  • repeated_tool_calls sube + stop_reason=max_steps -> el agente quedó en loop;
  • error_rate sube tras release + release_diff positivo -> regresión por cambio, no incidente puntual;
  • synthetic_run_status=fail + health_score baja -> el problema ya impacta el workflow crítico.

Cuándo usarlo

Un debugging-flow formal no siempre es necesario.

Para un escenario simple single-shot sin tools, puede bastar logging básico y revisión manual del error.

Pero un enfoque sistemático de debugging se vuelve crítico cuando:

  • el run tiene varios pasos de reasoning y tool calls;
  • los incidentes impactan latencia, costo o SLO;
  • hay releases frecuentes y es importante detectar regresiones rápido;
  • el equipo tiene proceso on-call y necesita MTTR predecible.

Ejemplo de implementación

Abajo hay una función simplificada que recoge evidence de un run y forma una hipótesis base. No reemplaza el incident tooling completo, pero muestra un proceso práctico de debugging.

PYTHON
from collections import Counter


def debug_run(run_id, trace_events, log_events, debug_metrics_snapshot):
    run_spans = sorted(
        [s for s in trace_events if s.get("run_id") == run_id],
        key=lambda s: s.get("started_at_ms", 0),
    )
    run_logs = [e for e in log_events if e.get("run_id") == run_id]

    first_error_span = next((s for s in run_spans if s.get("status") == "error"), None)
    # slowest_span puede ser None si el run no contiene spans
    slowest_span = max(run_spans, key=lambda s: s.get("latency_ms", 0), default=None)

    stop_reason = "unknown"
    for event in reversed(run_logs):
        if event.get("event") == "run_finished":
            stop_reason = event.get("stop_reason", "unknown")
            break

    seen_signatures = set()
    repeated_tools = Counter()
    for event in run_logs:
        if event.get("event") != "tool_call":
            continue
        signature = (event.get("tool"), event.get("args_hash"))
        if signature in seen_signatures:
            repeated_tools[event.get("tool")] += 1
        else:
            seen_signatures.add(signature)

    hypotheses = []
    if first_error_span and first_error_span.get("step_type") == "tool_call":
        hypotheses.append("Fallo probable en tool-layer: revisar disponibilidad de herramienta y timeout policy.")

    if repeated_tools:
        hypotheses.append("Hay tool calls repetidos: revisar dedupe/cache y stop conditions.")

    if slowest_span and debug_metrics_snapshot.get("run_latency_p95_ms", 0) > debug_metrics_snapshot.get("slo_latency_ms", 2500):
        hypotheses.append("La p95 latency está por encima del SLO: localizar bottleneck con slowest_span.")

    if debug_metrics_snapshot.get("release_error_rate_delta", 0) > 0:
        hypotheses.append("error_rate subió después del release: revisar cambios en prompt/runtime/tool routing.")

    return {
        "run_id": run_id,
        "first_error_span": first_error_span,
        "slowest_span": slowest_span,
        "stop_reason": stop_reason,
        "repeated_tools": dict(repeated_tools),
        "hypotheses": hypotheses,
    }

El debugging no se considera terminado hasta que el problema sea reproducible (replay) y se confirme que el fix lo elimina de forma estable. Si el problema no se puede reproducir, el debugging pasa a modo hipótesis, no a modo evidencia.

Insight

Replay != optional.

Sin replay, es una suposición.
Con replay, es evidencia.

Así puede verse un debugging snapshot corto:

Runfirst_error_spanslowest_spanstop_reasonConclusión
run_9fd2tool_call: search_docstool_call: search_docs (1.8s)tool_errortool degradado + retries
run_a113llm_generatellm_generate (2.4s)step_errorfallo de modelo tras release
run_d77creasoning (3.1s)max_stepsloop sin error explícito

Investigación

Cuando se dispara una señal de incidente:

  1. fijar run_id, trace_id, release y workflow afectado;
  2. encontrar first_error_span y slowest_span en tracing;
  3. revisar stop_reason, error_class, repeated_tool_calls en logs;
  4. confirmar escala del problema en métricas (spike o tendencia) y comparar diferencias entre releases.

Errores típicos

Incluso con observability configurada, el debugging suele fallar por errores comunes.

Empezar análisis con "cualquier" error del log

Sin vincular el análisis a un run_id específico, el equipo mezcla síntomas de incidentes distintos. En ese modo, es difícil separar un problema local de un fallo en cascada.

Sin correlación trace + logs + metrics

Si tracing, logs y métricas se revisan por separado, las hipótesis suelen contradecirse. Por eso, MTTR sube incluso en fallos de herramienta simples.

Ignorar repeated calls y stop_reason

Sin esas señales, es fácil perder loops y retry storms. Eso suele ocultar la fase temprana de spam de herramientas.

No comparar con el release anterior

Sin release_diff, el equipo no ve si el problema apareció tras cambios. Como resultado, la regresión permanece más tiempo en producción.

Cerrar incidente sin replay ni verificación

Un fix puede quitar el síntoma, no la causa. Esto eleva el riesgo de caída parcial repetida.

Autoevaluación

Checklist corta de debugging-flow baseline antes de release.

Progreso: 0/9

⚠ Falta observability base

Será difícil depurar el sistema en production. Empieza con run_id, structured logs y tracing de tool calls.

FAQ

Q: ¿Por dónde empezar el debugging de un run problemático?
A: Empieza con run_id y trace_id: encuentra first_error_span, revisa stop_reason y luego confirma el alcance en métricas. first_error_span es la forma más rápida de hallar el punto de fallo.

Q: ¿Qué es más importante para debugging: tracing o logs?
A: Ambos juntos: tracing muestra el camino de pasos, logs aportan detalles de eventos (error_class, args_hash, policy decision).

Q: ¿Cómo saber si es regresión de release y no fallo puntual?
A: Compara error_rate, latency_p95, repeated_tool_calls entre releases. Si la señal es consistentemente peor después del release, es regresión.

Q: ¿Cuál es el mínimo de datos para depurar en 10-15 minutos?
A: Mínimo: run_id, trace_id, first_error_span, stop_reason, error_class, latency_p95 y contexto de release.

Páginas relacionadas

Siguiente en este tema:

⏱️ 8 min de lecturaActualizado 23 de marzo de 2026Dificultad: ★★★
Integrado: control en producciónOnceOnly
Guardrails para agentes con tool-calling
Lleva este patrón a producción con gobernanza:
  • Presupuestos (pasos / topes de gasto)
  • Permisos de herramientas (allowlist / blocklist)
  • Kill switch y parada por incidente
  • Idempotencia y dedupe
  • Audit logs y trazabilidad
Mención integrada: OnceOnly es una capa de control para sistemas de agentes en producción.

Autor

Nick — ingeniero que construye infraestructura para agentes de IA en producción.

Enfoque: patrones de agentes, modos de fallo, control del runtime y fiabilidad del sistema.

🔗 GitHub: https://github.com/mykolademyanov


Nota editorial

Esta documentación está asistida por IA, con responsabilidad editorial humana sobre la exactitud, la claridad y la relevancia en producción.

El contenido se basa en fallos reales, post-mortems e incidentes operativos en sistemas de agentes de IA desplegados.