Pular para o conteúdo
← artigos
Claude CodeHarness EngineeringAI CodingDeveloper Tools

CLAUDE.md: boas práticas, o guia completo

O que entra no CLAUDE.md, o que cortar, onde fica cada arquivo e quanto ele custa. Mais a armadilha do import que colocou 70k tokens em cada sessão de um projeto de 13 apps.

O CLAUDE.md não é documentação. É a parte da sua context window que você já gastou antes de digitar a primeira palavra.

O Claude Code começa toda sessão sem memória nenhuma do seu projeto. O CLAUDE.md resolve isso: um arquivo Markdown que o Claude Code lê no início de cada sessão e mantém no contexto até a sessão acabar. Escreva bem e o Claude para de repetir os mesmos erros. Escreva mal e você paga por isso em cada requisição, em tokens e em instruções que o Claude segue pela metade.

A maioria dos conselhos sobre CLAUDE.md é um template. Este guia são as decisões: o que merece uma linha, o que sai, em qual arquivo cada instrução deve morar e como conferir quanto você está pagando de verdade. Aprendi a parte cara numa fintech de 13 apps que construí em 70 dias, onde um CLAUDE.md que parecia enxuto carregava quase 70.000 tokens em cada sessão.

CLAUDE.md é contexto, não configuração

Erre isso e nada mais no arquivo funciona. A documentação da Anthropic diz sem rodeio: o Claude “trata esses arquivos como contexto, não como configuração imposta”. O Claude lê seu CLAUDE.md do jeito que um engenheiro novo lê o documento de onboarding. Normalmente segue. Nem sempre. E quanto mais coisa o arquivo tem, menos dele é seguido.

Isso divide toda instrução em dois tipos. O tipo que exige julgamento (“filtre toda query por lojista”) vai no CLAUDE.md, porque só quem lê consegue aplicar. O tipo que nunca pode ser quebrado (“nunca rode kubectl apply”) não tem lugar num arquivo que o Claude pode ler por cima. Ele vai num hook ou num linter, onde a checagem roda com o Claude lembrando da regra ou não. Falo disso mais abaixo.

O CLAUDE.md da raiz do projeto também sobrevive à compactação. Depois de um /compact, o Claude Code relê o arquivo do disco e injeta de novo. Todo o resto que você disse no chat pode virar resumo. O arquivo fica.

Onde o CLAUDE.md fica decide quando você paga por ele

Não existe um CLAUDE.md. Existem vários, e eles carregam em momentos diferentes. Os arquivos no seu diretório de trabalho e em cada pasta acima dele carregam na inicialização e se empilham, da raiz do sistema de arquivos até onde você abriu o Claude, então o mais próximo é lido por último. Nada sobrescreve nada. Tudo é concatenado, e se dois arquivos se contradizem, a documentação avisa que o Claude “pode escolher um arbitrariamente”.

Todos os lugares onde o Claude Code procura

