AIDive

Pare de Redigitar Prompts: 4 Jobs no Claude Code, 4 Arquivos

Por AIDive · Publicado em

Agentes de códigoAutomação e workflows

Quatro prompts que você redigita viram quatro arquivos

As extensões do Claude Code são os arquivos que um repositório pode guardar para você parar de redigitar o mesmo prompt: uma skill, um hook, um subagent e um servidor MCP. Rodamos quatro tarefas recorrentes em um repo real, uma pequena API de faturas com um arquivo JSON como banco de dados. Cada tarefa recebeu primeiro a extensão errada, e a escolha errada falhou na tela todas as vezes. Depois cada uma virou um arquivo commitado. Esta página cobre os quatro gestos e o cartão de escolha que decide qual tipo usar.

Dois resultados enquadram tudo o que vem a seguir. Um hook costuma ser descrito como uma garantia e uma regra no arquivo de memória como um pedido, mas nosso primeiro hook rodou, exibiu o aviso e a escrita passou mesmo assim. O que transforma um hook que roda em um hook que bloqueia é explicado na seção do hook. O primeiro servidor de docs que conectamos não mudou nada, e o que respondeu foi o servidor de docs da própria ferramenta. A receita de hook que a maioria copia também exige um arquivo de script separado, mas a nossa cabe inteira no arquivo de configurações.

Antes de escrever qualquer um dos quatro arquivos, você precisa saber o que sua sessão já carrega.

O que são os quatro e o que sua sessão já carrega

Uma extensão do Claude Code é um arquivo que você adiciona ao repo para parar de redigitar as mesmas instruções na caixa de prompt. Existem quatro tipos, e quem já os conhece pode pular para a próxima seção.

  • Uma skill é um roteiro arquivado no seu repo. O Claude carrega os passos só quando essa tarefa aparece, e você pode iniciá-la digitando o nome dela.
  • Um hook é como um hook de commit no git, mas para as ações do próprio Claude. É um script que roda em um evento, como uma edição, seja qual for a intenção do Claude.
  • Um subagent é um terceirizado com a mesa vazia. Ele recebe o seu briefing, faz a leitura e devolve um relatório em vez da pilha de arquivos.
  • Um servidor MCP é um cliente de API que o Claude pode chamar, para dados que não estão no seu disco, como um banco de dados ou a documentação de uma ferramenta.

Para medir qualquer coisa, primeiro você precisa de uma linha de base. Abra uma sessão nova e rode o comando de contexto. Ele imprime uma tabela com tudo o que foi carregado antes da sua primeira palavra. No nosso teste, o total foi 26,2k tokens de uma janela de 1m, sem linha de arquivos de memória e sem nenhuma linha de MCP. Cada tarefa que você der ao Claude daqui para a frente ou acrescenta uma linha a essa tabela ou a deixa como está.

O primeiro job: o checklist de release vira uma skill

Uma skill é um checklist arquivado em uma pasta própria que o Claude só lê quando você a chama. O primeiro job é um checklist de release que você vive colando na caixa de prompt: typecheck, testes, subir a versão, adicionar uma linha no changelog, commit e tag.

O lugar óbvio para ele é o arquivo de memória, e essa é a escolha errada, porque tudo o que está nesse arquivo é carregado em cada turno de cada sessão. Colocamos os passos ali e lemos a tabela de contexto de novo. Ela tinha ganhado uma linha de Memory files com 210 tokens, carregada quer você esteja fazendo um release ou não. A documentação diz exatamente isso: quando uma seção desse arquivo virou um procedimento, o lugar dela é em uma skill.

A escolha certa é uma pasta dentro do diretório de skills com os passos em .claude/skills/release/SKILL.md, uma descrição curta no topo e uma linha extra de frontmatter, disable-model-invocation: true. Essa linha tira a skill da lista do próprio Claude, então só você pode iniciá-la, que é o que se quer para algo que faz commit e tag. Depois você digita uma barra e o nome dela, e o checklist roda.

