Phase 13 - Lesson 20

OpenTelemetry GenAI — Rastreabilidad de Llamadas a Herramientas de Extremo a Extremo

This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.

Un agente llama a cinco herramientas, tres servidores MCP y dos subagentes. Necesita un único trace a lo largo de todo esto. Las convenciones semánticas de OpenTelemetry GenAI (atributos estables en v1.37 y superiores) son el estándar de 2026, soportadas nativamente por Datadog, Langfuse, Arize Phoenix, OpenLLMetry y AgentOps. Esta lección nombra los atributos obligatorios, recorre la jerarquía de spans (agente → LLM → herramienta) y entrega un emisor de spans de la stdlib que puede conectar a cualquier exportador OTel.

Tipo: Build Lenguajes: Python (stdlib, emisor de spans de OTel) Prerrequisitos: Fase 13 · 07 (servidor MCP), Fase 13 · 08 (cliente MCP) Tiempo: ~75 minutos

Objetivos de Aprendizaje

  • Nombrar los atributos OTel GenAI requeridos para un span de LLM y un span de ejecución de herramienta.
  • Construir una jerarquía de traces que cubra el ciclo del agente, la llamada a LLM, la llamada a herramienta y el despacho del cliente MCP.
  • Decidir qué contenido capturar (opt-in) frente a redactar/ocultar (valores por defecto).
  • Emitir spans a un colector local (Jaeger, Langfuse) sin tener que reescribir el código de la herramienta.

El Problema

Una depuración de febrero de 2026: el usuario informa "mi agente a veces tarda 30 segundos en responder; otras veces 3 segundos". Sin traces. Los registros muestran la llamada a LLM, pero no el despacho de herramientas, ni la ida y vuelta al servidor MCP, ni el subagente. Usted adivina. Finalmente encuentra: un servidor MCP se cuelga ocasionalmente en un arranque en frío (cold-start).

Sin rastreabilidad de extremo a extremo, no puede encontrar esto. OTel GenAI lo soluciona.

Las convenciones se consolidaron en 2025-2026 bajo el grupo de convenciones semánticas de OpenTelemetry (semantic-conventions). Definen nombres de atributos estables para que Datadog, Langfuse, Phoenix, OpenLLMetry y AgentOps analicen los mismos spans. Instrumente una vez; envíe a cualquier backend.

El Concepto

Jerarquía de spans

agent.invoke_agent  (top, INTERNAL span)
 ├── llm.chat       (CLIENT span)
 ├── tool.execute   (INTERNAL)
 │    └── mcp.call  (CLIENT span)
 ├── llm.chat       (CLIENT span)
 └── subagent.invoke (INTERNAL)

Todo se anida bajo un único ID de trace. Los IDs de span vinculan las relaciones padre-hijo.

Atributos requeridos

Según las convenciones semánticas (semconv) de 2025-2026:

  • gen_ai.operation.name"chat", "text_completion", "embeddings", "execute_tool", "invoke_agent".
  • gen_ai.provider.name"openai", "anthropic", "google", "azure_openai".
  • gen_ai.request.model — cadena del modelo solicitado (p. ej., "gpt-4o-2024-08-06").
  • gen_ai.response.model — el modelo realmente servido.
  • gen_ai.usage.input_tokens / gen_ai.usage.output_tokens.
  • gen_ai.response.id — ID de respuesta del proveedor para correlación.

Para spans de herramientas:

  • gen_ai.tool.name — identificador de la herramienta.
  • gen_ai.tool.call.id — el ID de llamada específico.
  • gen_ai.tool.description — descripción de la herramienta (opcional).

Para spans de agentes:

  • gen_ai.agent.name / gen_ai.agent.id / gen_ai.agent.description.

Tipos de Spans (Span kinds)

  • SpanKind.CLIENT para llamadas que cruzan un límite de proceso (proveedor de LLM, servidor MCP).
  • SpanKind.INTERNAL para los pasos del propio ciclo del agente y la ejecución de herramientas.

Captura de contenido opcional (Opt-in)

Por defecto, los spans contienen métricas y tiempos, no prompts ni completions. Los payloads grandes y la PII (información de identificación personal) están desactivados por defecto. Establezca OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental y las variables de entorno específicas de captura de contenido para incluir el contenido. Revise detenidamente antes de habilitarlo en producción.

Eventos en spans

Los eventos a nivel de token se pueden agregar como eventos de span:

  • gen_ai.content.prompt — mensajes de entrada.
  • gen_ai.content.completion — mensajes de salida.
  • gen_ai.content.tool_call — llamada a herramienta según se registró.

