Phase 13 - Lesson 20
OpenTelemetry GenAI — Rastreamento de Chamadas de Ferramentas de Ponta a Ponta
This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.
Um agente chama cinco ferramentas, três servidores MCP e dois subagentes. Você precisa de um único trace em tudo isso. As convenções semânticas do OpenTelemetry GenAI (atributos estáveis na v1.37 e superiores) são o padrão de 2026, suportadas nativamente por Datadog, Langfuse, Arize Phoenix, OpenLLMetry e AgentOps. Esta lição nomeia os atributos necessários, percorre a hierarquia de spans (agente → LLM → ferramenta) e entrega um emissor de span da stdlib que você pode plugar em qualquer exportador OTel.
Tipo: Build Linguagens: Python (stdlib, emissor de span OTel) Pré-requisitos: Fase 13 · 07 (servidor MCP), Fase 13 · 08 (cliente MCP) Tempo: ~75 minutos
Objetivos de Aprendizado
- Nomear os atributos OTel GenAI necessários para um span de LLM e um span de execução de ferramenta.
- Construir uma hierarquia de trace que cubra o loop do agente, a chamada de LLM, a chamada de ferramenta e o despacho do cliente MCP.
- Decidir qual conteúdo capturar (opt-in) vs. redigir (padrão).
- Emitir spans para um coletor local (Jaeger, Langfuse) sem reescrever o código da ferramenta.
O Problema
Um debug de fevereiro de 2026: o usuário relata "meu agente às vezes leva 30 segundos para responder; outras vezes 3 segundos". Nenhum trace. Os logs mostram a chamada de LLM, mas não o despacho da ferramenta, nem a ida e volta ao servidor MCP, nem o subagente. Você tenta adivinhar. Eventualmente, você descobre: um servidor MCP ocasionalmente trava em um cold-start.
Sem rastreamento de ponta a ponta, você não consegue encontrar isso. O OTel GenAI resolve esse problema.
As convenções se consolidaram in 2025-2026 sob o grupo de convenções semânticas do OpenTelemetry (semantic-conventions). Elas definem nomes de atributos estáveis para que Datadog, Langfuse, Phoenix, OpenLLMetry e AgentOps analisem os mesmos spans. Instrumente uma vez; envie para qualquer backend.
O Conceito
Hierarquia 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)
Tudo se aninha sob um único ID de trace. Os IDs de span vinculam as relações pai-filho.
Atributos obrigatórios
De acordo com as convenções 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— string do modelo solicitado (ex:"gpt-4o-2024-08-06").gen_ai.response.model— o modelo realmente servido.gen_ai.usage.input_tokens/gen_ai.usage.output_tokens.gen_ai.response.id— ID de resposta do provedor para correlação.
Para spans de ferramentas:
gen_ai.tool.name— identificador da ferramenta.gen_ai.tool.call.id— o ID de chamada específico.gen_ai.tool.description— descrição da ferramenta (opcional).
Para spans de agentes:
gen_ai.agent.name/gen_ai.agent.id/gen_ai.agent.description.
Tipos de spans (Span kinds)
SpanKind.CLIENTpara chamadas que cruzam uma fronteira de processo (provedor de LLM, servidor MCP).SpanKind.INTERNALpara as etapas do próprio loop do agente e execução de ferramentas.
Captura de conteúdo opcional (Opt-in)
Por padrão, os spans carregam métricas e temporização — não prompts ou conclusões (completions). Grandes volumes de dados (payloads) e PII (informações pessoalmente identificáveis) ficam desativados por padrão. Defina OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental e variáveis de ambiente específicas de captura de conteúdo para incluir o conteúdo. Revise cuidadosamente antes de ativar em produção.
Eventos em spans
Eventos no nível de token podem ser adicionados como eventos de span:
gen_ai.content.prompt— mensagens de entrada.gen_ai.content.completion— mensagens de saída.gen_ai.content.tool_call— chamada de ferramenta conforme registrada.
Os eventos são ordenados cronologicamente dentro de um span para reprodução detalhada.
Exportadores (Exporters)
Os spans do OTel são exportados para:
- Jaeger / Tempo. OSS, on-prem.
- Langfuse. Específico para observabilidade de LLM; visualiza o uso de tokens.
- Arize Phoenix. Avaliações + tracing combinados.
- Datadog. Comercial; analisa nativamente os atributos
gen_ai.*. - Honeycomb. Orientado a colunas; amigável para consultas.
Todos utilizam o OTLP, o formato de transmissão de rede (wire format). Seu código não precisa se preocupar com isso.
Propagação via MCP
Quando um cliente MCP chama um servidor, injete o cabeçalho W3C traceparent na requisição. O HTTP transmitível (Streamable HTTP) suporta cabeçalhos padrão. O canal de entrada/saída padrão (stdio) não carrega cabeçalhos HTTP nativamente; o roadmap de 2026 da especificação discute a adição de um campo _meta.traceparent em chamadas JSON-RPC.
Até que isso seja lançado: inclua manualmente o traceparent no campo _meta de cada requisição. O servidor registra o ID de trace.
Métricas
Junto com os spans, as convenções semânticas do GenAI definem métricas:
gen_ai.client.token.usage— histograma.gen_ai.client.operation.duration— histograma.gen_ai.tool.execution.duration— histograma.
Use-as para painéis (dashboards) que não precisam de detalhes por chamada.
Camada do AgentOps
O AgentOps (fundado em 2024) é especializado em observabilidade de GenAI. Ele envelopa frameworks populares (LangGraph, Pydantic AI, CrewAI) para emitir spans do OTel automaticamente. Útil se sua pilha de tecnologia (stack) usa um framework suportado; caso contrário, use instrumentação manual.
Use-o
O arquivo code/main.py emite spans no formato OTel para a saída padrão (stdout) (em um formato semelhante a OTLP-JSON) para um agente que chama uma LLM, despacha duas ferramentas e faz uma viagem de ida e volta (round-trip) via MCP. Não há um exportador real — a lição se concentra no formato do span e no conjunto de atributos. Cole a saída em um visualizador compatível com OTLP ou apenas leia-a.
O que observar:
- O ID de trace é compartilhado por todos os spans.
- Os links pai-filho são codificados via
parentSpanId. - Os atributos obrigatórios
gen_ai.*são preenchidos. - A captura de conteúdo está desativada por padrão; um cenário a ativa por meio de variável de ambiente.
Envie
Esta lição produz outputs/skill-otel-genai-instrumentation.md. Dada uma base de código de agente, a skill produz um plano de instrumentação: onde adicionar spans, quais atributos preencher e quais exportadores visar.
Exercícios
Execute
code/main.py. Conte os spans e identifique quais são CLIENT vs. INTERNAL.Ative a captura de conteúdo (variável de ambiente) e confirme se os eventos
gen_ai.content.promptegen_ai.content.completionaparecem. Observe as implicações para PII.Adicione a métrica de execução da ferramenta
gen_ai.tool.execution.duratione emita-a como uma amostra de histograma por chamada.Propague um
traceparentde um span pai de agente para o campo_meta.traceparentde uma requisição MCP. Verifique se o servidor MCP veria o mesmo ID de trace.Leia a especificação do OTel GenAI semconv. Identifique um atributo listado no semconv que o código desta lição NÃO emite. Adicione-o.
Termos-chave
| Termo | O que as pessoas dizem | O que isso realmente significa |
|---|---|---|
| OTel | "OpenTelemetry" | Padrão aberto para traces, métricas e logs |
| GenAI semconv | "Convenções semânticas do GenAI" | Nomes de atributos estáveis para spans de LLM / ferramenta / agente |
gen_ai.* |
"O namespace do atributo" | Todos os atributos GenAI compartilham este prefixo |
| Span | "Operação cronometrada" | Uma unidade de trabalho com início, fim e atributos |
| Trace | "Ancestralidade cruzada entre spans" | Árvore de spans que compartilham um ID de trace |
| SpanKind | "CLIENT / SERVER / INTERNAL" | Dicas sobre a direção do span |
| OTLP | "Protocolo de Linha do OpenTelemetry" | Formato de transmissão (wire format) para exportadores |
| Opt-in content | "Captura de prompt / completion" | Desativado por padrão; variável de ambiente para ativar |
| traceparent | "Cabeçalho W3C" | Propaga o contexto de trace entre serviços |
| Exporter | "Enviador específico do backend" | Componente que envia spans para Jaeger / Datadog / etc. |
Leitura Adicional
- OpenTelemetry — GenAI semconv — convenções canônicas para spans, métricas e eventos de GenAI
- OpenTelemetry — GenAI spans — lista de atributos de span de LLM e execução de ferramenta
- OpenTelemetry — GenAI agent spans — span
invoke_agentno nível do agente - open-telemetry/semantic-conventions — GenAI spans — fonte da verdade hospedada no GitHub
- Datadog — LLM OTel semantic convention — passo a passo de integração em produção