Agent Mentor Learn
Observabilidade e depuração: enxergando cada passo do seu agente · Lição 3 de 6

Lição 3: Logs estruturados e métricas: transformando cada etapa em dado

Objetivos de aprendizado:

  • Explicar as quatro perguntas que a observabilidade em produção precisa responder, e reconhecer que são os mesmos números das métricas de avaliação, apenas usados de outro jeito
  • Projetar logs estruturados para o seu harness: um registro por requisição ao modelo, um por chamada de ferramenta, com campos cobrindo duração, tokens, nome da ferramenta e erros
  • Mapear padrões de métricas para correções específicas usando leituras diagnósticas, e perceber quando sinais como “zero erros” estão distorcidos pela forma como são registrados

Pré-requisitos: lições 1 e 2 concluídas, e um loop de harness funcionando (curso 7 desta série) | Anterior: << Lição 2 | Próxima: Lição 4 >>

Uma execução você lê, duzentas você não

No fim da lição 2 você fez algo que vale a pena: leu uma transcrição bruta do começo ao fim e pegou três problemas que o agente nunca mencionou. O método funciona, e a evidência é sólida. O problema é que aquilo era uma execução.

Agora coloque o mesmo agente em produção: duzentas execuções por dia, cada uma com uma dúzia de iterações do loop, somando duas ou três mil idas e voltas de chamada de ferramenta. Segunda de manhã alguém diz “o lote de sexta à tarde pareceu especialmente lento”, e como você responde? Ler duzentas transcrições obviamente não é realista. E mesmo que lesse, você ainda não conseguiria responder onde estava lento — esse julgamento exige olhar a distribuição entre execuções, não ler uma amostra. Olhos humanos respondem “por que ele fez isso nesta execução específica”, mas não “como este lote diferiu do lote anterior”.

Então o trabalho desta lição cabe em uma frase: transformar perguntas que exigem ler transcrições em perguntas que uma única consulta responde. A primeira é “por que ele buscou a mesma palavra repetidamente desta vez”; a segunda é “qual ferramenta foi mais chamada nos últimos sete dias, e os erros estão todos no mesmo parâmetro”. A regra da lição 2 continua de pé — transcrições brutas são evidência de primeira mão, o autorrelato do agente não vale. Esta lição só guarda a mesma evidência em outro formato, para que ela possa ser lida por pessoas E também filtrada, agregada e analisada por distribuição.

Quatro perguntas que ambientes de produção precisam responder

A documentação oficial lista quatro coisas que você precisa enxergar com clareza na observabilidade em produção: quais ferramentas foram chamadas, quanto tempo cada requisição ao modelo levou, quantos tokens foram gastos e onde as falhas ocorreram1. Ao tomar decisões de design, você vai voltar a essas quatro perguntas repetidamente: este campo ajuda a responder uma delas? Se não, é ruído.

Isso pode parecer familiar. O curso 10 desta série usou o mesmo conjunto de números ao falar de avaliação: além da acurácia do estado final, ele recomendava coletar o tempo de execução de chamadas de ferramenta individuais e de tarefas inteiras, a contagem total de chamadas de ferramenta, o consumo total de tokens e os erros de ferramenta2. Mesmas métricas, duas aparições, usos diferentes:

Este númeroCurso 10: na trilha de avaliaçãoEsta lição: no monitoramento diário
Tempo de execução de chamadas de ferramenta e de tarefas inteirasA mudança deixou a tarefa mais lentaQual janela de tempo ficou lenta hoje, e é o modelo ou são as ferramentas
Contagem total de chamadas de ferramentaQual versão do prompt dá menos voltasDetectar novos padrões de chamada repetitiva que apareceram em produção
Consumo total de tokensCalcular o custo de rodar a avaliação inteiraAcompanhar o gasto diário, achar as sessões que comem tokens
Erros de ferramentaA mudança introduziu novas falhasVer qual ferramenta está instável, e em qual parâmetro ela está falhando

