Cómo depurar pipelines de IA con tracing asincrónico y OpenTelemetry en producción | Gustavo Sied
Depuração de pipelines de IA com tracing assíncrono e OpenTelemetry em produção
Imagine uma terça-feira comum. Sua caixa de entrada está prestes a explodir com mensagens de stakeholders questionando uma mudança repentina nas previsões de comportamento dos usuários — previsões feitas pelo seu sistema de IA. Aquele sistema cuidadosamente construído ao longo de meses de trabalho e testes agora responde com confiança absoluta, mas com conteúdo completamente equivocado. Não há nenhum traceback dramático. Nenhum erro de servidor. O pipeline continua de pé, servindo respostas plausíveis — e perigosamente incorretas.
Um RAG que "confia" cegamente no contexto recuperado pode recomendar investimentos baseados em dados inventados, enquanto seus dashboards apontam tudo em verde. É exatamente nesse cenário que o debugging tradicional falha. É aqui que entra o tracing assíncrono com OpenTelemetry: a única maneira de enxergar dentro do pipeline de IA em produção sem derrubá-lo.
Neste artigo, vou apresentar um guia de campo completo para depurar agentes e pipelines de IA em produção usando tracing assíncrono e OpenTelemetry. Você vai entender por que os métodos convencionais não funcionam, como implementar uma estratégia de observabilidade de ponta a ponta e quais são as armadilhas mais comuns — com exemplos práticos que você pode aplicar hoje.
Por que o debugging tradicional não funciona para IA?
Em sistemas convencionais, um erro é um evento discreto: uma exceção, um HTTP 500, um timeout. Você tem um stack trace, uma linha de código, uma causa raiz. Em pipelines de IA, o erro é semântico. O sistema não falha — ele degenera silenciosamente.
Os principais motivos são:
- Não determinismo: o mesmo prompt pode gerar respostas diferentes a cada execução, mesmo com temperatura zero.
- Múltiplas camadas de abstração: um agente pode chamar ferramentas, consultar bancos vetoriais, reescrever prompts e orquestrar sub-agentes. O erro pode estar em qualquer uma dessas etapas.
- Respostas plausíveis: modelos de linguagem não indicam confiança real. Uma resposta errada não vem acompanhada de um aviso — ela vem formatada com a mesma autoridade de uma resposta correta.
- Contexto externo mutável: a base de dados vetorial pode ser atualizada, uma API terceira pode mudar o formato de resposta, ou o comportamento do usuário pode mudar sem aviso. O pipeline não "quebra"; ele simplesmente passa a produzir lixo.
Quando o CEO pergunta "por que as previsões mudaram?", você precisa de algo que não é um log de erros tradicional. Você precisa de uma narrativa completa do que aconteceu — desde a entrada do usuário até a saída final. É exatamente isso que o tracing assíncrono proporciona.
O que é tracing assíncrono (e por que ele é essencial aqui)
Tracing é a técnica de capturar o ciclo de vida de uma requisição à medida que ela atravessa diferentes componentes de um sistema distribuído. O termo assíncrono refere-se à capacidade de rastrear operações que não seguem um fluxo linear de execução — como chamadas a APIs externas, consultas a bancos vetoriais ou invocações de modelos com espera de streaming.
Em um pipeline de IA moderno, o fluxo é tudo, menos linear. Um agente pode:
- Receber a pergunta do usuário
- Planejar uma sequência de ações
- Fazer uma chamada assíncrona a uma ferramenta de busca
- Processar o resultado e decidir se gera uma resposta final ou se chama outra ferramenta
Cada etapa é uma unidade de trabalho com seu próprio contexto. O tracing assíncrono cria uma tree structure (árvore de spans) que representa essa execução — mas com a capacidade de "pular" entre processos, filas e threads. Isso é possível graças à propagação de contexto: cada span carrega consigo um trace_id e um parent_span_id, conectando operações que aconteceram em momentos diferentes e em ambientes diferentes.
Sem isso, você veria pedaços isolados de logs sem nenhuma correlação. Com tracing, você reconstrói exatamente o caminho percorrido pela requisição — incluindo o que foi consultado, qual prompt foi montado e qual resposta o modelo retornou.
OpenTelemetry: o padrão aberto para observabilidade
OpenTelemetry (OTel) é o framework de observabilidade mais adotado na indústria hoje. Ele fornece APIs, SDKs e instrumentações prontas para coletar traces, métricas e logs de qualquer aplicação — e é totalmente compatível com pipelines de IA.
Por que usar OpenTelemetry especificamente?
- Padrão neutro: você não fica preso a um vendor. Pode exportar para Jaeger, Grafana, Datadog, New Relic ou seu próprio backend.
- Instrumentação automática: bibliotecas como
openai,langchain,pgvectorefastapijá possuem instrumentações OTel oficiais ou de comunidade. Você adiciona observabilidade sem reescrever o código. - Contexto propagado: a propagação de contexto W3C permite que o
trace_idatravesse serviços, filas e funções serverless — essencial para operações assíncronas. - Suporte a métricas e logs: além de traces, você pode correlacionar métricas de latência e logs estruturados com o mesmo identificador de rastreamento.
Como funciona na prática
O fluxo de instrumentação é simples:
// 1. Configurar o SDK do OpenTelemetry
const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter(),
serviceName: 'ai-pipeline',
});
// 2. Criar um span para a operação principal
const tracer = trace.getTracer('rag-pipeline');
const parentSpan = tracer.startSpan('rag.query');
// 3. Propagar contexto em chamadas assíncronas
const childSpan = tracer.startSpan('embedding.generate', {
childOf: parentSpan
});
// ... fazer a chamada ao modelo de embedding ...
// 4. Registrar atributos semânticos
childSpan.setAttributes({
'model.name': 'text-embedding-3',
'model.dimension': 1536,
'operation.type': 'vector_search'
});
childSpan.end();
parentSpan.end();
O ponto crítico é o passo 3. Em operações assíncronas, o contexto precisa ser propagado explicitamente. Bibliotecas modernas de LLM já fazem isso internamente quando instrumentadas, mas você pode propagar manualmente usando context.with() ou invertendo o contexto (tracer.startSpan(..., { childOf: context.active() })).
Estruturando o tracing para um pipeline de IA: um guia passo a passo
Vamos aplicar isso a um caso real: um pipeline RAG que usa um agente para responder perguntas. O desafio é isolar qual camada falhou — prompt, ferramenta, modelo ou orquestração. O TL;DR é: "registre cada passo com um ID de rastreamento, reproduza as entradas exatas e bisecione". Cerca de 70% dos 'bugs de IA' acabam sendo bugs de contexto, parsing ou ferramenta — não do modelo em si.
Aqui está a estrutura de spans recomendada:
agent.run— o span raiz; representa a requisição completa do usuário.prompt.build— captura o prompt final enviado ao modelo, incluindo variáveis como o contexto recuperado.tools.execute— para cada ferramenta chamada (buscadores, APIs externas), com seus inputs e outputs.vectorstore.search— consulta à base vetorial, com parâmetros de busca (top-k, threshold).model.generate— a chamada ao LLM, com modelo, temperatura e tokens usados.agent.decide— se o agente decidir chamar outra ferramenta, esse span registra a lógica de decisão (qual caminho foi tomado e por quê).
O truque é registrar todos os atributos relevantes como metadados dos spans:
- Prompt original do usuário (truncado a 10k caracteres para não sobrecarregar o backend de tracing)
- Contexto recuperado (com fonte e score de similaridade)
- Resposta bruta do modelo (sem formatação)
- Timestamps individuais de cada etapa
- Versões do código e do modelo (ex:
model.version: "2026-03-15")
O poder da bisecção com tracing
Com essa árvore de spans, depurar um comportamento errado se torna um processo de bisecção:
Passo 1 — Identifique o span de maior duração ou o primeiro span com saída inesperada. No backend de tracing (como Grafana Tempo ou Jaeger), procure pelo trace_id da requisição problemática. Estabeleça um período de tempo — ex: "usuário relatou erro às 14h32" — e filtre os traces por intervalo e serviço.
Passo 2 — Compare o que entrou e o que saiu em cada etapa. Se a resposta final está errada, verifique o model.generate. Se o prompt estava correto e o modelo recebeu um contexto inadequado, o problema está no vectorstore.search ou na prompt.build. Se o contexto recuperado está correto, mas a resposta ignora o contexto, pode ser um problema de instrução do prompt (ou de temperatura alta demais).
Passo 3 — Reproduza o cenário exato. Com os atributos registrados (prompt exato, contexto exato, modelo exato), você pode reproduzir a execução offline. Se o problema desaparecer na reprodução, o culpado é provavelmente não-determinismo ou mudança de dados externos. Se persistir, você tem um bug determinístico.
É assim que ~70% dos "bugs de IA" são desmascarados: não é o modelo "alucinando", é um parsing de ferramenta que quebrou silenciosamente, ou uma data no formato errado que foi injetada no contexto.
Depurando um agente de IA em produção: estudo de caso
Vamos colocar isso em um cenário real. Um agente de IA de suporte ao cliente passa a recomendar reembolsos que não deveria. O código não foi alterado. O que mudou? Seus dashboards estão todos verdes, mas o comportamento está estranho.
Com tracing via OpenTelemetry, você descobre o seguinte trace:
- O span
tools.executechamou a API interna de política de reembolso, mas retornoustatus_code: 200com um payload vazio (a API mudou silenciosamente o contrato). - O span
prompt.buildmontou o prompt com contexto vazio, e o modelo, treinado para sempre dar uma resposta útil, pregou a regra padrão de "reembolso aceito".
Sem o tracing, você culparia o "modelo instável" ou "drift de dados". Com o rastreio, você vê a verdade: a falha está na API externa e na falta de validação de resposta vazia. O típico "bug de IA" era, na verdade, um bug de integração clássico.
A correção: adicionar validação no span de ferramenta — se a resposta for vazia, registrar um atributo tool.response.empty=true e lançar um erro estruturado. Agora, o pipeline se comporta de forma previsível (retorna "não foi possível processar agora" em vez de inventar uma política).
Boas práticas e armadilhas comuns
Implementar tracing assíncrono é fácil. Fazer isso bem é outra história. Com base em experiências em produção, aqui estão as lições mais importantes:
Boas práticas
- Instrumente logo no início do desenvolvimento. Adicionar tracing depois que o pipeline já está em produção é doloroso — você precisará correlacionar dados históricos sem identificadores únicos.
- Use nomes de spans semânticos e estruturados.
agent.run,prompt.build,tools.execute. Evite nomes genéricos comooperationouprocess. - Registre o input e output de cada etapa, exceto dados sensíveis. Em pipelines de IA, o principal valor do tracing é a reprodução. Sem inputs exatos, você não reproduz.
- Estabeleça amostragem inteligente. Em produção, você não precisa de 100% dos traces. Amostre 100% de erros e 10% de requisições bem-sucedidas. OpenTelemetry suporta isso nativamente.
- Crie correlação com métricas e logs. Use o mesmo
trace_idem logs estruturados. Quando uma alteração de performance acontecer, você parte da métrica para o trace e depois para o log.
Armadilhas que vão morder você
- Overhead de instrumentação em loops de agente: quando um agente entra em loop (chamando ferramentas repetidamente), a árvore de spans cresce descontroladamente. Defina um limite de profundidade e propagação de contexto, e encerre o trace após 100 spans.
- Dados sensíveis nos atributos: prompts podem conter PII. Você precisa de um mecanismo de redação automática — por exemplo, usando regex para mascarar e-mails, CPFs e tokens antes de setar os atributos. Alternativamente, configure a coleta de dados em nível de amostragem e use um backend com criptografia em repouso.
- Propagação incorreta de contexto em filas assíncronas: aquela operação que envia uma mensagem para o RabbitMQ ou SQS — se você não propaga o contexto na mensagem, o trace "quebra" no meio. A biblioteca de mensageria precisa ser instrumentada também.
- Falso senso de segurança: traces mostram o que aconteceu, mas não mostram o que deveria acontecer. Sem testes de avaliação (LLM-as-judge ou testes de golden set), você terá muita observabilidade e pouca capacidade de julgar se uma saída é "errada". Use o tracing para investigar o porquê, mas mantenha uma camada de avaliação contínua para detectar o quando.
Ferramentas e integrações que facilitam sua vida
O ecossistema OpenTelemetry para IA está amadurecendo rápido. Você encontrará suporte para:
- LangChain e LlamaIndex: instrumentações automáticas que criam spans para cada etapa do pipeline — desde o embedding até o parser de saída.
- Bancos vetoriais: instrumentações para gráficos semânticos. Você pode ver a query SQL/API enviada e o número de resultados encontrados.
- APIs de modelos: ainda não há instrumentação automática oficial para APIs como OpenAI ou Anthropic, mas a comunidade criou extensões. Se você usa um proxy de LLM (como LiteLLM), normalmente ele já exporta no formato OTel.
- Backends de tracing: o Grafana Tempo é gratuito e roda no seu cluster. Para soluções SaaS, há Honeycomb, Lightstep, DataDog APM, New Relic e o novo serviço de observabilidade da AWS.
O importante é começar de forma simples: um coletor OTel local exportando para um backend de testes. Você não precisa de infraestrutura complexa no primeiro dia.
Conclusão
Depurar pipelines de IA em produção é um desafio de primeira grandeza, mas não é impossível. A resposta está em trocar o paradigma: aceitar que o pipeline vai falhar de forma silenciosa, e construir a infraestrutura para iluminar cada etapa da execução.
O tracing assíncrono com OpenTelemetry oferece exatamente isso: uma visão completa, correlacionada e reproduzível do que seu agente fez, em que ordem, com quais dados e com qual resultado. Ele permite que você responda rapidamente àquela pergunta terrível — "por que a IA mudou de comportamento?" — com um trace, em vez de um chute.
Se você está construindo um RAG, um agente autônomo ou um sistema de recomendações em produção, a minha recomendação é concreta: instrumente agora. Não espere o alerta do CEO. Comece criando spans para cada etapa, registre inputs e outputs, e configure a amostragem inteligente. O investimento é pequeno — algumas horas de trabalho — e o retorno é a diferença entre operar um sistema de IA no escuro e operá-lo com faróis acesos.
Boas investigações — e que seus traces sejam sempre verdes.