Conferido com a documentação de memória do Claude Code em 6 de outubro de 2026.
ArquivoQuando carregaUse para
~/.claude/CLAUDE.mdToda sessão, todo projetoSeus hábitos: as ferramentas que você usa, como gosta dos commits
./CLAUDE.md ou ./.claude/CLAUDE.mdToda sessão neste repoAs regras da equipe. Vai para o repo junto com o código
./CLAUDE.local.mdToda sessão neste repo, só para vocêSuas URLs de sandbox e dados de teste. Coloque no .gitignore
subpasta/CLAUDE.mdQuando o Claude abre um arquivo ali com Read, Edit ou WriteRegras de um pacote de um monorepo
.claude/rules/*.mdNa inicialização, como o arquivo do projetoDividir um arquivo grande por tema. Mesmo custo
.claude/rules/*.md com paths:Quando o Claude abre um arquivo correspondente com Read, Edit ou WriteRegras que só importam para alguns arquivos
Arquivo de política gerenciadaToda sessão, para todo mundo na máquinaRegras da empresa inteira, definidas pela equipe de TI
Conferido com a documentação de memória do Claude Code em 6 de outubro de 2026.

Leia a segunda coluna de novo. Tudo o que carrega na inicialização custa em toda sessão, quer a tarefa encoste nisso ou não. Tudo o que carrega sob demanda só custa quando o trabalho chega lá. Boa higiene de CLAUDE.md é, na maior parte, mover linhas do primeiro grupo para o segundo. Um detalhe: os arquivos sob demanda carregam quando o Claude abre um arquivo com as ferramentas Read, Edit ou Write. Um grep pelo Bash não conta, e esse costuma ser o motivo de uma regra “não ter carregado”.

Na fintech, meu CLAUDE.md tinha 124 linhas. Um resumo do projeto, os comandos, onze regras críticas e depois um conjunto organizado de tabelas apontando para vinte arquivos por tema: papéis de auth, schema do banco, design tokens, componentes de UI, convenções de teste, infraestrutura. Parecia um sumário.

Não era um sumário. Cada entrada estava escrita como @.claude/ui/components.md, e num CLAUDE.md o @ é um import. A documentação é clara sobre o que isso significa: “Arquivos importados são expandidos e carregados no contexto na inicialização, junto com o CLAUDE.md que os referencia.” Os imports podem se aninhar até quatro níveis.

O que aquele arquivo de 124 linhas carregava de fato

124
linhasno próprio CLAUDE.md
20
importsescritos como @path em tabelas
~175 KB
carregadosno início de cada sessão
69,8k
tokensmedidos com /context
O CLAUDE.md em si tinha 1,8k tokens. Os maiores imports eram componentes de UI (10,8k), infraestrutura (10,6k) e design tokens (7,4k). Um bug fix na API de pagamento carregava os três.

Setenta mil tokens é mais de um terço de uma context window de 200k, gastos antes da primeira mensagem. A ironia é que eu já tinha escrito a regra contra isso. Meu guia de AGENTS.md diz para apontar para a documentação detalhada em vez de colar o conteúdo no arquivo. Segui a regra no espírito e quebrei na sintaxe.

A correção é um caractere. De novo a documentação: “O parsing de imports ignora code spans do Markdown.” Coloque o caminho entre crases e ele deixa de ser um import. Vira texto que o Claude pode decidir abrir.

@.claude/ui/components.md

  1. 01Um import
  2. 02Expandido no contexto na inicialização
  3. 03Pago em toda sessão, em toda tarefa
  4. 04Aninha até quatro níveis
  5. 05Sempre visto, então sempre diluindo

`.claude/ui/components.md`

  1. 01Um ponteiro
  2. 02Texto simples no arquivo
  3. 03Pago só se o Claude abrir
  4. 04O Claude decide quando é relevante
  5. 05Pode passar batido, então não serve para regra obrigatória
Um caractere decide se um arquivo custa em toda sessão ou só quando é necessário.

A última linha importa. Um ponteiro só funciona se o Claude decidir abrir. Para uma regra que precisa valer sempre que o Claude mexe em certos arquivos, o ponteiro é fraco demais e o import é caro demais. É exatamente para isso que existem as rules com escopo de path.

Coloque cada instrução onde ela funciona de verdade

Quando você para de tratar o CLAUDE.md como o lugar de tudo, a pergunta para cada linha passa a ser: qual é o mecanismo mais barato que ainda faz isso acontecer? São seis.

Onde cada tipo de instrução deve ficar

A instrução é…Coloque emExemplo da fintech
Válida em todo lugar e exige julgamentoCLAUDE.mdOs dados de um lojista nunca chegam a outro
Válida só para alguns arquivos.claude/rules/ com paths:Design tokens, só quando um arquivo de frontend está aberto
Um procedimento de vários passosUma skillCriar uma migration, rodar, adicionar o teste
Algo que nunca pode acontecerUm hook ou um linterNunca rodar kubectl apply em infra gerenciada pelo Terraform
Válida só para vocêCLAUDE.local.md ou ~/.claude/CLAUDE.mdSeus hostnames HTTPS locais
Algo que o Claude aprendeu com uma correçãoAuto memoryDeixe o Claude escrever. O índice carrega até 200 linhas ou 25 KB

As skills merecem mais uma frase, porque são o melhor negócio da lista. O corpo de uma skill só carrega quando você a invoca ou quando o Claude decide que ela serve para a tarefa. Um procedimento de deploy de vinte passos no CLAUDE.md custa em toda sessão. O mesmo procedimento como skill custa no dia do deploy. Na fintech, oito comandos do projeto ficavam em toda sessão como skills, a uns 20 tokens cada, até alguém chamar um deles. O guia de skill vs prompt vs memória aprofunda essa divisão.

Caixa alta não impõe nada

Meu arquivo tinha onze regras no formato “NUNCA faça X” e “SEMPRE faça Y”. Gritar não mudou o que elas eram: contexto que o Claude lê e normalmente segue. Três delas nem precisavam do julgamento do Claude. Precisavam de uma máquina que dissesse não.

“NUNCA desative regras do ESLint” é uma linha de config do ESLint: linterOptions: { noInlineConfig: true }, e todo comentário de disable inline para de funcionar. “NUNCA use valores arbitrários do Tailwind” também é uma regra de lint. Este site roda exatamente essa regra, e o pnpm verify falha em p-[13px]. E “NUNCA rode kubectl apply” é um hook PreToolUse, que roda antes de o Claude executar um comando e pode bloqueá-lo:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.command' | grep -qE 'kubectl.* apply' && { echo 'Infra is managed by Terraform. Use terraform apply.' >&2; exit 2; } || exit 0"
          }
        ]
      }
    ]
  }
}

O exit code 2 bloqueia a chamada e devolve a mensagem ao Claude, que entende o motivo e troca para o Terraform. Coloque isso no .claude/settings.json e a regra vale também no dia em que o Claude ler seu arquivo por cima. Regra que pode ser imposta deve ser imposta. O CLAUDE.md é para as que não podem.

O que merece uma linha no CLAUDE.md

A documentação traz o melhor teste que já vi para saber quando adicionar uma linha. Adicione quando o Claude cometer o mesmo erro pela segunda vez, quando o code review pegar algo que o Claude deveria saber, quando você digitar a mesma correção que digitou na sessão anterior, ou quando um colega novo precisaria do mesmo contexto. O que o arquivo não deve guardar é o histórico em volta do código: decisões, pessoas, o que cada reunião definiu. Isso cresce sem limite, e o lugar dele é uma LLM wiki que o agente lê sob demanda. Se nada disso aconteceu, a linha é um chute.

O que entra no CLAUDE.md do projeto

  • Obrigatório:
    Duas ou três linhas sobre o que é o projetoA stack e o formato do repo. Nada de pitch, nada de ensaio sobre arquitetura.
  • Obrigatório:
    Os comandos que o Claude deve rodarSetup, servidor de dev, o comando que verifica tudo. O Claude não tem como adivinhar isso.
  • Obrigatório:
    Convenções que um bom engenheiro ainda errariaOnde os erros da API são traduzidos. Qual pacote cuida do auth. Tudo o que foge do padrão.
  • Obrigatório:
    Regras que exigem julgamentoIsolamento de dados, transações, o que nunca sai do servidor. Escreva de um jeito que dê para checar.
  • Obrigatório:
    Ponteiros entre crases para a documentação detalhadaCaminhos que o Claude abre quando a tarefa pede. Nada de @imports.
  • Anti-pattern:
    Regras que um linter ou um hook poderia imporImponha. Um arquivo só consegue pedir.
  • Anti-pattern:
    Referências longas sobre uma parte do códigoMova para uma rule com escopo de path, para carregar junto com os arquivos que ela descreve.
  • Anti-pattern:
    Conselhos genéricos como 'escreva código limpo'O Claude já faz isso. A linha custa tokens e não muda nada.
Se o arquivo passa de 200 linhas, a Anthropic diz que a aderência cai. O limite é por arquivo, e cada import conta como um arquivo à parte. O meu ficou abaixo disso. Os vinte imports dele, não.

Escreva cada linha de um jeito que dê para checar se o Claude seguiu. Os exemplos da própria documentação são bons: “Use indentação de 2 espaços” em vez de “Formate o código direito”, “Rode npm test antes de commitar” em vez de “Teste suas mudanças”. Se você não consegue dizer se uma regra foi quebrada, o Claude também não consegue.

Não deixe o /init escrever por você

O /init lê seu código e rascunha um CLAUDE.md. É um bom ponto de partida e um arquivo final ruim, e agora existem dados que explicam o porquê. O Evaluating AGENTS.md, um estudo de 2026 com agentes de código em issues reais do GitHub, mostrou que arquivos de contexto em geral não aumentaram a taxa de sucesso e somaram mais de 20% ao custo de inferência, em média. Arquivos gerados por um LLM foram um pouco piores do que nenhum arquivo. Arquivos escritos pelos próprios desenvolvedores do repo foram só um pouco melhores. O que ajudou foi o que foge do padrão, as convenções que um modelo não adivinharia. A visão geral do repositório, justamente o que o /init faz melhor, não ajudou.

Então rode o /init e depois corte. A documentação manda refinar o arquivo “com instruções que o Claude não descobriria sozinho”. Tudo o que o Claude descobriria lendo o código é uma linha que você paga para repetir. O guia de AGENTS.md tem o teste de poda que eu uso: se tirar uma linha não causaria nenhum erro, tire.

Um exemplo de CLAUDE.md: o arquivo da fintech, reescrito

Aqui está o arquivo de 124 linhas como eu escreveria hoje. Mesmo projeto, as mesmas regras que importam, nenhum import.

# Payment Platform

PIX payment gateway with on-chain settlement on the Liquid Network.
Turborepo + pnpm. Fastify 5, Drizzle, Zod. Next.js, Tailwind. PostgreSQL, Redis.

## Commands

- `pnpm setup:dev`: Docker, databases, migrations, seed
- `pnpm dev:https`: dev servers behind Caddy
- `pnpm verify`: format, lint, types, tests. Run it before every commit.

## Layout

- `apps/<domain>/api`: Fastify APIs for auth, exchange and payment
- `apps/<domain>/<app>`: Next.js frontends
- `packages/ui`, `packages/i18n`, `packages/auth`: shared code

## Rules that need judgment

- One merchant's data never reaches another merchant. Scope every query by merchant.
- Validate on the server. Never trust the client.
- Writes that touch more than one table run in a transaction.
- APIs return English messages plus a code from `ERROR_CODES`.
  Frontends translate with `getErrorMessage(code)`.

## Read when the task needs it

- Local setup: `.claude/setup/local-development.md`
- Git workflow: `.claude/git/workflow.md`
- Infrastructure: `infrastructure/README.md`

Menos de 40 linhas. O resto dos vinte arquivos não sumiu. Eles vão para onde carregam junto com o trabalho que precisa deles.

Para onde iria o resto da documentação

  • .claude/
    • CLAUDE.mdsempre// o arquivo acima
    • settings.jsonobrigatório// o hook do kubectl
    • rules/
      • frontend.mdpaths// frontends e packages/ui: tokens, componentes, UX
      • database.mdpaths// apps/*/api/src/db/**: schema, migrations, entidades
      • auth.mdpaths// APIs e packages/auth: papéis, scopes, permissões de rota
      • testing.mdpaths// pastas de teste e e2e: convenções de teste
      • pricing.mdpaths// apps/exchange/**: o motor de precificação
    • skills/
      • new-migration/sob demanda// o procedimento, carregado quando é usado

Uma rule com escopo de path é um arquivo Markdown normal com um campo a mais. Esta só carrega quando o Claude lê ou edita um arquivo dentro de uma pasta de banco de dados:

---
paths:
  - "apps/*/api/src/db/**"
---

# Database

- Every table: a prefixed ID (`mer_`, `cus_`, `ord_`), `createdAt`, `updatedAt`,
  and an index on every foreign key.
- Tables are snake_case plural. Columns are snake_case.
- Relations live in a separate `relations.ts`.

A rule de frontend continua grande. Só a referência de componentes de UI tem 10,8k tokens. Mas agora ela carrega quando o Claude abre um componente React, e fica de fora quando ele corrige um retry de webhook. Essa é a troca: o custo não sumiu, mudou para o momento em que ele compra alguma coisa.

Meça o que você carrega, não chute

Meu primeiro chute para a fintech, pelo tamanho dos arquivos, foi 45.000 tokens. O /context no repo antigo disse 69.800. O chute errou por um terço, e para o lado que agrada você. Meça. O Claude Code já vem com as ferramentas.

Dentro de uma sessão do Claude Code

  1. Veja cada arquivo de memória que carregou e quantos tokens ele ocupa

    /context
  2. Abra e edite os arquivos de memória que o Claude Code encontrou

    /memory
  3. Encontre instruções desatualizadas, faltando ou contraditórias (v2.1.283+)

    /doctor prompt-audit
O Claude Code também avisa no startup quando um arquivo, ou o conjunto deles, passa do tamanho recomendado.

Rode o /context no seu repo principal hoje. Se os arquivos de memória ocupam mais do que alguns milhares de tokens, abra o maior e pergunte, linha por linha, qual sessão realmente precisou daquilo.

CLAUDE.md vs AGENTS.md: um arquivo basta

Se o seu repo é usado por mais de um agente, talvez você nem precise de um CLAUDE.md. Desde a v2.1.277, o Claude Code lê o AGENTS.md como instruções do projeto quando não há CLAUDE.md nem CLAUDE.local.md na sua pasta ou acima dela, e Codex, Cursor, Copilot e outros também leem esse arquivo. Repare no segundo arquivo: criar um CLAUDE.local.md faz o Claude parar de ler seu AGENTS.md sem avisar. Se os dois tipos de arquivo existem, o Claude Code lê só os CLAUDE.md por padrão, a menos que você mude Project instructions para claude-md-and-agents-md no /config.

A configuração limpa é um AGENTS.md compartilhado, mais um CLAUDE.md que começa com @AGENTS.md só quando o Claude precisa de linhas que os outros agentes não devem ver. Esse import é tranquilo, porque você quer o arquivo inteiro em toda sessão. O guia de AGENTS.md tem a tabela completa de qual agente lê o quê.

Mantenha atualizado ou apague

Um CLAUDE.md errado é pior do que nenhum, porque o Claude segue com confiança. Mude o arquivo no mesmo pull request que muda a convenção. Trocou o banco de Prisma para Drizzle? A linha sobre Prisma morre naquele commit, e não três meses depois, quando o Claude escrever uma query em Prisma.

A cada poucas semanas, rode o /context, olhe o número e corte. O melhor CLAUDE.md que tenho é o deste site: um AGENTS.md curto na raiz e algumas rules em .claude/rules/ que só carregam para os arquivos que descrevem. O /context mostra a memória do projeto em 2.000 tokens. A da fintech era 69.800. Não está completo. É barato, e está certo.

CLAUDE.md, respostas rápidas

Onde fica o CLAUDE.md?

Para um projeto, na raiz do repo como CLAUDE.md ou em .claude/CLAUDE.md, versionado junto com o código. Para regras que valem em todos os seus projetos, em ~/.claude/CLAUDE.md. Para notas pessoais sobre um projeto, em CLAUDE.local.md na raiz do repo, adicionado ao .gitignore. Um CLAUDE.md dentro de uma subpasta só carrega quando o Claude trabalha em arquivos daquela pasta.

Qual deve ser o tamanho do CLAUDE.md?

A documentação da Anthropic recomenda ficar abaixo de 200 linhas por arquivo, porque arquivos mais longos ocupam mais contexto e reduzem a aderência.

Conte os imports também. Um arquivo de 124 linhas com vinte @imports não é um arquivo de 124 linhas. Rode /context para ver o tamanho real.

O Claude lê o CLAUDE.md toda vez?

Sim, no início de cada sessão, e ele fica no contexto durante a sessão inteira. Depois de /compact, o Claude Code relê do disco o CLAUDE.md da raiz do projeto. Arquivos CLAUDE.md em subpastas e rules com escopo de path só carregam quando o Claude lê ou edita um arquivo correspondente.

O CLAUDE.md pode importar outros arquivos?

Sim, com @caminho/do/arquivo. Arquivos importados carregam na inicialização, então custam o mesmo que colar o conteúdo, e podem se aninhar até quatro níveis. Para citar um caminho sem importar, coloque entre crases.

Por que o Claude está ignorando meu CLAUDE.md?

Primeiro confira se ele carregou: o /context lista cada arquivo de memória carregado na inicialização. Depois confira o tamanho e se dois arquivos se contradizem, porque o Claude pode escolher um arbitrariamente.

Se uma regra nunca pode ser quebrada, pare de pedir num arquivo. Use um hook PreToolUse ou um linter que bloqueie.

Como usar o CLAUDE.md num monorepo?

Deixe no arquivo da raiz as regras que todos os pacotes compartilham. Coloque as regras de cada pacote num CLAUDE.md dentro da pasta dele ou numa rule com escopo de path, para que só carreguem quando o Claude trabalha ali. Se arquivos de outras equipes carregam nas suas sessões, pule esses arquivos com claudeMdExcludes em .claude/settings.local.json.

Qual a diferença entre CLAUDE.md e CLAUDE.local.md?

O CLAUDE.md é da equipe e vai para o controle de versão. O CLAUDE.local.md é seu, fica ao lado dele e vai para o .gitignore. Os dois carregam na inicialização, e o local entra depois do compartilhado.

Devo commitar o CLAUDE.md?

Commite o CLAUDE.md do projeto. Ele descreve como trabalhar no código e deve mudar nos mesmos pull requests que mudam o código. Deixe o que é pessoal no CLAUDE.local.md e o que é segredo fora dos dois.