A diferença não está nos números — está em contra o que você os compara. Na avaliação, você compara “antes da mudança contra depois da mudança” sobre um conjunto de teste fixo, então os números precisam ser reproduzíveis. No monitoramento, você compara “hoje contra os últimos sete dias” ou “esta sessão contra outras sessões”, então a referência é o histórico das próprias execuções, o que significa que os números precisam ser contínuos, marcados no tempo e fatiáveis por dimensão. Esta lição cobre o segundo caso.

Logs estruturados: um registro por etapa

Esta seção descreve uma prática de engenharia. Não há orientação autoritativa sobre como nomear campos de log ou em qual formato gravar em disco — o que segue é um ponto de partida padrão que funciona, não uma especificação oficial. Os nomes de campo tomam emprestado termos que de fato aparecem em materiais oficiais (session id, prompt id, tool name, tool_input, tool_response, duration_ms, contagens de token, error), de modo que, quando você depois integrar com telemetria oficial, não precisará remapear o vocabulário.

Unidade de registro: um para requisição ao modelo, um para chamada de ferramenta

O loop do agente tem naturalmente dois tipos de “etapa”: uma requisição ao modelo e uma execução de ferramenta. Elas têm atributos bem diferentes — requisições ao modelo têm contagens de token mas não têm nome de ferramenta; execuções de ferramenta são o inverso — mas compartilham o mesmo lote de campos de contexto (qual sessão, qual prompt, quanto tempo).

Então: grave um registro por requisição ao modelo, um por chamada de ferramenta e use um campo type para distingui-los. Não comprima uma iteração inteira do loop em um registro só — assim você nunca consegue calcular a divisão entre tempo de modelo e tempo de ferramenta. Também não grave apenas um registro-resumo quando a tarefa terminar — se a tarefa travar no meio, você nem vai saber em qual etapa ela travou.

Formato: JSON Lines, um objeto por linha

JSON Lines (comumente escrito JSONL) é exatamente o que o nome diz: um arquivo, cada linha é um objeto JSON completo, sem vírgulas entre linhas e sem array externo envolvendo tudo.

As razões para escolhê-lo são todas prosaicas, mas todas válidas: escritas em modo append funcionam sem precisar voltar e acrescentar um ] no fim do arquivo, então, mesmo que o processo seja morto, você não fica com um arquivo sintaticamente quebrado (a última linha pode estar pela metade, mas todas as anteriores continuam parseáveis — essa é também a origem no mundo real do requisito do exercício de que “linhas ruins são reportadas mas não interrompem o processamento”). Quando o arquivo cresce para centenas de megabytes, você consegue processá-lo em streaming, linha a linha. Cada linha é autocontida, então grep consegue filtrar, jq consegue processar e olhos humanos conseguem ler.

Compare isso com os logs em prosa que muitos harnesses já têm — [09:12:05] search_docs retornou 3 resultados, levou 412ms. Lê-se bem, mas só pode ser lido por humanos. Para responder “qual a duração média de search_docs nos últimos sete dias”, você precisaria escrever regex para extrair aquele 412ms; se alguém trocar “levou” por “decorrido”, a regex silenciosamente começa a retornar zero. Logs em prosa codificam a estrutura dentro da linguagem natural, e linguagem natural é para humanos decodificarem. Logs estruturados invertem isso: a estrutura fica nos campos, e máquinas leem sem ambiguidade. Podem ser filtrados, agregados e analisados por distribuição — essas três habilidades são o que você de fato precisa ao passar de uma execução para duzentas.

Vocabulário de campos