Leitura do contexto Total Linha de Memory files
Linha de base, sessão nova 26.2k / 1m nenhuma
Checklist no arquivo de memória 26.4k / 1m 210 tokens
Checklist como skill 26.2k / 1m nenhuma, skill não listada

Quando rodamos, o Claude concluiu os seis passos em menos de um minuto: typecheck, 34 testes, versão de 0.4.0 para 0.4.1, linha no changelog, commit e tag. Ele também pegou uma falha no nosso próprio checklist. O comando de commit como estava escrito ignora arquivos não rastreados, então o Claude colocou o novo changelog no stage primeiro e avisou. O release agora é um comando que você digita, vive no repo para o time inteiro e não custa nada de contexto até você digitá-lo.

O segundo job: a regra que precisa valer vira um hook

Um hook é um script que o Claude Code roda antes de uma ferramenta disparar, aqui antes de qualquer edição ou escrita, e o que esse script responde decide o que acontece em seguida. O segundo job é uma regra que nunca pode quebrar: neste repo o arquivo de dados armazenados nunca é editado à mão, e toda mudança passa por uma migração.

Escrever essa regra em maiúsculas no arquivo de memória não a faz valer. A documentação é direta: esse arquivo é contexto, não configuração imposta, e uma instrução como "never edit this file" é um pedido, não uma garantia, enquanto um hook que bloqueia a edição é imposição.

O primeiro hook óbvio é o que escrevemos. No arquivo de configurações, ele vigia as escritas no arquivo de dados, exibe um aviso e sai com código zero, como um script de log. Em seguida pedimos ao Claude para mudar o valor de uma fatura direto no arquivo, sem migração. O hook rodou e o aviso apareceu, mas a escrita passou: o preço unitário da terceira fatura foi de 8000 para 12000. A resposta do Claude nunca mencionou o hook, porque um hook que sai limpo e não imprime nada não tomou nenhuma decisão, e os avisos dele nunca chegam ao Claude.

A garantia não é o hook rodar, é a resposta que ele devolve. A correção mantém o mesmo hook e faz com que ele devolva uma decisão de deny: uma linha curta de JSON com o motivo que você quer que o Claude leia. Sair com código dois bloqueia do mesmo jeito. O hook inteiro é um comando inline em .claude/settings.json, sem arquivo de script:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -c 'if (.tool_input.file_path // \"\") | test(\"data/.*\\\\.json$\") then {hookSpecificOutput: {hookEventName: \"PreToolUse\", permissionDecision: \"deny\", permissionDecisionReason: \"Stored data is never edited by hand: write a migration in src/store/migrations.ts (README § Conventions).\"}} else empty end'"
          }
        ]
      }
    ]
  }
}

Com o mesmo pedido, a edição foi recusada e o arquivo de dados ficou intacto. O Claude viu este erro: PreToolUse:Edit hook error: Stored data is never edited by hand: write a migration in src/store/migrations.ts (README § Conventions). Ele disse que não tinha mudado nada e perguntou se devia ignorar a proteção ou escrever a migração.

O limite, que o próprio Claude apontou: este hook vigia só as ferramentas de edição e escrita, e em uma rodada posterior o Claude se ofereceu para fazer a mudança pelo shell. Um hook precisa cobrir o shell também, ou o shell precisa ficar fora da sua lista de permissões, porque uma proteção que cobre só uma porta continua sendo um pedido. O hook não custa nada de contexto, porque roda fora da sua conversa.

O terceiro job: a auditoria que inunda vira um subagent

Um subagent é uma sessão separada do Claude com um contexto próprio, em branco. Ele recebe o seu briefing, lê o que precisa e só devolve um resumo. O terceiro job é uma auditoria que inunda a sua thread: conferir cada arquivo da pasta de código-fonte contra as convenções do README e listar toda violação com arquivo e linha.

Pedida inline, o Claude lê todos os arquivos para dentro da sua conversa, e todo esse conteúdo fica lá pelo resto da sessão. Na nossa rodada o Claude leu os 19 arquivos de código, a linha Messages da tabela de contexto inchou e os achados ficaram enterrados sob a pilha.

