ThiagoThomaz.com

Sistema de agentes Claude Code: como evitar que o contexto exploda

9 min de leitura
agentesclaude-codeia

TL;DR: Quando você usa o AgentTool do Claude Code para disparar um subagente, o sistema clona partes do contexto do pai e abre uma nova janela de contexto. Cada fork tem custo proporcional ao momento do disparo. Se o subagente não receber o campo querySource, ele pode acionar o autocompact enquanto o pai já está compactando, o que cria um ciclo recursivo imprevisível. Três ajustes simples resolvem a maioria dos casos.


Passei semanas construindo um sistema de agentes no Claude Code sem entender direito o que acontecia por baixo. O sistema funcionava, mas o custo de tokens era mais alto do que eu esperava e, vez ou outra, uma sessão travava de forma estranha.

Quando a codebase do Claude Code vazou em março de 2026, usei o próprio Claude Code para ler os 1.900 arquivos e extrair os princípios de arquitetura interna. O que encontrei mudou como penso na estrutura do sistema.

Este post explica o que aprendi na prática sobre contexto em sistemas multi-agente, com foco em três problemas reais que afetaram o meu sistema.

O que acontece quando você dispara um subagente?

Quando o Claude Code usa o AgentTool para criar um subagente, ele abre uma nova janela de contexto independente. O subagente não herda o histórico de conversa do pai. O único canal de comunicação é o prompt string que o pai envia no momento do disparo.

O que o subagente recebe: o prompt do pai, o system prompt definido no arquivo de configuração do agente, detalhes do ambiente (diretório de trabalho, plataforma) e as skills listadas na configuração. Tudo que o pai acumulou durante a sessão fica para trás, a não ser que o pai inclua explicitamente no prompt.

Isso é bom. A isolação mantém o contexto do pai limpo enquanto o subagente faz trabalho pesado. O subagente pode ler dezenas de arquivos, rodar buscas, fazer chamadas de ferramenta, e só o resultado final volta para o pai. Todo o ruído intermediário fica dentro da janela do subagente.

Qual é o custo real de um fork?

O custo de disparar um subagente depende do modelo e do escopo da tarefa. Para referência, conforme documentado na documentação oficial de subagentes:

  • Subagente do tipo Explore (modelo Haiku, somente leitura): cerca de 5k tokens por invocação
  • Subagente geral (modelo Sonnet, acesso completo às ferramentas): entre 30k e 50k tokens
  • Cada servidor MCP adicionado ao subagente acrescenta de 10k a 20k tokens

O custo em workflows multi-agente é de 4 a 7 vezes maior do que sessões de agente único. Agent Teams chegam a 15 vezes o uso padrão.

Mas tem um atenuante: mais de 90% dos tokens em sessões pesadas são leituras de cache de prompt, que custam 10% do preço de input normal. Na prática, o impacto financeiro é menor do que os números brutos sugerem.

O que não é atenuado: o custo de disparar um subagente caro quando a tarefa não justificava. No meu sistema, o agente Reviewer era disparado em 100% das tarefas, incluindo correções de uma linha. O Reviewer tem 337 linhas de persona e é disparado depois de Architect e Coder, quando o contexto já está carregado. Para tarefas triviais, esse fork era custo puro.

A solução foi um gate de skip baseado em task_type e contagem de LOC. Para bugfixes simples, config e docs com menos de 50 linhas, o Reviewer é pulado. Isso cortou entre 40% e 60% do custo nesses ciclos sem afetar qualidade nas tarefas complexas.

O que é autocompact recursivo e por que é um problema?

O autocompact é o mecanismo do Claude Code que compacta o histórico de conversa quando a janela de contexto está chegando perto do limite. A função autoCompactIfNeeded monitora o uso após cada execução. Quando acionada, cria um agente bifurcado para gerar um resumo sem interromper a conversa principal.

O problema aparece quando um subagente aciona o autocompact enquanto o agente pai também está em processo de compactação.

A função shouldAutoCompact() guarda apenas três tipos de mensagem: session_memory, compact e marble_origami. Se o subagente não recebe um querySource no momento do dispatch, ele não tem como saber que o pai está compactando. O resultado pode ser um ciclo de compactação dentro de outro ciclo, com comportamento imprevisível.