Contexto que vai em todo registro: ts (timestamp ISO 8601 com milissegundos e fuso), type (model_call ou tool_call), session_id (identificador de uma sessão, constante ao longo de vários turnos), prompt_id (identificador de um prompt do usuário; todas as requisições ao modelo e chamadas de ferramenta que ele dispara compartilham este valor), duration_ms. Requisições ao modelo acrescentam model, stop_reason, input_tokens / output_tokens. Chamadas de ferramenta acrescentam tool, tool_use_id (para parear com as respostas), error (presente apenas quando falha).

prompt_id é o campo menos vistoso aqui, mas o que se torna mais útil depois. Agora você só o está gravando em cada registro; a lição 4 vai usá-lo para circular registros espalhados em “eventos do mesmo prompt” e depois costurá-los numa árvore via relações pai-filho. Quanto ao input e ao valor de retorno da própria ferramenta (tool_input / tool_response) — não grave o texto completo por padrão; registre apenas o tamanho ou a contagem de bytes. A justificativa vem na penúltima seção.

Integrando ao harness

O trecho abaixo se apoia no loop guiado por stop_reason do curso 7 desta série. Primeiro, o logger:

logRecord() faz uma coisa só: juntar o contexto comum com os campos de quem chamou em uma linha de JSON e anexá-la ao arquivo. Ele não julga, não formata, não faz nada “esperto” — quanto mais burro o logger, melhor, porque quando ele quebra você fica sem logs para consultar. Agora os dois pontos de instrumentação do loop:

Dois detalhes que valem ser destacados.

Onde você inicia e para o cronômetro determina o que esse número significa. O t1 começa antes de runTool e para depois que ele retorna, então duration_ms inclui as retentativas da própria ferramenta, as esperas de backoff e as idas e voltas de rede, mas não a validação de parâmetros anterior à chamada. Você define essa fronteira; uma vez definida, escreva-a em algum lugar — daqui a seis meses, encarando um duration_ms de 30 segundos, você vai precisar saber se ele inclui retentativas.

Erros vão tanto para o log quanto para o contexto do modelo. O bloco catch enfia a mensagem de erro de volta no tool_result, então o agente a vê no turno seguinte. A orientação oficial encaixa perfeitamente aqui: quando uma chamada de ferramenta levanta um erro, a resposta deveria passar por engenharia de prompt para comunicar com clareza melhorias específicas e acionáveis, não um código de erro opaco ou um traceback2. Você pode escrever ETIMEDOUT no log, mas o que volta para o modelo deveria ser “A requisição deu timeout (30 segundos). Este endpoint tende a dar timeout em consultas de intervalo amplo; tente estreitar date_range para 7 dias ou menos.”

Lendo métricas de forma diagnóstica

O valor de uma métrica não está em “hoje fizemos 1,283 chamadas de ferramenta” como número — está em certos padrões apontarem para certas correções. As correlações oficiais são todas pistas que vale a pena verificar primeiro:

Muitas chamadas redundantes → parâmetros de paginação ou de limite de tokens talvez precisem de ajuste. Muitas chamadas redundantes de ferramenta podem sugerir que vale redimensionar os parâmetros de paginação ou de limite de tokens2. O modelo precisa achar uma passagem na documentação, seu search_docs retorna apenas 5 resultados por página, então ele tem que folhear 28 páginas. Cada uma dessas 28 chamadas é legítima, cada uma tem sucesso, as métricas não mostram nenhum “erro”, mas todas são desperdício. Suba os resultados por página para 25 e esse padrão desaparece.

Muitos erros de parâmetro inválido → a descrição da ferramenta provavelmente precisa de clareza ou exemplos. Muitos erros de ferramenta por parâmetros inválidos podem sugerir que as ferramentas se beneficiariam de descrições mais claras ou exemplos melhores2. Esta é poderosa quando os erros se agrupam no mesmo parâmetro: sete erros todos dizendo invalid parameter: date_range significam que você deveria primeiro verificar se sua descrição explica em que formato esse parâmetro é esperado. A direção da investigação é a descrição da ferramenta, não o modelo.