A escolha certa é um arquivo em .claude/agents/, aqui .claude/agents/conventions-auditor.md, com um nome, uma descrição de quando usar, as ferramentas que ele pode usar e um modelo fixado. Fixar o modelo importa, porque um subagent, se não, herda o que a sua sessão estiver usando, e a maioria dos trabalhos de leitura não precisa do modelo grande.

Fizemos exatamente a mesma pergunta de novo, e o Claude leu os arquivos ele mesmo. Nas duas tentativas ele nunca chamou o agente, mesmo ele estando listado: 0 de 2 delegações. O que funcionou foi citá-lo no começo do prompt: "use the conventions auditor subagent". Saiu uma única chamada e voltou um resumo curto.

Execução Contexto total Linha Messages
Auditoria inline 46.1k 19.3k
Subagent nomeado 34.1k 7.2k

Os achados foram igualmente bons: o subagent pegou um bug de caminho que a execução inline tinha deixado passar, e deixou passar um que a execução inline achou. Então o arquivo faz o subagent existir, e o seu prompt faz o Claude usá-lo; até o Claude escolhê-lo sozinho, você o cita. Um limite: a conta não mudou. As duas execuções custaram o mesmo, porque a leitura continua acontecendo, só que não na sua janela.

O quarto job: o dado que o Claude não alcança vira um servidor MCP

Um servidor MCP é um cliente de API que o Claude pode chamar, e o trabalho para o qual ele existe são dados mais novos que o modelo ou que ficam fora do seu disco. A escolha reflexa aqui é errada, e nós a fizemos primeiro.

Conectamos um servidor de docs público para a nossa biblioteca de testes e pedimos ao Claude um teste com fake timers. Nada mudou: o Claude já conhecia essa biblioteca e só chamou o servidor quando o citamos. Documentação que o modelo já conhece não é dado que ele não alcança.

O teste de verdade é uma pergunta sobre o próprio Claude Code, sobre uma configuração de hook mais nova que o modelo: qual configuração faz um hook com falha bloquear, qual versão a adicionou e qual é o JSON exato. Sem servidor, o Claude leu o schema de configurações da própria instalação, não achou nada e respondeu que não conseguiu encontrar a configuração e que não ia chutar uma. Essa resposta é honesta e inútil, porque a configuração existe; ela só chegou depois do conhecimento do modelo.

A correção é adicionar ao repo o servidor de docs do próprio Claude Code, com escopo de projeto, para que a config vá parar em um arquivo na raiz do repo que o time inteiro recebe:

claude mcp add --transport http claude-docs --scope project https://code.claude.com/docs/mcp

Isso grava .mcp.json. O Claude Code lista o servidor como pendente até você aprová-lo na sua próxima sessão, e a partir daí as ferramentas dele ficam disponíveis para o Claude. Fizemos a mesma pergunta em palavras simples, sem citar o servidor. O Claude pesquisou a documentação, achou a página e respondeu com a configuração, a versão e o JSON a adicionar, com o link.

A configuração é "onFailure": "block", que faz um hook com falha bloquear a ação em vez de deixá-la passar. Ela chegou na v2.1.295, enquanto a nossa instalação ainda estava na 2.1.294. Esse é o limite: o Claude nunca disse que a nossa instalação não podia usá-la, porque não conferiu a versão, então a versão você confere por conta própria. Na tabela de contexto o servidor aparece só pelos nomes das ferramentas, carregadas sob demanda até o Claude buscar uma.

Quatro arquivos, um cartão de escolha

Depois dos quatro jobs, o git status mostra exatamente quatro arquivos, porque o hook não precisa de um script próprio:

  • .claude/skills/release/SKILL.md
  • .claude/settings.json
  • .claude/agents/conventions-auditor.md
  • .mcp.json

Faça o commit deles, e a próxima sessão neste repo terá todos, assim como qualquer pessoa que o clonar.

O motivo de cada escolha ter sido certa é uma tabela que a documentação traz, e que você pode guardar como cartão de decisão:

Situação Extensão
Um procedimento que você cola mais uma vez Skill
Algo que precisa acontecer toda vez, sem perguntar Hook
Uma tarefa lateral que inunda a conversa com uma saída que você não vai reler Subagent
Dados que você vive copiando de um lugar que o Claude não enxerga Servidor MCP