No meu sistema, nenhum dispatch de subagente incluía o campo querySource. Todos os subagentes podiam acionar autocompact recursivo sem proteção. O fix foi uma linha no template de dispatch. Não tinha feito antes porque não sabia que o campo existia.

O campo querySource é descrito na análise da codebase do Claude Code como o identificador que permite ao sistema coordenar compactação entre agente pai e subagentes. Sem ele, cada agente toma decisões de compactação de forma independente.

Como estruturar o CLAUDE.md para não pagar por ele em todo request?

O CLAUDE.md não é lido uma vez na abertura da sessão. É injetado em todo turno via getUserContext(). Um arquivo de 10k tokens custa 10k tokens em cada request ao longo de toda a sessão. Manter instruções longas no arquivo é um custo recorrente, não fixo. A solução é manter o arquivo enxuto e mover instruções específicas para os arquivos de configuração de cada agente.

O que parece um investimento fixo é na verdade um custo multiplicado pelo número de requests da sessão.

Tem um mecanismo de cache que ajuda: conteúdo antes do marcador SYSTEM_PROMPT_DYNAMIC_BOUNDARY é cacheado. Conteúdo dinâmico (git status, data atual) entra depois desse marcador. Qualquer mudança no estado do repositório invalida o cache do sistema inteiro para o conteúdo que ficou depois do marcador.

A prática que funcionou para mim: manter o CLAUDE.md enxuto. Instruções universais ficam no arquivo. Instruções específicas de cada agente ficam no arquivo markdown de configuração do próprio agente, em .claude/agents/. Isso evita que contexto de um agente polua o contexto de outro e reduz o tamanho do arquivo injetado em todo turno.

O post sobre como o Claude Code construiu este blog mostra na prática como a estrutura de arquivos de configuração afeta o comportamento do sistema.

Por que o cycle counter não é uma boa métrica de orçamento

Muitos sistemas de agentes usam um contador de ciclos como limite de segurança. "O agente pode executar no máximo N ciclos" é uma heurística comum.

O problema é que ciclos não mapeiam para uso de contexto de forma previsível. A função real para calcular o orçamento disponível é finalContextTokensFromLastResponse(). O buffer real do sistema é calculado como contextWindow - 13000 - min(maxOutputTokens, 20000).

Um counter de 7 ciclos, que era o limite do meu Maestro, pode parar quando ainda existe muito orçamento disponível (em ciclos curtos com pouca saída) ou deixar passar quando o contexto já está pesado (em ciclos longos com muito output).

O resultado prático é falsos positivos (o agente para sem necessidade) e falsos negativos (o agente continua quando deveria parar). A forma mais direta de corrigir é usar a fórmula real para determinar quando parar, não um número arbitrário de ciclos.

Para quem está construindo sistemas de agentes do zero, começar com essa fórmula em vez de um counter poupa bastante retrabalho depois.

Como configurar um subagente no sistema de agentes Claude Code?

Um subagente é um arquivo markdown em .claude/agents/ com frontmatter YAML. Os campos obrigatórios são name, description, model e tools. A description é o que o Claude usa para decidir quando delegar: quanto mais específica, melhor o roteamento. O campo isolation: worktree evita conflitos quando múltiplos subagentes trabalham em paralelo.

---
name: reviewer
description: Revisa código e aponta problemas de qualidade, segurança e padrões do projeto
model: claude-sonnet-4-5
tools:
  - read
  - bash
isolation: default
maxTurns: 10
---

Para subagentes que precisam ser rápidos e baratos, usar model: claude-haiku-4-5 e limitar as ferramentas disponíveis. Um subagente de exploração que só lê arquivos não precisa de acesso a bash ou ferramentas de escrita.

O que a auditoria do sistema de agentes encontrou na prática

Depois de ler os princípios da codebase, fiz uma auditoria de cada componente do meu sistema aplicando cada princípio como uma pergunta.

Quatro problemas principais apareceram:

querySource ausente em todos os dispatches. Risco direto de autocompact recursivo em qualquer sessão longa. Fix: uma linha no template.