Acompanhar chamadas de ferramenta revela outras coisas. Acompanhar chamadas de ferramenta ajuda a revelar fluxos de trabalho comuns que os agentes perseguem e oferece oportunidades de consolidar ferramentas2. Por exemplo, se 90% das chamadas de read_file são seguidas de parse_config, talvez você devesse oferecer um read_config de um passo só. Esse tipo de descoberta nunca emerge de uma única execução — só de agregados. Outro conjunto de leituras úteis: analise suas métricas de chamada de ferramenta para identificar as ferramentas mais usadas, as taxas de sucesso das ferramentas, os tempos médios de execução e os padrões de erro por tipo de ferramenta3.

Alguns problemas são inerentemente problemas de magnitude — você não consegue dizer “onde está o muito” sem olhar agregados. A Anthropic documentou problemas iniciais desse tipo: vasculhar a web sem fim atrás de fontes inexistentes4 — olhar qualquer busca isolada não vai sinalizar erro nenhum; você precisa enfileirar dezenas de chamadas para ver que “ele está girando no lugar”.

Uma experiência geral (sem fonte autoritativa): a duração média quase sempre mente. 99 chamadas de 80ms mais 1 chamada de 30 segundos dão média de 379ms, o que parece um pouco lento mas aceitável; a realidade são 99 chamadas rápidas mais uma completamente travada. Ao ler duração, olhe no mínimo a mediana e os percentis altos, ou vá direto aos poucos registros mais lentos.

A armadilha ao ler números: o que o seu sinal está de fato contando

O jeito mais fácil de uma métrica mentir não é contando errado — é quando o que ela conta não é o que você acha que ela conta.

Olhe um design real de produto. O Claude Code faz retentativas internas de requisições de API que falham e emite um único evento api_error só depois de desistir — esse evento é o sinal terminal daquela requisição; tentativas intermediárias de retentativa não são registradas como eventos separados3. Esse design faz sentido: se cada retentativa registrasse um erro, o gráfico de erros seria inundado por tropeços transitórios que a recuperação automática resolveu, obscurecendo quantas requisições de fato falharam. O custo é que você tem que lembrar dessa semântica — “3 eventos api_error hoje” significa “3 requisições falharam em definitivo”, não “3 tropeços de rede”, e não diz nada sobre quantas retentativas bem-sucedidas estão escondidas embaixo.

A mesma página de documentação oferece uma leitura bem prática: para distinguir se uma sessão se recuperou de um erro ou travou por completo, agrupe os eventos por session id e verifique se existe um evento de requisição de API posterior ao erro3. Se há continuação, ela seguiu; se não há, parou ali. Esse julgamento custa um agrupamento mais uma verificação de “varrer se há registros depois do erro”, com custo-benefício altíssimo — o exercício do nível 2 faz você escrever exatamente isso. (JSONL escrito em append é naturalmente ordenado no tempo, então você não precisa ordenar explicitamente dentro de um único arquivo; quando os logs vêm de vários processos, ordene por ts antes.)

Dessa armadilha você extrai uma prática geral: escreva uma frase para cada métrica dizendo “ela conta o quê”. Escreva em comentários de código ou na documentação dos campos. “Contagem de erros de ferramenta = uma contagem depois que todas as retentativas falham” e “= uma contagem por exceção lançada” são duas métricas completamente diferentes, mas o nome pode ser idêntico, e quem for ler o painel daqui a seis meses não consegue diferenciar só pelo número.

Custo e tokens: o número que mais vale acompanhar

Se você só pudesse acompanhar um número, acompanhe tokens.

