antonio leandro

claude, na prática

Claude Code subagents

tutorial · 05 · na prática · Anthropic · · ~61 min de leitura do original

a tese

subagente não é paralelismo, é orçamento de contexto: ele lê o barulho na janela dele e devolve só o resumo — e o preço disso é que ele começa sem saber nada da sua conversa

o que fica

  1. A `description` de cada subagente é o que roteia a delegação e fica carregada o tempo todo; quando a soma das descrições passa de 15.000 tokens, o Claude Code avisa na inicialização e você tem que mover detalhe para o system prompt, que só carrega quando aquele subagente roda.
  2. Subagente em background — o padrão em sessão interativa com fork mode ligado — só mantém uma lista curta de ferramentas built-in, então a mesma definição resolve para conjuntos diferentes de ferramentas conforme onde roda, e a remoção não reporta erro.
  3. Explore e Plan não carregam CLAUDE.md nem o git status da sessão pai, e não há campo para mudar isso: regra que precisa valer para eles tem que ser repetida no prompt de delegação.
  4. Um fork herda a conversa inteira e, por ter system prompt e ferramentas idênticos ao pai, reaproveita o prompt cache dele — mais barato que um subagente novo, ao custo de abrir mão do isolamento de entrada.
  5. Arquivo de subagente sem `name`, sem `description` ou com YAML quebrado é ignorado em silêncio: o motivo só aparece no debug log.
  6. O resultado de cada subagente volta para a conversa principal, então muitos subagentes devolvendo relatório detalhado reintroduzem exatamente o problema de contexto que eles deviam resolver.

o problema

Uma sessão de agente queima a janela de contexto com material que ela nunca mais vai consultar: saída de grep, arquivo lido para descartar, log de teste, página de documentação aberta só para conferir uma assinatura. Nada disso é lixo no momento em que chega — cada pedaço responde uma pergunta. Mas fica. Quando a janela enche, vem a compactação, e a tarefa que importa perde fidelidade junto com o entulho.

O segundo problema é de escopo. Você acaba pedindo o mesmo tipo de trabalho — revisar código, depurar, consultar banco — com as mesmas instruções, sem lugar para fixá-las. E tudo roda com o mesmo conjunto de ferramentas, as mesmas permissões e o mesmo modelo: um trabalhador que só deveria ler tem Write na mão porque a sessão inteira tem Write, e uma busca trivial roda no modelo caro porque a conversa roda no modelo caro.

a ideia

Um subagente é um trabalhador com janela de contexto própria, system prompt próprio, lista de ferramentas própria e permissões próprias. Ele faz o serviço sujo no espaço dele e devolve para a conversa principal só o resumo. A definição é um arquivo markdown com frontmatter YAML, e a chave de tudo é o campo description: é por ele que Claude decide quando delegar. Descrição vaga não é um detalhe de estilo — é roteamento quebrado.

como funciona

---
name: code-reviewer
description: Revisa código para qualidade e segurança. Use logo após escrever ou modificar código.
tools: Read, Grep, Glob, Bash
model: inherit
---

Você é um revisor sênior. Para cada problema, explique a causa e mostre a correção.

name e description são obrigatórios. O corpo vira o system prompt — e o subagente recebe esse prompt mais detalhes de ambiente, não o system prompt do Claude Code.

Arquivos vivem em .claude/agents/ (projeto) ou ~/.claude/agents/ (usuário), com precedência: managed settings, flag --agents, projeto, usuário, plugin. O modelo resolve em outra ordem: parâmetro passado na invocação, campo model do frontmatter, variável CLAUDE_CODE_SUBAGENT_MODEL, modelo da conversa principal.

tools funciona como allowlist e disallowedTools como denylist, aplicada primeiro. Sobre isso incidem dois filtros do próprio Claude Code: um remove de qualquer subagente ferramentas como AskUserQuestion e EnterPlanMode; o outro corta o conjunto built-in de quem roda em background. permissionMode escolhe o modo de permissão, mas perde para o pai quando o pai está em bypassPermissions, acceptEdits ou auto mode.

Além disso: skills injeta conteúdo de skill no startup; mcpServers dá acesso a servidores MCP que a conversa principal não tem, evitando que as descrições daquelas ferramentas ocupem contexto lá; hooks prende validação ao ciclo de vida do subagente; memory dá um diretório persistente entre sessões; isolation: worktree roda o subagente numa cópia isolada do repositório.

Subagentes aninham até três camadas abaixo da conversa principal, e vinte simultâneos é o teto padrão. Um caso especial é o fork: em vez de começar do zero, ele herda a conversa inteira, com o mesmo modelo e as mesmas ferramentas. As chamadas dele continuam fora do seu histórico; só o resultado volta.

o que isso custou

A isolação de entrada é o ganho e a conta. Um subagente que não é fork não vê seu histórico, não vê as skills já invocadas, não vê os arquivos já lidos. Ele gasta tempo redescobrindo o que a conversa principal já sabia — a documentação recomenda ficar na conversa principal quando a latência importa ou quando o trabalho precisa de idas e vindas.

As descrições ocupam contexto permanentemente, mesmo quando nenhum subagente roda. Passando de 15.000 tokens somados, aparece aviso na inicialização.

O resultado sempre volta para a conversa principal. Vários subagentes devolvendo relatório detalhado recriam o problema original — a própria página avisa.

Explore e Plan pulam CLAUDE.md e git status para ficarem rápidos e baratos, e não existe campo para mudar isso. Regra de projeto que precisa alcançá-los tem que ser repetida no prompt.

Há uma varredura na saída de cada subagente antes de Claude ler, porque o subagente pode ter lido texto de terceiro com instrução embutida. A varredura não remove nada, não julga se o conteúdo é malicioso e, nas palavras do texto, não substitui restringir o que o subagente alcança.

onde isso aparece hoje

O mecanismo é o mesmo que sustenta os hooks do Claude CodeSubagentStart e SubagentStop existem por causa dele — e é a contraparte de Agent Skills: com skills no subagente, o subagente manda no system prompt e carrega a skill; com context: fork na skill, a skill é injetada no agente que você escolher.

O mesmo arquivo de definição serve para o Claude Agent SDK e para o modo não interativo, onde os built-in podem ser desligados por variável de ambiente, e escopar servidores MCP por subagente é o jeito recomendado de manter tool description fora da conversa principal.

lido na íntegra por pipeline de llm, revisado por antonio leandro antes de publicar ·