Los eventos se ordenan cronológicamente dentro de un span para una reproducción detallada.

Exportadores (Exporters)

Los spans de OTel se exportan a:

  • Jaeger / Tempo. OSS, on-prem.
  • Langfuse. Específico para observabilidad de LLM; visualiza el uso de tokens.
  • Arize Phoenix. Evaluaciones + tracing combinados.
  • Datadog. Comercial; analiza de forma nativa los atributos gen_ai.*.
  • Honeycomb. Orientado a columnas; amigable para consultas.

Todos hablan OTLP, el formato de transmisión (wire format). A su código no le importa.

Propagación a través de MCP

Cuando un cliente MCP llama a un servidor, inyecte el cabezal W3C traceparent en la solicitud. El HTTP transmitible (Streamable HTTP) admite cabezales estándar. El canal de entrada/salida estándar (stdio) no transmite cabezales HTTP de forma nativa; la hoja de ruta de 2026 de la especificación discute agregar un campo _meta.traceparent en llamadas JSON-RPC.

Hasta que eso ocurra: incluya el traceparent en el campo _meta de cada solicitud de forma manual. El servidor registrará el ID de trace.

Métricas

Junto con los spans, las semconv de GenAI definen métricas:

  • gen_ai.client.token.usage — histograma.
  • gen_ai.client.operation.duration — histograma.
  • gen_ai.tool.execution.duration — histograma.

Utilice estas métricas para paneles (dashboards) que no requieran detalles por llamada.

Capa de AgentOps

AgentOps (fundada en 2024) se especializa en observabilidad de GenAI. Envuelve frameworks populares (LangGraph, Pydantic AI, CrewAI) para emitir spans de OTel de forma automática. Es útil si su pila de tecnología (stack) utiliza un framework compatible; de lo contrario, utilice instrumentación manual.

Úsalo

code/main.py emite spans con formato OTel a la salida estándar (stdout) (en un formato similar a OTLP-JSON) para un agente que llama a un LLM, despacha dos herramientas y realiza un viaje de ida y vuelta (round-trip) de MCP. No hay un exportador real: la lección se centra en el formato de span y el conjunto de atributos. Pegue la salida en un visor compatible con OTLP o simplemente léala.

Qué observar:

  • El ID de trace se comparte en todos los spans.
  • Los enlaces padre-hijo se codifican a través de parentSpanId.
  • Los atributos obligatorios gen_ai.* están completos.
  • La captura de contenido está desactivada por defecto; un escenario la activa mediante una variable de entorno.

Envíalo

Esta lección produce outputs/skill-otel-genai-instrumentation.md. Dada una base de código de agente, la skill genera un plan de instrumentación: dónde agregar spans, qué atributos completar y a qué exportadores dirigirse.

Ejercicios

  1. Ejecute code/main.py. Cuente los spans e identifique cuáles son CLIENT frente a INTERNAL.

  2. Active la captura de contenido (variable de entorno) y confirme que aparezcan los eventos gen_ai.content.prompt y gen_ai.content.completion. Tenga en cuenta las implicaciones para la PII.

  3. Agregue la métrica de ejecución de la herramienta gen_ai.tool.execution.duration y emítala como una muestra de histograma por llamada.

  4. Propague un traceparent desde un span de agente padre al campo _meta.traceparent de una solicitud MCP. Verifique que el servidor MCP vería el mismo ID de trace.

  5. Lea la especificación de convenciones semánticas (semconv) de OTel GenAI. Identifique un atributo listado en las semconv que el código de esta lección NO emita. Agréguelo.

Términos clave

Término Lo que dice la gente Lo que realmente significa
OTel "OpenTelemetry" Estándar abierto para traces, métricas y registros (logs)
GenAI semconv "Convenciones semánticas de GenAI" Nombres de atributos estables para spans de LLM, herramienta y agente
gen_ai.* "El espacio de nombres de atributos" Todos los atributos de GenAI comparten este prefijo
Span "Operación temporizada" Una unidad de trabajo con inicio, fin y atributos
Trace "Ancestralidad entre spans" Árbol de spans que comparten un ID de trace
SpanKind "CLIENT / SERVER / INTERNAL" Pistas sobre la dirección del span
OTLP "Protocolo de Línea de OpenTelemetry" Formato de transmisión (wire format) para exportadores
Opt-in content "Captura de prompt / completion" Desactivado por defecto; variable de entorno para habilitar
traceparent "Cabezal W3C" Propaga el contexto del trace a través de los servicios
Exporter "Enviador específico de backend" Componente que envía spans a Jaeger, Datadog, etc.

Lectura adicional

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).