Pular para o conteúdo
claudemods

Agent Profiler: um profiler para Claude Code que mostra para onde vai o tempo

Para onde vai o tempo de uma sessão do Claude Code: modelo, ferramentas, subagentes, ao vivo. Com exportação OTLP.

Permissões

  • Grava arquivosPode criar ou sobrescrever arquivos na sua máquina ($.fs.write).
  • RedePode fazer requisições HTTP ou se comunicar com servidores MCP ($.http.fetch / $.mcp.*).
  • Intercepta chamadas de ferramentasVê cada chamada de ferramenta que o Claude faz (tool.call / tool.check) e pode bloqueá-la ou alterá-la.
  • Altera a interfaceDesenha na interface do Claude Code: faixas, painéis, texto de status, notificações (ui.render / $.ui.*).
  • Adiciona comandos/ferramentasRegistra novos comandos de barra ou ferramentas que você ou o Claude podem acionar ($.command.register / $.tool.register).
testado com
v2.1.303
último teste
requer
Claude Code ≥ 2.1.287
superfícies
status, painel, notificação

Instale dentro do Claude Code:

/plugin install agent-profiler --marketplace YeonwooSung/my-claude-code-mods
Todas as opções de instalação ↓

O que este mod faz?

O Agent Profiler é um profiler para Claude Code criado por YeonwooSung, parte da coleção my-claude-code-mods. Ele responde a uma pergunta: quando uma sessão parece lenta, para onde foi o tempo? Divide o tempo de cada turno em espera pelo modelo, execução de ferramentas, subagentes bloqueantes e sobrecarga do motor, e mostra o resultado em três lugares.

  • Uma linha de status que se atualiza enquanto o Claude trabalha, por exemplo model 100% · tools 0% · ▶ model claude-haiku-5-5 12.5s.
  • /profile, um relatório em texto da sessão inteira, ou /profile turn para o último turno. Ele lista categorias de tempo, tempo até o primeiro token, tokens, ferramentas lentas, leituras repetidas de arquivos, subagentes e uma lista curta de achados.
  • /profile-pane, um painel ao vivo com as requisições e ferramentas em andamento. O /profile-export grava a sessão como OTLP JSON.

O mod é cuidadoso com o que afirma. Ele nunca informa um "tempo de inferência". Cada número carrega um grau: measured (entregue pelo Claude Code, como a duração de uma ferramenta), observed (medido pelo mod nos limites dos eventos), reported (uso de tokens informado pela API) ou inferred (um resto calculado). O README do autor exige o Claude Code 2.1.287 ou posterior.

Demonstração

A gravação inicia o Claude Code com o mod carregado no pequeno projeto de demonstração e pede ao Claude que leia o README.md e descreva o projeto em uma frase. Enquanto o turno roda, a linha de status acima do rodapé conta ao vivo: primeiro model 92% · tools 0%, depois model 100% com a requisição em andamento ▶ model claude-haiku-5-5 e seus segundos decorridos. Quando o turno termina, o clipe executa /profile. O relatório mostra 29,0 s de espera pela resposta do modelo, 5 ms de ferramentas, o tempo até o primeiro token, 82,3k tokens de entrada, a única chamada Read e o achado de que esperar pelo modelo foi 100% do tempo do agente.

Instalação

Use qualquer um dos métodos do bloco de instalação; todos instalam direto do marketplace do próprio autor. Esse marketplace lista vários plugins, então escolha agent-profiler. A linha de status e os comandos aparecem no próximo início de sessão.

$ install agent-profiler

Requer Claude Code ≥ 2.1.287

Instala a partir do marketplace do autor: YeonwooSung/my-claude-code-mods

  1. 1.Uma linha, dentro do Claude Code

    /plugin install agent-profiler --marketplace YeonwooSung/my-claude-code-mods

    Cole em uma sessão em andamento (v2.1.275+). O Claude Code pede primeiro para adicionar o marketplace.

  2. 2.Pelo seu shell

    claude plugin marketplace add YeonwooSung/my-claude-code-mods
    claude plugin install agent-profiler@my-claude-code-mods

    Depois execute /reload-plugins em qualquer sessão que já esteja aberta.

  3. 3.Experimente sem instalar

    git clone https://github.com/YeonwooSung/my-claude-code-mods
    claude --plugin-dir ./my-claude-code-mods/agent-profiler

    Carrega o mod só para uma sessão. Nada é adicionado às suas configurações.

Como funciona

O módulo hooks/register.tsx mantém um objeto Profiler na memória e o alimenta nos limites dos eventos: turn.start e turn.complete, cada chamada ao modelo por turn.step, cada ferramenta por tool.call, e a duração de ferramenta que o próprio Claude Code fornece em classic.PostToolUse. O hook tool.call só observa. Ele espera a ferramenta com await next(e) e devolve a resposta sem alteração, de hooks/register.tsx:

on('tool.call', async ($, e, next) => {
  anonymous += 1
  const id = e.tool_use_id ?? `anonymous-${anonymous}`
  const tool = String(e.tool)
  safe(() => profiler.toolStart(Date.now(), { id, tool, agentId: e.agentId, input: summarizeInput(tool, e as unknown as Record<string, unknown>) }))
  paint($)
  try {
    const answer = await next(e)
    safe(() => profiler.toolEnd(Date.now(), id, toolOutcome(answer)))
    return answer
  } // ...
}).catch(($, e, next) => next(e))

Cada etapa de registro passa por safe(), então um erro do profiler é descartado em vez de quebrar a sessão. A linha de status é redesenhada no máximo duas vezes por segundo. Depois de cada turno, o mod grava os spans recém-concluídos em <outputDir>/<sessionId>/<loadId>-<seq>.otlp.json e, ao fim da sessão, grava o restante mais um span raiz da sessão. Os nomes dos spans seguem as convenções GenAI (chat <model>, execute_tool <tool>, invoke_agent <type>). Os ids de span e de trace são determinísticos, então enviar a mesma sessão duas vezes gera os mesmos spans. A memória é limitada a 20.000 requisições e chamadas de ferramentas; acima disso, os turnos concluídos mais antigos são descartados.

Personalize

Três opções ficam no menu de configurações do /plugin ou em pluginConfigs:

Opção Padrão Significado
otlpEndpoint vazio URL base de um coletor OTLP/HTTP como http://localhost:4318. Vazio significa só arquivos.
outputDir ~/.claude/agent-profiler Onde os arquivos de trace são gravados, uma pasta por sessão.
exportCommandText false Inclui nas exportações os prompts dos turnos, as linhas de comando Bash e os padrões de busca, ocultando segredos óbvios.

Para ver um trace no Jaeger, execute o examples/jaeger/docker-compose.yml do repositório, defina otlpEndpoint como http://localhost:4318 e abra http://localhost:16686. O Grafana Tempo aceita o mesmo endpoint OTLP/HTTP.

Permissões e segurança

Antes de executar, lemos os arquivos que o plugin pode executar: .claude-plugin/plugin.json, hooks/hooks.json, e hooks/register.tsx e o arquivo compose do Jaeger por inteiro. Dos onze módulos de hooks/core/, lemos por inteiro export.ts, otlp.ts, redact.ts e o resumidor de entradas de profiler.ts, e pesquisamos em todos chamadas de rede, processos, arquivos, eval, import() e ambiente (os únicos resultados estão em register.tsx). Os arquivos de teste foram listados, não lidos. Não há package.json, script de instalação, binário, código empacotado ou minificado, eval nem import() dinâmico. O código-fonte de hooks/ não tem caracteres de largura zero nem ocultos; os únicos caracteres não ASCII são símbolos visíveis de status e relatório como █, ░, · e ⏱. O mod não injeta texto em prompts nem em resultados de ferramentas.

Achados relevantes:

  • Grava arquivos, ligado por padrão. Chama $.fs.write depois de cada turno e ao fim da sessão, em ~/.claude/agent-profiler/<sessionId>/, a menos que você defina outputDir. É a pasta do próprio plugin, não settings.json nem um arquivo do shell, mas é gravada sem perguntar. Os arquivos contêm tempos, contagens de tokens, nomes de modelos, nomes de ferramentas, caminhos de arquivos de Read/Edit/Write e uma categoria para cada comando Bash (como test ou build). Os caminhos de arquivos são sempre exportados. Prompts, comandos Bash e padrões de busca só com exportCommandText.
  • Rede só se você optar. $.http.fetch só é chamado quando otlpEndpoint não está vazio, e apenas envia por POST o mesmo JSON de trace para <endpoint>/v1/traces. O host é o que você digitar. Se apontar para um coletor remoto, caminhos de arquivos e, com exportCommandText, comandos com segredos ocultados saem do seu computador. O README avisa que a ocultação é de melhor esforço.
  • Lê uma variável de ambiente, HOME, para expandir ~ em outputDir.
  • Intercepta chamadas de ferramentas sem alterá-las. tool.call e tool.check são observados e repassados sem mudança, ambos com proteção .catch. Nada é negado nem reescrito. O claude plugin validate também lista os hooks classic.* como hooks de controle sem .catch; são observadores que devolvem next(e). Segundo o validate, os hooks classic.* não rodam quando uma organização gerencia o Claude Code, então lá o relatório pode ficar incompleto.
  • Sem processos, sem daemons, sem chamadas ao modelo. Não executa comandos nem mantém serviço em segundo plano. Os únicos temporizadores são relógios dentro da sessão.
  • Serviço externo opcional. Jaeger ou Tempo só são necessários para navegar pelos traces. O arquivo compose baixa jaegertracing/all-in-one:latest e o mod nunca o executa.
  • Licença. Apache-2.0 (o LICENSE na raiz do repositório).