Cycle counter de 7 ciclos no Maestro desconectado do orçamento real. O número 7 não tinha relação com a fórmula de budget. Criei um mecanismo baseado na função real.

Reviewer disparado em 100% das tarefas. Custo de fork alto para tarefas que não precisavam de revisão completa. Fix: gate de skip por complexidade.

CoT obrigatório de 70 linhas no Coder para qualquer tarefa. O bloco de chain-of-thought era marcado como "MANDATORY, never skip". O modelo produzia as 70 linhas para correção de typo, incluindo análise de pitfalls de frontend em tarefas de backend. Output desnecessário que vai direto para o contexto do turno seguinte.

O que já estava certo: estrutura de tiers de memória com separação de long-term e session context. Gate de aprovação humana no fluxo de planejamento. Filtro de noise antes do Reviewer analisar (arquivos gerados, lock files e vendor ficam de fora).

Nenhum dos quatro problemas exigiu refatoração grande. Três eram configuração, um era uma linha de código.

Conclusão

Sistemas multi-agente no Claude Code têm uma lógica de contexto específica. O AgentTool não é transparente: cada decisão de quando disparar um subagente, com qual prompt e com quais ferramentas, afeta o custo e o comportamento do sistema.

Os três ajustes que tiveram mais impacto no meu caso: incluir querySource em todo dispatch, criar um gate de skip para subagentes caros, e substituir o cycle counter pela fórmula real de orçamento de contexto.

Se você está construindo um sistema de agentes agora, a leitura do agent-optimization.md poupa tempo. São os princípios extraídos diretamente da codebase interna do Claude Code, aplicáveis a qualquer sistema.

Para receber mais conteúdo como este sobre agentes e sistemas de IA, assine a newsletter ou me siga no LinkedIn. Posto sobre o que estou construindo e o que estou quebrando, sem filtro.


Perguntas Frequentes

O que é o fork cost de um subagente no Claude Code?

Fork cost é o custo em tokens de disparar um subagente via AgentTool. O custo depende do modelo usado (Haiku custa cerca de 5k tokens por invocação, Sonnet entre 30k e 50k) e de quantos servidores MCP estão configurados. O ponto crítico é que o custo varia com o escopo da tarefa e o momento do disparo dentro da sessão. Subagentes disparados mais cedo, com prompts mais enxutos, custam menos.

O subagente herda o contexto do agente pai?

Não. O subagente recebe apenas o prompt enviado pelo pai, o system prompt do seu arquivo de configuração, detalhes do ambiente e as skills listadas. Nada do histórico de conversa do pai é passado automaticamente. Se o subagente precisar de um arquivo específico, uma decisão de arquitetura ou o output de outro subagente, o pai precisa incluir isso explicitamente no prompt de dispatch.

O que é autocompact recursivo e como evitar?

Autocompact recursivo acontece quando um subagente aciona o mecanismo de compactação de contexto enquanto o pai também está compactando. A causa raiz é a ausência do campo querySource no dispatch do subagente. Com esse campo, o sistema consegue coordenar a compactação entre pai e filho. Sem ele, cada um age de forma independente, o que pode criar ciclos imprevisíveis em sessões longas.

Qual é o limite real da janela de contexto no Claude Code?

O buffer efetivo é calculado como contextWindow - 13000 - min(maxOutputTokens, 20000). Para um modelo com janela de 200k tokens e maxOutputTokens de 4096, o limite real é aproximadamente 182.904 tokens. O autocompact dispara por padrão quando o uso chega a 95% desse valor, mas isso pode ser ajustado com a variável de ambiente CLAUDE_AUTOCOMPACT_PCT_OVERRIDE.

Como dimensionar um sistema de agentes para não estourar o orçamento?

Três práticas: usar modelos mais leves (Haiku) para subagentes de exploração e leitura, criar gates de skip para subagentes caros quando a tarefa não justifica o fork, e manter o CLAUDE.md enxuto para reduzir o custo recorrente por request. Workflows multi-agente consomem de 4 a 7 vezes mais tokens que sessões de agente único, então o dimensionamento precisa partir dessa premissa, não de estimativas de sessão única.