← Alle Playbooks
Playbook· build

Ver qué hizo realmente tu agente, tracing en 10 pasos con OpenTelemetry

Un agente se ejecuta, hace veinte llamadas a herramientas y al final entrega algo. ¿Por qué? Con tracing abres la caja negra y ves cada paso en una línea de tiempo. Así se configura.

Has construido un agente, llama a un par de herramientas, piensa un poco entre medias y al final entrega un resultado. Si el resultado es bueno, te alegras. Si está mal, te quedas a oscuras. ¿Qué herramienta se disparó? ¿Qué devolvió? ¿Dónde se torció la cadena? Con un solo prompt todavía puedes releerlo en el log. Con un agente de veinte pasos repartidos por tres servidores MCP, ya no.

El tracing resuelve justo eso. Haces visible cada paso como una entrada en una línea de tiempo, con duración, entrada y salida, anidado tal y como ocurrieron las llamadas de verdad. No es una técnica exótica, es el mismo estándar con el que se observan los grandes sistemas web desde hace años. Y desde que la spec de MCP del 28 de julio de 2026 ancló el W3C Trace Context de forma fija, un trace así viaja limpio desde tu app anfitriona, pasando por el cliente y por el servidor, hasta la última herramienta. Repaso los diez pasos que necesitas para pasar de ciego a ver.

Paso 1, la diferencia entre logs y traces

Los logs son notas que lanzas por ahí. "Herramienta search invocada." "Respuesta recibida." Cada línea va por su cuenta, ninguna sabe de la otra. Con un agente que hace muchas llamadas paralelas y anidadas, eso se convierte rápido en un amasijo en el que ya no asignas nada a nada.

Un trace es una línea de tiempo con estructura. Un trace abarca una ejecución completa, por ejemplo una petición entera al agente. Dentro viven los spans, y cada span es una sección con inicio, final y span padre. La ejecución del agente es el span exterior, cada llamada a herramienta es un span hijo dentro, y cada llamada al LLM también. Al final ves un árbol en lugar de una lista, y en ese árbol lees de inmediato adónde se va el tiempo y dónde falló algo.

Paso 2, el vocabulario que de verdad necesitas

Tres términos, para empezar no hacen falta más. Un trace es el proceso completo y tiene un trace ID. Un span es una sección dentro de él y tiene su propio span ID más una referencia a su span padre. Un atributo es un par clave-valor que cuelgas de un span, por ejemplo qué modelo se ejecutó o cuántos tokens costó.

Con eso basta para entender todo lo demás. OpenTelemetry, OTel para abreviar, es el estándar abierto que define esas tres cosas. Es neutral respecto al fabricante, o sea que instrumentas una vez y luego puedes mandar los traces a cualquier backend compatible sin tocar tu código.

Paso 3, por qué el trace aguanta a través de las fronteras entre sistemas

El truco de OTel es el paso de los IDs. Cuando tu agente llama a un servidor MCP, le pasa el trace ID. El servidor abre su propio span, lo engancha como hijo y le pasa el ID a la herramienta. Así surge un único árbol, aunque hayan participado tres procesos separados.

El estándar para eso se llama W3C Trace Context. Transporta la información en una cabecera llamada traceparent, a lo que se suman tracestate y baggage para información adicional. El formato es fijo, un ejemplo ilustrativo tiene esta pinta:

traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01

Cuatro partes, separadas por guiones. Versión, luego el trace ID, luego el ID del span que llama, y por último un flag que indica si este trace se está registrando. Nunca tienes que construirlo a mano, lo hace la librería. Pero ayuda saber que es justo esa cadena de caracteres la que hace que todo se mantenga unido.

Paso 4, qué cambia en esto la nueva spec de MCP

Hasta hace poco, dónde debían ir esos IDs dentro de una petición MCP era cuestión de interpretación. Cada servidor lo hacía un poco distinto, y un trace se cortaba a menudo en la frontera entre cliente y servidor. La versión de spec 2026-07-28 pone orden. traceparent, tracestate y baggage tienen ahora sitios fijos en el campo _meta de cada petición. Eso es SEP-414.

Para ti eso significa que, si usas un servidor o un cliente MCP actual, o bien el paso del contexto de trace ya viene incluido, o bien puedes fiarte de que los nombres de las claves son correctos. Se acabó adivinar adónde va el ID. Quien todavía no conozca los detalles de la spec los encuentra en el playbook sobre la spec 2026-07-28.

Paso 5, elegir un backend donde aterricen los traces

Instrumentar es una mitad, mirarlo es la otra. Necesitas un destino que reciba los traces y los muestre como línea de tiempo. Para aplicaciones de LLM y de agentes, Langfuse es una buena primera opción, porque está hecho justo para este caso. Por cada span enseña los prompts, las respuestas, el número de tokens y los costes, no solo barras de tiempo peladas.

Langfuse se puede autoalojar y acepta traces en formato OpenTelemetry. Ese es el punto que te da libertad. Escribes tu código contra OTel, y si más adelante Langfuse no te encaja, mandas los mismos traces a otro sitio. Alternativas que también hablan OTel son Jaeger para la mirada puramente técnica, o un backend gestionado si no quieres operar nada tú mismo.