Primeiro, a magnitude. Nos dados da Anthropic, agentes normalmente usam cerca de 4× mais tokens do que interações de chat, e sistemas multiagentes usam cerca de 15× mais tokens do que chats4. Essa é a observação deles sobre os próprios sistemas, não uma constante universal, mas ela ajusta uma expectativa: quando você converte um recurso de chat em um agente, a conta não sobe “um pouquinho”. Eles têm outra observação estatística: o uso de tokens sozinho explica 80% da variância, com o número de chamadas de ferramenta e a escolha do modelo como os outros dois fatores explicativos4 — isso vem do parágrafo em que analisam o desempenho da avaliação, ou seja, “quais quantidades melhor explicam as diferenças entre execuções”, e tokens ficam em primeiro. Leia os dois juntos: tokens são ao mesmo tempo a maior parte da conta e o principal fator explicativo da variância entre execuções, então, entre as métricas candidatas, é a que mais vale acompanhar primeiro.

Duas notas práticas. Números de custo são aproximações: a documentação oficial diz que métricas de custo são aproximações; para dados oficiais de faturamento, consulte seu provedor de API3. Então o uso delas é “detectar anomalias, comparar tendências”, não “conciliar com o financeiro”. Atribuição exige fatiar por dimensão: métricas de uso podem ser usadas para acompanhar tendências entre times ou indivíduos, identificar sessões de alto consumo e também atribuir gasto a coisas específicas, como nome da Skill, nome do plugin ou tipo de subagente3. A implicação para harnesses próprios é direta — escreva essas dimensões nos registros de log desde o começo, não tente fazer a junção depois; juntar dimensões após o fato é basicamente refazer a execução. Além disso, copie as contagens de token diretamente do campo usage da resposta do modelo; não estime usando contagem de caracteres dividida por 4 ou métodos parecidos — esses erram bastante em cenários multilíngues, com muito código ou com imagens.

Contenção: não invente limiares, não registre conteúdo completo

Depois de ter métricas, o impulso natural seguinte é configurar alertas: taxa de erro passa de 5%, alerta; duração no percentil alto passa de 10 segundos, alerta.

Pare. Esta lição não dá nenhum número de limiar, porque não há nenhum nos materiais autoritativos. A documentação oficial menciona que alertar é algo que alguém deveria fazer, mas nunca deu valores específicos — orçamentos de erro, metas de SLO, limiares de alerta, nenhum número. Se eu escrevesse aqui “recomendo 5%”, isso seria invenção minha, e você usaria. Limiares só podem crescer a partir da sua própria linha de base: registre duas semanas de dados primeiro, veja a faixa de flutuação normal, e então defina o que conta como anormal. Inverta a ordem e você acaba com uma regra que dá falso alarme três vezes por dia e é silenciada por todo mundo depois de duas semanas.

A divisão de responsabilidade também vale copiar dos produtos oficiais: o Claude Code emite apenas o fluxo bruto de eventos; detecção de anomalias, definição de linha de base, correlação entre sessões e alertas são responsabilidade do seu SIEM ou backend de observabilidade3. Para harnesses próprios isso significa: o sistema observado não faz julgamentos por conta própria. Não escreva “depois de 3 erros de ferramenta consecutivos, enviar e-mail” dentro do harness — essa lógica é publicada junto com o agente, reiniciada junto com o agente e quebra junto com o agente, e ela não tem dado histórico contra o que comparar.

Uma última coisa, também a mais fácil de virar incidente três meses depois do lançamento: não registre conteúdo por padrão. O Claude Code não coleta o conteúdo dos prompts do usuário por padrão — apenas o comprimento do prompt; para incluir conteúdo você precisa definir explicitamente uma variável de ambiente3. A telemetria do Agent SDK é igualmente estrutural por padrão — cada span registra duração, nome do modelo, nome da ferramenta; contagens de token são registradas quando a API retorna dados de uso, mas o conteúdo que seu agente lê e escreve não é registrado por padrão1.

