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
- código-fonte
- YeonwooSung (Apache-2.0)
Instale dentro do Claude Code:
/plugin install agent-profiler --marketplace YeonwooSung/my-claude-code-modsO 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 turnpara 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-exportgrava 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.Uma linha, dentro do Claude Code
/plugin install agent-profiler --marketplace YeonwooSung/my-claude-code-modsCole em uma sessão em andamento (v2.1.275+). O Claude Code pede primeiro para adicionar o marketplace.
2.Pelo seu shell
claude plugin marketplace add YeonwooSung/my-claude-code-mods claude plugin install agent-profiler@my-claude-code-modsDepois execute /reload-plugins em qualquer sessão que já esteja aberta.
3.Experimente sem instalar
git clone https://github.com/YeonwooSung/my-claude-code-mods claude --plugin-dir ./my-claude-code-mods/agent-profilerCarrega 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.writedepois de cada turno e ao fim da sessão, em~/.claude/agent-profiler/<sessionId>/, a menos que você definaoutputDir. É a pasta do próprio plugin, nãosettings.jsonnem 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 deRead/Edit/Writee 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ó comexportCommandText. - Rede só se você optar.
$.http.fetchsó é chamado quandootlpEndpointnã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, comexportCommandText, 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~emoutputDir. - Intercepta chamadas de ferramentas sem alterá-las.
tool.calletool.checksão observados e repassados sem mudança, ambos com proteção.catch. Nada é negado nem reescrito. Oclaude plugin validatetambém lista os hooksclassic.*como hooks de controle sem.catch; são observadores que devolvemnext(e). Segundo o validate, os hooksclassic.*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:lateste o mod nunca o executa. - Licença. Apache-2.0 (o
LICENSEna 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-pluginsdepois 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
outputDirpermite 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.
# Mods relacionados
DestaqueAgent 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
DestaqueCache 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
DestaqueContador 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.