O claude plugin validate não relatou erros nem avisos, apenas as notas acima. Os 67 testes do autor em 11 arquivos passaram todos com claude plugin test no Claude Code 2.1.303.

Grava arquivos
Pode criar ou sobrescrever arquivos na sua máquina ($.fs.write).
Rede
Pode fazer requisições HTTP ou se comunicar com servidores MCP ($.http.fetch / $.mcp.*).
Intercepta chamadas de ferramentas
Vê cada chamada de ferramenta que o Claude faz (tool.call / tool.check) e pode bloqueá-la ou alterá-la.
Altera a interface
Desenha na interface do Claude Code: faixas, painéis, texto de status, notificações (ui.render / $.ui.*).
Adiciona comandos/ferramentas
Registra novos comandos de barra ou ferramentas que você ou o Claude podem acionar ($.command.register / $.tool.register).

Compatibilidade e solução de problemas

Verificado com o Claude Code 2.1.303 no macOS: validate, os testes do autor e a gravação da demonstração. O README diz que o teste de ponta a ponta do próprio autor rodou na 2.1.280 e que os formatos dos eventos seguem as declarações de tipos da 2.1.292. O painel e a linha de status são desenhados no terminal e na aba Code do app desktop, mas não no painel de chat do VS Code nem no claude -p; o texto do /profile funciona em todo lugar.

  • Sem linha de status ou comandos. Confira se claude --version é 2.1.287 ou posterior e execute /reload-plugins depois de instalar em uma sessão já aberta.
  • Sem arquivos de trace. Nada é gravado até o id da sessão ser conhecido. Uma falha de gravação aparece uma vez como toast; verifique se outputDir permite escrita.
  • Os números zeram após um hot reload. O estado em memória recomeça, mas os lotes já gravados continuam no disco sob o id de carga anterior.
  • Arquivos alterados via Bash. O detector de leituras repetidas não os enxerga.
  • O tempo dentro do servidor do modelo (fila, prefill, decodificação) não pode ser dividido por nenhuma ferramenta do lado do cliente; o tempo até o primeiro token o agrupa.

Perguntas frequentes

O Agent Profiler envia meus dados para algum lugar?
Não por padrão. Ele grava arquivos de trace em uma pasta do seu computador. Só faz uma requisição de rede se você definir a opção otlpEndpoint, e então envia cada lote de traces por POST para essa URL mais /v1/traces. Nada é enviado ao autor.
Onde os arquivos de trace são gravados?
Em ~/.claude/agent-profiler/<sessionId>/, a menos que você defina outputDir. Um arquivo é gravado depois de cada turno concluído e de novo quando a sessão termina. Eles contêm tempos, contagens de tokens, nomes de ferramentas e caminhos de arquivos.
Meus prompts e comandos Bash são exportados?
Não, a menos que você ative exportCommandText. Com a opção desligada, prompts, linhas de comando Bash e padrões de busca ficam fora dos arquivos e dos POSTs, e só uma categoria de comando como test ou build é mantida. Ligada, eles são exportados depois de ocultar segredos da melhor forma possível.
Ele mede quanto tempo o modelo computa?
Não, e o README diz isso. Ele mede quanto o cliente esperou, por exemplo o tempo até o primeiro token, que mistura rede, fila e prefill. Cada número leva a marca observed, measured, reported ou inferred.
Preciso do Jaeger ou de outro serviço?
Não. O /profile e a linha de status funcionam sozinhos. Jaeger ou Grafana Tempo só são necessários se você quiser explorar os traces OTLP exportados em uma interface. O repositório inclui um pequeno arquivo docker-compose do Jaeger para isso.
Agent Radar em execução no Claude CodeDestaque

Agent Radar

Uma linha ao vivo acima do prompt por subagente em execução: tempo, ferramentas e ação atual, mais um painel /radar.

  • acima do prompt
  • painel
  • notificação
  • Intercepta chamadas de ferramentas
  • Lê seus prompts
  • Altera a interface
  • Adiciona comandos/ferramentas

testado com v2.1.291

Cache Clock em execução no Claude CodeDestaque

Cache Clock

Uma linha do cache de prompt sob a barra de status: tempo restante, taxa de acertos e tokens recacheados a frio.

  • status
  • Lê arquivos
  • Grava arquivos
  • Executa comandos
  • Adiciona comandos/ferramentas

testado com v2.1.296

Contador de chamadas de ferramentas em execução no Claude CodeDestaque

Contador de chamadas de ferramentas

Conta as chamadas de ferramentas do Claude por turno e por sessão, mostra o total junto ao spinner e adiciona /tally.

  • spinner
  • transcrição
  • status
  • Intercepta chamadas de ferramentas
  • Altera a interface
  • Adiciona comandos/ferramentas

testado com v2.1.310

Mais em Timers, tarefas e standups, Linha de status e barra do prompt, Painéis e dashboards.