Esses dois padrões refletem o mesmo julgamento: informação estrutural (quem, quando, quanto tempo, qual ferramenta, quantos tokens) basta para responder à imensa maioria das perguntas de operação; conteúdo não. Uma vez que o conteúdo entra nos logs, ele segue os logs para os backups, para o armazenamento de longo prazo, para a vista de qualquer pessoa com permissão de leitura. Então seu harness deveria registrar por padrão input_bytes: 137 em vez de tool_input: {...}; quando você realmente precisar investigar os parâmetros exatos de uma chamada específica, ligue o registro completo para aquele caso pontual. Isso não conflita com o “transcrições brutas são evidência de primeira mão” da lição 2: ao depurar você absolutamente deve ver a ida e volta completa, em um ambiente que você controla, para uma execução específica, e você termina assim que lê. Logs de produção têm por padrão retenção de longo prazo e visibilidade para várias pessoas — isso é outra coisa.

Limites: onde esta lição para

A esta altura você tem uma pilha de registros estruturados e um conjunto de métricas legíveis. Três coisas que esta lição não faz: costurar relações pai-filho entre registros (quais requisições ao modelo um prompt disparou, qual chamada de ferramenta aninha sob qual subagente) exige identificadores de correlação para montar uma árvore — isso é a lição 4. Pendurar sondas nos pontos de verificação do ciclo de vida sem modificar o código do harness são os hooks da lição 5. Montar essa camada inteira sobre o seu harness do curso 7 e percorrer um exercício completo de depuração é a lição 6.

💻 Exercícios

Recapitulação

  • A observabilidade em produção precisa responder quatro perguntas: quais ferramentas foram chamadas, quanto tempo cada requisição ao modelo levou, quantos tokens foram gastos e onde as falhas ocorreram1. Essas quatro e as métricas de avaliação do curso 10 desta série (tempo de execução de chamadas de ferramenta individuais e de tarefas inteiras, contagem total de chamadas de ferramenta, consumo total de tokens, erros de ferramenta)2 são o mesmo conjunto de números — na avaliação você os usa para julgar se uma mudança melhorou as coisas; no monitoramento você os usa para acompanhar a saúde das execuções.
  • O design dos campos de log e a escolha do JSONL não têm especificação autoritativa — é decisão de engenharia sua. Ponto de partida padrão: um registro por requisição ao modelo, um por chamada de ferramenta, um objeto JSON por linha, com session id, prompt id, duração, contagens de token, nome da ferramenta e erros. Logs em prosa só podem ser lidos por humanos; os estruturados podem ser filtrados, agregados e analisados por distribuição.
  • O valor das métricas está em padrões que mapeiam diretamente para correções: muitas chamadas redundantes significam que parâmetros de paginação ou de limite de tokens precisam de ajuste; muitos erros de parâmetro inválido significam que descrições de ferramenta precisam de clareza ou exemplos2. Acompanhar chamadas de ferramenta também revela fluxos de trabalho comuns dos agentes e oportunidades de consolidar ferramentas2. Quando uma chamada de ferramenta levanta um erro, a própria resposta deveria ser escrita como orientação específica e acionável, não um código de erro opaco2.
  • A semântica de um sinal é definida pela forma como ele é registrado. O Claude Code faz retentativas internas de requisições de API que falham e emite um único evento api_error só depois de desistir — é o sinal terminal daquela requisição; retentativas intermediárias não são registradas separadamente3 — então uma “contagem de erros” pode esconder muitas retentativas invisíveis embaixo. Para distinguir se uma sessão se recuperou ou travou, agrupe os eventos por session id e verifique se existe um evento de requisição posterior ao erro3.
  • Tokens são a métrica isolada que mais vale acompanhar: nos dados da Anthropic, agentes usam cerca de 4× os tokens do chat, sistemas multiagentes cerca de 15×4. Ao analisar o desempenho da avaliação, eles descobriram que o uso de tokens sozinho explica 80% da variância, com a contagem de chamadas de ferramenta e a escolha do modelo como os outros dois fatores explicativos4. Métricas de custo são aproximações; o faturamento oficial vem do seu provedor de API3. O gasto pode ser atribuído a coisas específicas, como nome da Skill, nome do plugin ou tipo de subagente3.
  • Dois princípios de contenção: o sistema observado só emite o fluxo bruto de eventos; detecção de anomalias, definição de linha de base e alertas são responsabilidade do backend3. Logs não deveriam registrar conteúdo por padrão — produtos oficiais têm como padrão não coletar o conteúdo dos prompts, apenas o comprimento3; a telemetria tem como padrão registrar apenas informação estrutural, não o que o agente lê e escreve1. Limiares de alerta e SLOs não têm números nos materiais autoritativos — não os invente; registre primeiro uma linha de base de duas semanas.

