Claude Code em monorepo: como não estourar contexto em base grande
Em projeto pequeno qualquer agente brilha. Você abre o Claude Code numa pasta com 30 arquivos, pede uma feature, e ele entrega. Parece mágica. O problema é que projeto pequeno mente pra você. Ele esconde a única coisa que separa um agente de IA útil de um que se perde: o limite de contexto.
Em monorepo de 500 mil linhas é onde a engenharia de verdade aparece. O Claude Code não fica burro porque a base é grande. Ele fica burro porque você deixou o contexto encher de coisa que não tem nada a ver com a tarefa. E aí vem a alucinação, o arquivo errado editado, o "vou refatorar tudo" quando você pediu um fix de três linhas.
Se você ainda está se ambientando com a ferramenta, vale primeiro entender o que é o Claude Code e como ele funciona. Aqui a gente assume que você já usa e vai direto ao ponto: configurar o Claude Code para base grande e monorepo. Como escopar a sessão, como estruturar CLAUDE.md em camadas, quando jogar trabalho pra subagente, e o que fazer pra ele não se perder no meio de um milhão de linhas. Tudo com base na documentação oficial da Anthropic.
TL;DR
- O que é: estratégias de configuração e workflow pra usar Claude Code em monorepo e large codebase sem estourar o context window.
- Stack/Ferramenta: Claude Code (CLI),
CLAUDE.md, subagentes, plugins de code intelligence (LSP), git worktrees. - Custo/Acesso: requer assinatura do Claude Code; configuração toda em arquivos versionados no repo.
- Link útil: Set up Claude Code in a monorepo or large codebase (docs oficiais).
O contexto — por que monorepo quebra o agente?
O Claude Code funciona em qualquer tamanho de base. O detalhe é que os defaults dele são afinados pra projeto pequeno. À medida que a base cresce, esses mesmos defaults enchem o context window de instrução e leitura de arquivo que não têm relação nenhuma com a tarefa — gastando token e degradando a performance do modelo, segundo a própria Anthropic.
Pensa no que acontece. Você abre o Claude Code na raiz de um monorepo. Ele carrega o CLAUDE.md raiz, que alguém recheou com convenção de seis times diferentes. Você pede um ajuste no serviço de pagamento. Pra encontrar uma função, ele faz grep e volta com 2 mil matches. Lê dez arquivos pra achar a definição certa. Cada leitura é token. Cada token aproxima do limite.
E aqui está a parte que o pessoal não entende: o context window não é memória infinita. Mesmo com janela de 1 milhão de tokens, encher de ruído não deixa o modelo "mais informado". Deixa mais perdido. É o velho problema de context rot: quanto mais lixo no contexto, pior o sinal — e é mais ou menos assim que seu Claude Code trava em tarefas longas.
A boa notícia: dá pra resolver isso quase todo na configuração. Não é prompt mágico. É arquitetura de contexto.
Pré-requisitos
Antes de aplicar o que vem abaixo, você precisa de:
- [ ] Claude Code instalado e logado (CLI).
- [ ] Um monorepo ou base grande de verdade — o tutorial não faz sentido em projeto de 20 arquivos.
- [ ] Familiaridade com
CLAUDE.mde com a ideia de que o Claude Code lê arquivos de settings versionados (.claude/settings.json). - [ ] Para a parte de code intelligence: o language server da sua linguagem instalado na máquina (TypeScript, Python, Go, Rust e outros têm plugin oficial).
Mão na massa — escopando o Claude Code em base grande
Passo 1: comece a sessão no lugar certo
Essa é a decisão mais barata e mais ignorada. Onde você roda claude define o que entra no contexto.
Segundo a doc oficial, o comportamento é direto:
- Começou na raiz do repo: acesso a todos os arquivos, mas só o
CLAUDE.mdraiz carrega no início. Os de subpasta carregam sob demanda. - Começou numa subpasta (ex:
packages/api/): acesso só àquele subtree, e carrega oCLAUDE.mddaquela pasta mais o de todos os diretórios ancestrais.
Traduzindo pro dia a dia: se sua tarefa vive em packages/api/, abra o Claude Code lá dentro. Ele sobe a árvore pegando o contexto raiz que importa e ignora o CLAUDE.md do packages/web/ inteiro. Você não desperdiça um token com convenção de frontend numa tarefa de backend.
# Tarefa escopada no serviço de API
cd packages/api
claude
# Tarefa que atravessa vários pacotes
cd ~/monorepo
claude
Regra de bolso: comece na raiz só quando a tarefa realmente cruza pacotes. No resto, suba a partir da pasta da tarefa.
Passo 2: quebre o CLAUDE.md em camadas
Um CLAUDE.md único na raiz tem dois destinos, ambos ruins: ou ele cresce até cobrir a convenção de cada subsistema — e aí custa contexto em instrução que não vem ao caso — ou fica genérico demais pra ser útil.
A solução é layering. Um split de dois níveis resolve a maioria dos casos:
CLAUDE.mdraiz: o que vale em todo lugar. Padrão de código, convenção de commit, e o mapa do repositório.CLAUDE.mdpor subpasta: convenção específica daquela área. Em monorepo, um por pacote. Em base de árvore única, um por subsistema (src/db/,src/api/).
O raiz orienta o Claude sobre a estrutura:
This is a monorepo with three packages under packages/:
- packages/api: Node.js REST API with Express, TypeScript, and PostgreSQL
- packages/web: React frontend with Vite, TypeScript, and TailwindCSS
- packages/shared: shared TypeScript utilities used by both api and web
Run commands from the package directory, not the monorepo root.
E o packages/api/CLAUDE.md desce ao detalhe que só importa ali:
This package is the REST API server.
- Run tests: `npm test` (uses Vitest)
- Run dev server: `npm run dev` (port 3001)
- Database migrations: `npm run migrate`
API routes are in src/routes/. Database queries use Knex in src/db/.
Never write raw SQL strings in route handlers.
Detalhe de ouro que a doc recomenda e quase ninguém faz: revisite o CLAUDE.md depois de cada release grande de modelo. Uma regra que você escreveu pra contornar limitação de um modelo antigo — tipo "refatore um arquivo por vez" — vira puro overhead quando o modelo novo já dá conta sozinho. Instrução velha não é grátis. Ela ocupa contexto toda sessão.
Passo 3: corte a leitura de lixo
Instrução é só metade do problema. A outra metade é leitura de arquivo. E base grande tem muito arquivo que o Claude nunca deveria abrir.
As buscas do Claude já respeitam o .gitignore, então node_modules/, dist/ e build/ já ficam de fora. O que escapa é o que está versionado: SDK vendorizado, código gerado commitado. Pra isso, use Read deny rules no .claude/settings.json:
{
"permissions": {
"deny": [
"Read(./**/dist/**)",
"Read(./**/build/**)",
"Read(./**/*.generated.*)",
"Read(./vendor/**)"
]
}
}
E quando você nunca trabalha em certos pacotes — código de outro time, legado, subtree vendorizado — use claudeMdExcludes pra impedir até que aqueles CLAUDE.md carreguem:
{
"claudeMdExcludes": [
"**/packages/admin-dashboard/**",
"**/packages/legacy-*/**"
]
}
Passo 4: troque grep por code intelligence
Aqui mora um dos maiores ganhos de contexto em base grande. Achar onde um símbolo é definido ou usado, via texto, custa um monte de leitura de arquivo e chamadas de grep. Um plugin de code intelligence conecta o Claude a um language server (LSP) — ele pula direto pra definição e pras referências, em vez de varrer a árvore.
A diferença, nas palavras da própria Anthropic: o LSP "retorna só as referências que apontam pro mesmo símbolo, então a filtragem acontece antes do Claude ler qualquer coisa". Texto te dá milhares de matches irrelevantes. LSP te dá os certos.
/plugin install typescript-lsp@claude-plugins-official
Tem plugin oficial pra TypeScript, Python, Go, Rust e outras. Casa perfeitamente com os deny rules do passo anterior: um mantém o lixo fora do contexto, o outro evita que o Claude leia o resto inteiro só pra localizar uma definição.
Passo 5: jogue investigação pra subagente
Essa é a virada de chave mental. Nem tudo precisa estar na sua sessão principal.
Um subagente é uma instância isolada do Claude, com o próprio context window. Tarefas paralelas — rastrear como o serviço de auth lida com refresh de token, achar uma utility compartilhada, mapear um diretório — são ruído na sessão principal. Nenhuma delas precisa do contexto inteiro do projeto. Você manda o subagente investigar, ele volta só com o resumo, e as dez leituras de arquivo que ele fez nunca entram na sua conversa.
Dá até pra rodar vários em paralelo. No code review, por exemplo, você dispara um style-checker, um security-scanner e um test-coverage ao mesmo tempo — cada um no seu contexto, sem um poluir o outro.
A regra: trabalho exploratório, que gera muita leitura e pouco resultado final, vai pra subagente. A sessão principal fica limpa pro raciocínio que importa.
Limitações e pontos de atenção
Nenhuma config salva você de tudo. Onde dá ruim:
- Mudança que cruza pacotes. Quando uma edição toca vários pacotes — mudar um tipo compartilhado e todos os call sites — entregue a mudança inteira numa sessão só, pra manter a decisão consistente. E peça pro Claude salvar o plano num arquivo markdown antes de editar. Sessão longa compacta o contexto pelo caminho, e o plano salvo sobrevive onde o histórico da conversa pode sumir.
/compacté faca de dois gumes. Compactar destila a conversa num resumo. Bom pra continuar, mas compactação agressiva demais perde contexto sutil. OCLAUDE.mdraiz sobrevive; decisões antigas e preferências sutis podem ser truncadas.- Estrutura não-padrão confunde. Se a organização de diretórios é esquisita, escreva um mapa: um markdown leve listando as pastas de topo com uma linha de descrição. Vira índice navegável pro Claude.
- Não confie no agente pra rodar a suíte inteira. Em monorepo, rodar todos os testes num ajuste de um serviço dá timeout. Por isso o comando de teste mora no
CLAUDE.mdda subpasta, escopado.
FAQ rápido
Preciso indexar a base num vector DB pro Claude Code achar as coisas? Não. O Claude Code faz busca agêntica na base ao vivo, sem índice central. Isso evita o problema clássico de RAG sobre código: referência velha pra função renomeada ou módulo deletado. O índice nunca fica desatualizado porque não tem índice.
Devo rodar tudo da raiz do monorepo?
Só quando a tarefa cruza pacotes de verdade. Pra trabalho escopado num pacote, abra o Claude Code dentro dele — você carrega menos CLAUDE.md e dá menos acesso de leitura, o que mantém o contexto enxuto.
CLAUDE.md por pasta ou regras com path scoped?
Os dois miram parte da árvore. CLAUDE.md por pasta é melhor quando o dono do diretório mantém a própria convenção, versionada junto do código. Regras em .claude/rules/ com glob de paths: são melhores quando você quer tudo centralizado num lugar só.
E quando o layering de CLAUDE.md vira bagunça?
Quando convenção começa a divergir e ninguém é dono do raiz, mova o conteúdo de referência pra mecanismos que carregam sob demanda: skills, plugins versionados, ou um MCP server que exponha seu índice de busca. Tira peso do CLAUDE.md que carrega toda sessão.
Conclusão
Base grande não deixa o Claude Code burro. Configuração preguiçosa deixa. A diferença entre um agente que se perde em meio milhão de linhas e um que entrega é toda engenharia de contexto: começar a sessão no lugar certo, CLAUDE.md em camadas, cortar leitura de lixo, trocar grep por LSP e jogar investigação pra subagente. Nada disso é truque. É arquitetura.
E é exatamente essa a fronteira que separa "usar IA" de "construir produto com IA". Saber escopar contexto, isolar trabalho em subagentes e desenhar o harness em volta do modelo é o mesmo conjunto de decisões que sustenta um agente rodando em produção — é o que a gente coloca na mesa no workshop Do Prompt ao Harness: construindo um agente de vendas, indo do prompt inicial até o harness de um agente de vendas de verdade.
O próximo passo é parar de tratar o context window como detalhe e começar a tratá-lo como o recurso escasso que ele é. Quem domina isso não fica refém do tamanho da base — fica livre pra trabalhar em qualquer uma.
{AI Engineer} — apaixonado por Laravel, arquitetura de software e construir produtos com impacto. Compartilho aqui tutoriais, descobertas e reflexões sobre o dia a dia de engenharia.
Você também pode gostar
Subagentes na prática: dividindo contexto entre Claudes para não estourar o token budget
Padrão pesquisador, executor e validador na prática. Por que três Claudes especializados batem um agente gigante em qualidade e travam menos no limite de contexto. Com números reais publicados pela Anthropic.
Especificação mínima viável: o framework de 1 página que evita construir a Catedral antes da Cabana
Template proprietário de 1 página com objetivo, contexto, restrições, critérios de aceite e anti-escopo. Mostra quando expandir e quando NÃO expandir, e por que esse formato vira o melhor harness pra agente de IA executar sem alucinar feature paralela.
Claude Code hooks, slash commands e MCP: os três recursos que mudam seu fluxo
Guia prático dos três pontos de extensão do Claude Code — hooks, slash commands e MCP. Os arquivos de config exatos pra transformar o agente de autocomplete em parte do seu fluxo de engenharia.
Programmatic Tool Calling: por que executar suas ferramentas em código é o futuro do agente
Function calling clássico vai virar legado. Programmatic tool calling do Claude troca o loop turno-a-turno por código Python no sandbox: 37% menos tokens, paralelismo nativo via asyncio.gather e composição em um único script. A gente compara latência, tokens, debug, e fecha com um agente que escreve o próprio orquestrador.