Recibimos una llamada de un cliente del sector logístico: un agente que debía automatizar reservas de transporte había empezado a seleccionar sistemáticamente al transportista más caro en lugar del más barato. La diferencia de precio era visible — la causa, no. Los logs mostraban entradas y salidas. No mostraban por qué el agente, en un paso concreto, había llamado a una herramienta con los parámetros que utilizó. Nos costó cuatro horas reconstruir la secuencia de decisiones a partir de logs en bruto. El problema se solucionó en quince minutos — pero solo cuando supimos dónde buscar.
Este es el problema que se repite en la mayoría de los primeros despliegues de agentes en producción. Los equipos saben construir un agente, saben ponerlo en marcha, pero no saben depurarlo. La observability — la capacidad de entender el estado interno de un sistema a partir de sus salidas externas — no es un lujo para los agentes. Es la condición necesaria para poder mantener y mejorar el sistema.
Eval vs. observability: dos cosas distintas
Antes de entrar en herramientas y enfoques, conviene distinguir dos conceptos que se confunden con frecuencia.
Eval (evaluación) responde a la pregunta: *¿es suficiente la calidad del output del agente?* Se mide offline o sobre datos históricos — por ejemplo: ¿acertó el agente en el 87 % de los casos? ¿Generó el formato correcto? ¿Respondió bien las preguntas?
Observability responde a la pregunta: *¿qué ocurrió exactamente durante una ejecución concreta?* Se mide en runtime — mientras el agente está corriendo o justo después de que haya terminado — y captura la secuencia de decisiones, las llamadas a herramientas, el estado intermedio y los errores.
Eval es estadística retrospectiva. Observability es un instrumento quirúrgico para un incidente concreto. Ambas son necesarias — no se duplican entre sí.
La mayoría de los equipos empiezan con eval e ignoran la observability. En la práctica eso funciona hasta el primer incidente en producción. Después las prioridades se invierten.
Qué hay que capturar
Un agente no es una sola función. Es una red de pasos — cada paso tiene entrada, salida, prompt al LLM, decisión y, en su caso, error. Para cada ejecución del agente necesitas ver:
- Trace: el árbol completo de llamadas desde el prompt de entrada hasta la respuesta final, incluyendo todos los subárboles
- Spans: los pasos individuales dentro del trace — cada LLM call, cada llamada a herramienta, cada retrieval
- State diff: qué cambió en el estado interno del agente entre pasos (clave en
LangGraph) - Tool calls: los parámetros exactos de cada llamada a herramienta y el output exacto que devolvió la herramienta
- LLM prompts: cuál fue el prompt real enviado al modelo (no la plantilla — el texto final tras la interpolación)
- Tokens y latencia: número de tokens por span, tiempo por span — identificación de cuellos de botella
- Errores y reintentos: dónde falló el agente, cuántas veces reintentó y con qué resultado
Cada uno de estos elementos es imprescindible. Si solo capturas el output del último paso, tienes un log de aplicación — no observability del agente.
Por qué el logging clásico no es suficiente
Cuando los desarrolladores oyen "observability" por primera vez, suelen responder: "pero si ya hacemos logging". Lo hacen — pero no de la manera correcta para agentes.
Un log clásico es secuencial. Registro tras registro, timestamp, mensaje. Para una API sencilla basta. Para un agente donde una sola entrada del usuario desencadena decenas de llamadas al LLM, llamadas a herramientas y pasos de retrieval — en un árbol, no en una secuencia — el log plano es inútil. No tienes contexto, no tienes jerarquía, no tienes el estado en el tiempo.
Otro problema: frameworks de agentes como LangGraph internalizan muchas decisiones. Qué nodo se seleccionó, por qué se activó un edge concreto, cuál era el estado en el checkpoint — esto no es visible en un log stdout habitual. Necesitas integración directa con el framework, no un wrapper alrededor de él.
El tercer problema es el sampling y el coste. Un agente en producción puede ejecutar miles de runs al día. Loguear *todo* en un trace estructurado es caro en almacenamiento. Necesitas una estrategia de sampling — por ejemplo, capturar el 100 % de los errores y de los runs largos, y un 10–20 % de muestreo aleatorio de los runs exitosos.
Trace: la base de la observability del agente
Trace es el contenedor raíz de una ejecución del agente. Corresponde a una tarea — por ejemplo, una petición de usuario o una operación programada. Dentro del trace hay spans — cada span es un paso con metadatos.
La jerarquía tiene este aspecto:
- Trace: "Reservar transporte para el pedido #4821"
- - Span: LLM call — comprensión de la petición
- - Span: Tool call —
search_carriers(origin, destination, date) - - Span: Tool call —
get_price(carrier_id=12) - - Span: Tool call —
get_price(carrier_id=17) - - Span: LLM call — decisión y razonamiento
- - Span: Tool call —
book_shipment(carrier_id, price, ...)
Cada span tiene: tiempo de inicio y fin, entrada, salida, error si lo hay, ID del padre. A partir de esto podemos reconstruir todo el flujo de decisión sin necesidad de inferir nada.
En LangGraph este árbol se mapea de forma natural sobre grafos — cada nodo del grafo es un span. Herramientas como LangSmith capturan el state diff en cada transición de arista del grafo, lo que ofrece una vista detallada de la evolución del estado.
ReAct tracing: reason-act-observe en los logs
Cuando el agente utiliza la arquitectura ReAct — el bucle Reason, Act, Observe — la observability debería capturar cada uno de esos pasos de forma explícita.
Paso Reason: lo que el agente "pensó" — el output de chain-of-thought del modelo antes de llamar a la herramienta. Este es el paso más valioso para la depuración. Cuando el agente llama a la herramienta equivocada, la respuesta casi siempre es visible en el paso reason — el modelo "decidió" incorrectamente por una razón que está en el texto.
Paso Act: la llamada exacta a la herramienta con sus parámetros. No la plantilla — los valores reales tras la interpolación. Los errores en tool calling — parámetros mal formados, tipo incorrecto — son visibles aquí.
Paso Observe: lo que devolvió la herramienta. Importante: el output bruto de la herramienta antes de que el modelo lo procese. Cuando una herramienta devuelve un formato inesperado o un mensaje de error, este es el lugar donde lo verás.
Sin logging explícito de estos tres pasos por iteración, solo tienes el output final. Y el output final no te dirá por qué el agente cambió de decisión en la tercera iteración.
Métricas que hay que monitorizar
Más allá del trace por ejecución, necesitas métricas agregadas para el monitoring:
- Latencia p50/p95/p99 — no solo la latencia total de la ejecución, sino la latencia por nodo. ¿Dónde pasa el tiempo el agente?
- Consumo de tokens por ejecución — tendencia, outliers (ejecuciones con 10× más tokens = patrón de error)
- Tool error rate — porcentaje de ejecuciones donde al menos una tool call falló
- Retry rate — qué porcentaje de ejecuciones requirió reintento. Un retry rate del 12 % o más suele señalar un problema en la validación del schema o en el prompt
- Abandonment rate — ejecuciones donde el agente no alcanzó el objetivo y devolvió una respuesta de fallback
- Human escalation rate — en sistemas HITL (human-in-the-loop): porcentaje de ejecuciones escaladas a un humano
Cada una de estas métricas tiene carácter sintomático. Un retry rate elevado apunta a un tool calling inestable. Una latencia p99 alta con p50 baja apunta a escenarios outlier — probablemente contextos largos o bucles de reintento. Un abandonment rate alto apunta a casos límite que el agente no sabe gestionar.
Herramientas: LangSmith, Langfuse, Arize Phoenix
Para despliegues en producción existen hoy tres plataformas principales:
`LangSmith` — la integración más profunda con LangGraph y LangChain. Captura automáticamente traces, state diff, tokens y latencia. Tiene un playground para reproducir ejecuciones — puedes tomar un trace concreto y volver a ejecutarlo con un prompt modificado. Es cloud-hosted, con pricing por volumen de traces. Si tu stack es LangGraph, LangSmith es la elección natural.
`Langfuse` — agnóstico al framework, self-hostable (Postgres + ClickHouse). SDK para Python, TypeScript y REST. Funciona aunque no escribas con LangGraph — llamas al SDK directamente en cada LLM call y tool call. Adecuado para equipos que quieren control total sobre los datos (sectores regulados, requisitos on-prem). El self-hosting añade overhead de operaciones — hay que mantener el clúster ClickHouse.
`Arize Phoenix` — basado en OpenTelemetry. Captura traces mediante el protocolo estándar OTel, lo que implica integración con el stack de monitoring existente (Prometheus, Grafana, Jaeger). Además: más de 50 métricas de eval directamente en la plataforma — faithfulness, detección de alucinaciones, relevance. Para equipos donde la observability del agente debe ser parte de una solución APM más amplia.
Elección: si estás en LangGraph en cloud — LangSmith. Si necesitas self-hosting o tienes un stack heterogéneo — Langfuse. Si quieres observability y eval en uno solo y tienes infraestructura OTel — Arize Phoenix.
Para proyectos más pequeños en fase inicial: Langfuse self-hosted en un Docker Compose sencillo es suficiente y ahorra costes.
Replay y depuración de un incidente concreto
La observability tiene mayor valor ante un incidente concreto. El proceso que funciona en la práctica:
- 1.Identifica el trace por trace ID o por filtro (por ejemplo: todas las ejecuciones con tool error rate > 0 en las últimas 24 horas)
- 2.Abre el state diff — observa cómo cambió el estado del agente paso a paso. ¿Dónde se produjo el cambio que no esperabas?
- 3.Lee el texto reason en cada LLM call — busca la lógica que responde al "por qué el agente tomó esta decisión"
- 4.Comprueba los outputs de las herramientas — ¿podría estar el problema en lo que devolvió la herramienta, y no en lo que el agente hizo con ese output?
- 5.Ejecuta el replay con el prompt o los parámetros modificados — verificación de la hipótesis sin necesidad del entorno real
Este proceso reduce el MTTR (mean time to resolution) de horas a minutos. Por experiencia: la mayoría de los bugs de agentes no están en el LLM reasoning — están en el tool calling, en el formato inesperado del output de la herramienta o en la gestión del estado. La observability permite hacer esa distinción en segundos.
Alertas y monitorización proactiva
La depuración reactiva es solo una capa. Un sistema en producción necesita también alertas proactivas.
Reglas básicas para el alerting:
- Tool error rate > 5 % en una ventana horaria → alerta, probable cambio en el sistema downstream o en el schema de la herramienta
- Latencia media de ejecución > 2× baseline → alerta, escenario outlier o ralentización upstream
- Abandonment rate > 10 % en un día → alerta, nuevos casos límite en producción
- Coste en tokens por día > X EUR — alerta de coste, imprescindible en agentes donde el looping puede generar llamadas sin límite. Un agente sin alerta de coste puede generar de noche miles de llamadas y una factura del orden de miles de euros — un riesgo que vemos en la práctica
Las alertas deben enlazar al trace, no solo al número. Cuando recibo una alerta "tool error rate 8 %", quiero directamente el enlace al trace donde ocurrió — no un número sin contexto.
Observability y costes del agente
La observability en sí genera costes — almacenamiento de traces, cómputo para analytics. Para sistemas en producción con alto volumen es importante configurar una estrategia de sampling.
Enfoque recomendado:
- 100 % de sampling para ejecuciones erróneas (tool error, abandonment, timeout)
- 100 % de sampling para ejecuciones con latencia inusual (outliers p99)
- 10–20 % de sampling para ejecuciones exitosas dentro de la norma
- 100 % de sampling durante el despliegue de una nueva versión del agente (primeras 24–48 horas)
Esto reduce los costes de almacenamiento entre 5 y 10 veces manteniendo visibilidad completa para el diagnóstico. Plataformas como Langfuse soportan la configuración del sampling rate de forma nativa.
Relación con los costes del agente en producción: la observability te permite identificar qué ejecuciones son ineficientes — por ejemplo, ejecuciones donde el agente llama repetidamente a la misma herramienta por culpa de una respuesta ambigua. Esto es típicamente un problema de fiabilidad en el tool calling que la observability expone antes de que llegue a incrementar significativamente los costes.
La dimensión de seguridad del tracing
Los traces contienen datos sensibles — prompts, outputs de herramientas, estado interno del agente. En sectores regulados (finanzas, sanidad, legal) esto exige:
- Cifrado de traces at rest y in transit
- Control de acceso — ¿quién puede leer los registros de traces?
- Política de retención — ¿cuánto tiempo se conservan los traces?
- PII scrubbing — los datos personales en prompts o outputs de herramientas no pueden almacenarse en texto plano
Langfuse self-hosted proporciona control total sobre estos aspectos. Las plataformas cloud deben evaluarse frente a tus requisitos GDPR/data residency — especialmente si los traces contienen datos empresariales o de clientes.
Para despliegues LLM on-prem, la observability self-hosted es casi siempre un requisito, no una opción.
Preguntas frecuentes
¿Es necesario tener observability antes del primer despliegue del agente?
No necesariamente antes del primer despliegue de prueba — pero sí antes de desplegar en producción con usuarios reales o datos reales. Sin observability no tienes forma de identificar dónde falla el agente ni por qué. El primer incidente en producción que exige depuración sin tracing suele convencer al equipo más rápido que cualquier argumento.
¿Cuál es la diferencia entre tracing y logging estándar?
Un log clásico es una secuencia plana de registros. El tracing captura un árbol jerárquico — el trace contiene spans, los spans contienen child spans. Para un agente donde una sola entrada desencadena decenas de llamadas en árbol, la estructura jerárquica es imprescindible. Además, el tracing captura el state diff entre pasos, algo que el log plano no permite.
¿Funciona la observability también para agentes que no usan LangGraph?
Sí. Langfuse y Arize Phoenix son agnósticos al framework — basta con llamar al SDK en cada LLM call y tool call. Si escribes tu propio agente sin framework, puedes añadir OpenTelemetry spans manualmente. LangSmith tiene la integración más profunda con LangGraph, pero también existen integraciones para otros frameworks.
¿Cuánto cuesta?
Langfuse self-hosted es gratuito (solo costes de infraestructura — un Docker Compose sencillo con Postgres + ClickHouse). LangSmith y Arize Phoenix tienen un free tier para volúmenes bajos; los planes de pago parten de decenas de euros al mes. El principal coste no es la plataforma — es el almacenamiento de traces, especialmente con un alto volumen de ejecuciones.
¿Hay que loguear los prompts completos del LLM?
Sí — con una condición: si los prompts contienen datos personales o empresariales, hay que aplicar PII scrubbing antes de almacenarlos. Loguear solo metadatos (recuento de tokens, latencia, nombre de la herramienta) sin el contenido del prompt es más barato, pero limita considerablemente la capacidad de depuración. Recomendamos loguear los prompts completos con política de retención y control de acceso.
Conclusión
*La observability de los agentes de IA no es cuestión de herramientas — es una cultura de responsabilidad sobre lo que el sistema hace en producción. Cuando un agente falla, la pregunta "por qué" debe tener respuesta en minutos, no en horas. En MP Industrial Solutions ayudamos a los equipos a integrar la observability como parte de la arquitectura del agente — no como una capa añadida a posteriori. Si estás considerando desplegar un agente o estás gestionando un incidente en un sistema existente, nos encantará revisar tu caso concreto.*