>> Lição 4: Tracing: costurando uma execução em uma árvore

Footnotes

  1. Observability with OpenTelemetry — Claude Agent SDK Official Documentation — https://code.claude.com/docs/en/agent-sdk/observability 2 3 4

  2. Writing effective tools for agents — with agents — Anthropic Engineering — https://www.anthropic.com/engineering/writing-tools-for-agents 2 3 4 5 6 7 8 9

  3. Monitoring — Claude Code Official Documentation — https://code.claude.com/docs/en/monitoring-usage 2 3 4 5 6 7 8 9 10 11 12 13

  4. How we built our multi-agent research system — Anthropic Engineering — https://www.anthropic.com/engineering/multi-agent-research-system 2 3 4 5

Exercícios

01

Sem código. Abaixo está um resumo de métricas de cinco tarefas que seu agente rodou ontem:

Nível 1: Leia três tipos de problema em uma tabela de métricas
TarefaTempo totalChamadas de ferramentaTokens totaisErros de ferramenta
T1 Corrigir um teste que falha42s938,4000
T2 Achar o uso de uma API na documentação186s41214,0000
T3 Gerar um relatório semanal71s1244,9007
T4 Refatorar um módulo402s16806,0001
T5 Responder uma pergunta de configuração55s831,2000

Contexto adicional puxado dos logs:

  • As 41 chamadas de T2 incluem 28 chamadas a search_docs, com apenas o parâmetro offset mudando: 0, 20, 40, 60…
  • Os 7 erros de T3 vieram todos de search_issues, com texto de erro idêntico: invalid parameter: date_range
  • As 16 chamadas de T4 incluem 4 chamadas de read_file lendo o mesmo arquivo de 3.000 linhas; o 1 erro é um timeout de run_tests
  • T1 e T5 não mostram chamadas repetidas à mesma ferramenta

Responda três perguntas, declarando em qual número (ou detalhe de contexto) você se apoiou em cada uma: qual padrão aponta para “parâmetros de paginação ou de limite de tokens precisam de ajuste”? Qual aponta para “a descrição da ferramenta precisa de clareza ou exemplos”? Qual valor de tokens vale investigar primeiro, e por que é esse e não o segundo maior total? Mais um verdadeiro/falso: o 1 erro de T4 constitui um sinal de que “a descrição da ferramenta precisa ser corrigida”?

Critérios de conclusão · marcado localmente
02

Este exige código que rode de verdade. Abaixo está um trecho de log JSONL do seu harness (20 registros, 4 prompts, 2 sessões). Salve como agent.jsonl:

Nível 2: Escreva um script de agregação de logs

Escreva um stats.mjs que rode com node stats.mjs agent.jsonl e faça quatro coisas: ler o JSONL (um objeto por linha, pular linhas vazias, capturar e reportar linhas ruins sem interromper); agregar por type produzindo contagem, duração total, tokens totais e contagem de erros; agrupar por prompt_id para achar execuções em que “existe erro e não há registros posteriores” e imprimir o prompt_id, o session_id e a mensagem de erro delas; código de saída 1 significa suspeita de travamento detectada, 0 significa nenhuma (para poder plugar em CI ou cron). Use apenas a biblioteca padrão do Node, sem dependências.

Critérios de conclusão · marcado localmente