Os tipos também se combinam. A documentação une uma skill a um servidor MCP: o servidor fornece a conexão, e a skill ensina o Claude a usá-la bem. Uma skill também pode rodar dentro de um subagent em fork, para que a leitura dela fique fora da sua janela. Quando outro repo precisar da mesma configuração, um plugin é a caixa que entrega todos juntos.

O cartão decide o tipo, não a qualidade. Um hook que só registra, um subagent que você nunca cita e um servidor para docs que o modelo já conhece estavam todos no tipo certo e mesmo assim falharam. Escolha o tipo pelo cartão e depois faça o arquivo responder, não apenas existir.

Veredito: quando usar cada um, quando nenhum, a regra única

Os quatro jobs que você costumava redigitar foram testados do jeito errado primeiro, falharam na tela e agora são arquivos no repo que funcionam. O release é um comando que você digita. A regra dos dados é um hook que recusa a edição e faz o Claude perguntar. A auditoria volta como um resumo. A pergunta sobre a documentação recebe a configuração e a versão que o Claude não conseguiu achar sozinho.

O hook com que abrimos, o que rodou e deixou a escrita passar, ensinou a regra por baixo de tudo isso: um hook decide só pelo que o comando dele devolve, então um hook que só registra é um pedido fantasiado.

Alguns casos não pedem nenhuma dessas opções:

  • Uma convenção que o Claude insiste em errar ainda pertence ao arquivo de memória, como uma linha, não como um procedimento.
  • Um trabalho que você precisa conduzir de um lado para o outro, com o seu histórico à vista, fica na thread principal e não em um subagent.
  • Um servidor de docs para uma biblioteca que o modelo já conhece custa contexto e não muda nada. Conecte o que o modelo não pode ter, não o que ele já tem.

A regra para lembrar: dê a cada job que você redigita o seu próprio arquivo, escolha o tipo pelo cartão e saiba que, entre eles, só o hook nunca pergunta.

Recursos gratuitos

Fontes

Perguntas frequentes

Devo usar uma skill, hook, subagent ou servidor MCP no Claude Code?
Use uma skill para um procedimento que você vive colando, um hook para algo que precisa acontecer toda vez sem perguntar, um subagent para uma tarefa lateral que inunda a sua conversa e um servidor MCP para dados que o Claude não enxerga. A documentação traz isso como uma tabela de decisão.
Por que meu hook do Claude Code rodou mas não bloqueou a edição?
Um hook decide só pelo que o comando dele devolve. Um hook que exibe um aviso e sai com código 0 não tomou nenhuma decisão, então a edição passa; devolver uma permissionDecision de deny, ou sair com código 2, bloqueia.
Devo pôr um checklist de release no CLAUDE.md ou em uma skill?
Em uma skill. Tudo o que está no arquivo de memória é carregado em cada turno de cada sessão (210 tokens para o nosso checklist de seis passos), enquanto uma skill com disable-model-invocation não custa nada de contexto até você digitar o nome dela.
Por que o Claude Code não chama meu subagent automaticamente?
Mesmo com uma descrição quase idêntica ao nosso prompt, o Claude leu os arquivos ele mesmo em 2 de 2 rodadas. Citar o subagent no começo do prompt fez o Claude delegar, e a linha Messages caiu de 19.3k para 7.2k tokens.
Quando vale a pena adicionar um servidor MCP ao Claude Code?
Quando os dados são mais novos que o modelo ou ficam fora do seu disco. Um servidor de docs para uma biblioteca que o modelo já conhece não mudou nada, enquanto o servidor de docs do Claude Code respondeu uma pergunta sobre uma configuração de hook que o schema da própria instalação não continha.
Como adiciono o servidor MCP de docs do Claude Code a um repo?
Rode claude mcp add --transport http claude-docs --scope project https://code.claude.com/docs/mcp. Ele grava o .mcp.json na raiz do repo, e o servidor aparece como pendente até você aprová-lo na sua próxima sessão.

Vídeos relacionados