Paso 6, poner el primer span a mano

Empieza pequeño. Coge una única función, el punto más exterior de tu agente, y envuélvela en un span. En Python con el SDK de OTel, en esencia se ve así:

from opentelemetry import trace

tracer = trace.get_tracer("mein-agent")

with tracer.start_as_current_span("agent-run") as span:
    span.set_attribute("agent.task", task_beschreibung)
    ergebnis = agent.run(task_beschreibung)
    span.set_attribute("agent.status", "ok")

Ahí está toda la magia. start_as_current_span abre el span, todo lo que pasa dentro del bloque with cuelga automáticamente por debajo, y al final se cierra solo. Los atributos que pongas aparecen luego en el backend y hacen legible el span. En TypeScript y en otros lenguajes el patrón es idéntico, solo cambia la sintaxis.

Paso 7, hacer visibles las llamadas a herramientas una a una

Un span alrededor de toda la ejecución te enseña la duración total, nada más. El valor llega cuando cada llamada a herramienta se convierte en su propio span hijo. Así que pones también un span alrededor de cada llamada, con el nombre de la herramienta y los argumentos importantes como atributos.

with tracer.start_as_current_span("tool-call") as span:
    span.set_attribute("tool.name", tool_name)
    span.set_attribute("tool.args", str(argumente)[:500])
    antwort = tool.call(argumente)
    span.set_attribute("tool.result_len", len(str(antwort)))

Un detalle que si no te acaba mordiendo. Recorta los valores largos, aquí a 500 caracteres. Si guardas respuestas completas de herramientas con diez mil caracteres como atributo, inflas tus traces y vuelves lento el backend. El sentido es ver la estructura, no archivar cada byte.

Paso 8, no escribir secretos en el trace

Aquí es donde el tracing se vuelve peligroso si no tienes cuidado. Un trace captura entradas y salidas, y ahí acaban rápido cosas que no pintan nada en un backend de observabilidad. Una clave de API en un argumento. El correo de un cliente en la respuesta de una herramienta. Un prompt entero con datos personales.

Constrúyete una pequeña función que sustituya patrones conocidos antes de asignar un atributo, claves, direcciones de correo, tokens. Y con cada atributo piensa si de verdad necesitas ese valor para depurar un problema. Casi siempre basta con la longitud o un hash en lugar del contenido. Quien quiera profundizar en el tema de la minimización de datos encuentra las bases en el playbook Protección de datos con herramientas de IA.

Paso 9, responder una pregunta a partir del trace

Instrumentar es un medio para un fin. El fin es responder rápido a una pregunta concreta. Tres salen una y otra vez. La primera, adónde se va el tiempo. Abres la ejecución más lenta y ves de inmediato qué span llena la barra, muchas veces es una única llamada a herramienta que se queda bloqueada en una API externa.

La segunda, dónde se tuerce la lógica. Una ejecución entrega tonterías, recorres los spans hijos en orden y encuentras el punto en el que una herramienta ya devolvió la respuesta equivocada, antes de que el modelo construyera encima. La tercera, cuánto cuesta de verdad una ejecución. Si registras el número de tokens como atributos, los sumas a lo largo del trace y ves el coste real por petición en lugar de una factura mensual sin desglose. Para el lado puramente de costes merece la pena además el playbook Cuánto cuesta la IA de verdad.

Paso 10, convertir el tracing en costumbre

Un agente instrumentado una vez sirve de poco si solo lo miras cuando ya hay algo ardiendo. El beneficio viene de la rutina. Mira unos cuantos traces después de desplegar un cambio, no solo cuando alguien se queja. Fíjate dos o tres atributos que registres en cada agente, tarea, modelo, estado, número de tokens, para que tus traces sigan siendo comparables.

Y separa con limpieza tracing y evaluación. Un trace te dice qué pasó, un eval te dice si el resultado fue bueno. Necesitas los dos, pero son dos herramientas distintas. Si quieres seguir por la parte del eval, el playbook Eval de agente en 60 minutos es el siguiente paso adecuado.

Qué viene después

Si todavía no tienes un agente propio en marcha para el que merezca la pena el tracing, construye primero uno con el Claude Agent SDK y luego vuelve aquí. Quien ya opere servidores MCP y quiera saber qué más cambia la nueva spec, que lea MCP se vuelve stateless. Y para el arco grande sobre la calidad de los agentes, Eval de agente en 60 minutos va como gemelo al lado de este playbook.

Fuente

  • W3C Trace Context en la spec de MCP (SEP-414), anuncio oficial: https://blog.modelcontextprotocol.io/posts/2026-07-28-release-candidate/
  • Conceptos de OpenTelemetry (traces, spans, propagación de contexto): https://opentelemetry.io/docs/concepts/
  • Estándar W3C Trace Context (formato traceparent): https://www.w3.org/TR/trace-context/
  • Langfuse, tracing compatible con OpenTelemetry para aplicaciones LLM: https://langfuse.com/docs
Ver qué hizo realmente tu agente, tracing en 10 pasos con OpenTelemetry — StudioMeyer Academy