Os três atos da memória: eu tentei duas arquiteturas antes da que funcionou

Foto: Brett Sayles via Pexels
Meu CLAUDE.md — o arquivo de regras permanentes que o Claude Code lê em toda sessão — tinha 225 palavras. Hoje tem 553. Ele mais que dobrou de tamanho — e o agente passou a errar menos.
No mesmo intervalo, minha memória de projeto (os arquivos que o agente lê pra saber como o sistema funciona) saiu de 103 arquivos num único escopo — tudo carregado sempre — para 106 arquivos fatiados: 59 que valem pra tudo e 47 trancados dentro de 12 projetos isolados. Repare: o total até cresceu. O que caiu foi o quanto disso entra em cada tarefa. Foram três arquiteturas em pouco mais de duas semanas — o repositório inteiro tem três semanas de vida, não anos de maturação. A segunda falhou, e é a mais interessante das três.
Agora a parte incômoda. Enquanto você lê isto, tem gente aparando o CLAUDE.md, cortando adjetivo, brigando para caber em uma tela, convencida de que instrução enxuta é instrução obedecida. Eu fiz exatamente isso. Por dias.
Eu escrevi um arquivo de regras maior e tive resultado melhor.
O tamanho da regra nunca foi o problema. O problema era o que chegava junto com ela. A IA não estava afogada em regra. Estava afogada em memória que não era da tarefa dela.
Ato 1: memória plana — "conforme o projeto cresce, a LLM vai ficando burra"
Essa frase é minha, e é a descrição mais honesta que consegui dar na época. Não era uma métrica. Era uma sensação de todo dia: o agente ia ficando pior à medida que o projeto ia ficando maior.
O baseline está num snapshot que eu tirei antes de mexer em qualquer coisa — um commit chamado f6b3927, que você não vai poder abrir porque o repo é meu e é fechado, mas que fixa a data do "antes" pra eu não reescrever a história depois. Ele registra o estado: 103 arquivos numa pasta de memória só, escopo único. 26 agentes num diretório plano. E nada decidindo o que entrava: tudo entrava. Tudo que o sistema sabia morava no mesmo lugar, e esse lugar só crescia.
A lógica parecia sólida: se a memória é boa e está toda documentada, o agente fica bom. Cada arquivo ali era útil. Nenhum era lixo.
Só que "útil" e "útil agora" são coisas diferentes — e eu levei uma arquitetura inteira pra entender isso.
Ato 2: memória central por índices — o ato que quase todo mundo está vivendo agora
A segunda tentativa foi a solução que a comunidade inteira aponta. Uma memória central, organizada por índices. Um INDEX.md apontando para os documentos certos, categorias limpas, hierarquia coerente. Carregamento sob demanda em vez de despejo.
E melhorou. Não vou fingir que não. Sair do caos plano para uma estrutura indexada é um ganho real, e se você está nesse degrau hoje, ele é melhor que o anterior.
Mas não era bom o suficiente para um projeto grande e complexo. E aqui está o ponto que eu quero mesmo entregar: essa arquitetura é onde quase todo mundo está agora, e a maioria acha que chegou. É o topo do conteúdo em português sobre o assunto. É o que os posts recomendam como estado da arte.
Eu passei por lá. Eu sei onde trinca.
Um índice reduz o que você procura. Ele não reduz o que entra. Quando o agente segue o índice e carrega os cinco documentos certos, esses cinco documentos entram no contexto e ficam lá — competindo por atenção com a tarefa real, turno após turno. O índice organizou a biblioteca. Não impediu que eu levasse a biblioteca inteira pra dentro da sala.
E, olhando pra trás, a v2 falhar foi a melhor coisa que aconteceu. Foi muito bom porque me fez buscar outra solução. Se o índice tivesse funcionado "quase bem" o bastante, eu teria parado ali — e passado os próximos seis meses refinando categorias em vez de questionar a premissa.
Por que o índice não bastou: não é sobre caber
A explicação técnica de por que o ato 2 trinca não é minha. É da pesquisa de context rot da Chroma — a empresa do banco vetorial de mesmo nome, que resolveu medir isso. Context rot é o termo que a comunidade usa para a degradação do modelo conforme o contexto cresce. Eles testaram 18 modelos, incluindo Claude 4, GPT-4.1, Gemini 2.5 e Qwen3, e a conclusão central é esta:
"models do not use their context uniformly; instead, their performance grows increasingly unreliable as input length grows."
Leia de novo devagar, porque a implicação é brutal. A degradação é função do comprimento da entrada — não de você bater num limite. Não existe uma linha onde tudo funciona de um lado e para de funcionar do outro. A confiabilidade vai se desfazendo conforme o contexto engorda, e isso acontece mesmo em tarefas simples.
Preciso ser chato com dois pontos aqui, porque é onde o nicho mente.
Primeiro: a janela de contexto não encolhe. Ela é fixa. Se você já leu que "a janela vai ficando menor conforme a conversa avança", isso está errado e a confusão importa — porque quem acha que o problema é espaço vai esperar a janela de 1 milhão de tokens resolver. Ela não resolve. Se fosse só espaço, janela maior seria a resposta.
Segundo: você vai encontrar blogs citando esse paper com "queda de 30%+" e "orçamento seguro de 150K–400K tokens". Esses números não estão no paper. Eu abri e conferi. São invenção de conteúdo de SEO citando um estudo que não leu.
Junte as duas coisas e o veredito sobre o ato 2 fica claro. O índice tenta ganhar um jogo de organização quando o jogo é de volume. Não é sobre caber. É sobre não estar lá.
Ato 3: macro no gerente, micro na memória
A terceira arquitetura nasceu no commit 4296eb4, em 14 de julho de 2026. A formulação que eu uso: eu gerencio o projeto no macro, mas a memória fica no micro. Isso facilita pra mim e facilita pra IA — pelo mesmo motivo.
Na prática, tem um roteador na frente de tudo. Antes de qualquer tarefa começar, roteador/route_projetos.py responde uma pergunta:
Qual é o menor pedaço do sistema que essa IA realmente precisa conhecer agora?
Só essa memória carrega. O resto deixa de existir para o modelo naquele momento — não fica indexado esperando, não fica "disponível se precisar". Não entra. As peças são auditáveis:
roteador/routes.json— os 12 micro-projetos, cada um com sua memória e seus agentes declarados. Nenhum sabe da existência do outro.roteador/route_hook.py— roda no evento UserPromptSubmit e reforça a rota a cada pedido. Hook é código seu que o harness executa em momentos determinados do ciclo, fora do modelo.roteador/session_start_hook.py— dispara no SessionStart e trava a rota antes do primeiro prompt existir.roteador/validate_routes.py— retorna 0 quando todo caminho declarado existe de fato. Integridade verificada por código, não por confiança.alianca/memory/decisions/0019-abstracao-micro-projetos-roteador.md— a decisão registrada como ADR, com o raciocínio inteiro.
E é por isso que o CLAUDE.md pôde crescer. Ele hoje carrega o que é macro: como rotear, como carregar memória, quais são os invariantes. Isso vale sempre, em todo turno, para toda tarefa. As 328 palavras que eu adicionei (de 225 pra 553) não competem com nada — porque o que competia com elas (a memória dos outros 11 projetos) não entra mais na sala.
O sistema errou hoje, e a trava pegou
Enquanto eu planejava este artigo, aconteceu o seguinte: o roteador escolheu o projeto errado no meio de uma conversa. Eu estava trabalhando no blog e ele apontou pra outro projeto.
Aí entrou a segunda camada: uma checagem burra que roda antes de cada edição e compara o arquivo que eu ia tocar com a rota que estava travada. Ela cuspiu, em português torto de log: "editando projetos/blog-seo mas a rota atual e projetos/carrossel-ia". Traduzindo: você disse que ia mexer numa coisa e está mexendo em outra.
Eu podia ter cortado essa cena do artigo. Não corto, por dois motivos. Primeiro porque é um sistema real, e sistema real erra. Segundo porque é exatamente o ponto: quem escolhe a rota é palpite e vai errar; quem confere é código determinístico e pegou. A arquitetura não presume acerto. Ela presume erro e coloca uma trava no caminho.
O que eu ainda não sei
Aqui eu preciso puxar o freio, senão este artigo vira o hype que ele critica.
Essa arquitetura tem dias de estrada. Ela nasceu em 14 de julho de 2026. Eu não tenho benchmark, não medi "X% menos alucinação", e não vou te dar número de resultado — porque o resultado mais importante não apareceu em benchmark, apareceu no comportamento. Se eu te desse um percentual aqui, ele seria inventado.
Então o que eu estou afirmando não é vitória. É decisão arquitetural + raciocínio, com o código na mesa pra você auditar. Declarar vitória com dias de uso seria repetir exatamente o erro que me fez perder tempo no ato 2: confundir "melhorou" com "resolvido". O follow-up vem depois — aí sim o experimento estará completo, com estrada suficiente pra afirmar alguma coisa.
Um limite honesto, aliás: escopo pequeno demais também tem custo. Se a tarefa precisa de contexto que o roteador não carregou, o agente trabalha cego. Fatiar não é grátis — é uma troca, e a fronteira certa ainda estou calibrando.
Perguntas frequentes
Se o CLAUDE.md pode crescer, então tamanho não importa mesmo? Importa, só que muito menos do que o nicho acha — e não é a variável que você deveria estar otimizando primeiro. O que importa é relevância por turno. 553 palavras que valem para toda tarefa custam menos que 200 palavras somadas a dezenas de milhares de tokens de memória de outro projeto entrando junto. Antes de cortar adjetivo do seu arquivo de regras, pergunte quanta memória irrelevante está entrando junto com ele.
Eu estou no ato 2 (memória central com índice). Preciso jogar fora? Não. O ato 2 é melhor que o ato 1 e a organização não se perde — ela vira a base do ato 3. A diferença é a pergunta que você faz. No índice: "onde está a informação certa?". No micro: "qual é o mínimo que essa tarefa precisa conhecer?". Se o seu projeto é pequeno, o índice pode ser suficiente pra sempre. A trinca aparece com escala e complexidade.
Isso não é só RAG com outro nome? Tem parentesco, mas a diferença é onde a decisão acontece. RAG normalmente busca por similaridade em tempo de execução, e o que volta é probabilístico. Aqui o escopo é declarado à mão em routes.json e verificado por validate_routes.py. Eu não pergunto "o que parece relevante?" — eu declaro "esta tarefa vive neste projeto". Menos flexível, e é esse o objetivo: eu quero errar de forma previsível.
Vale a complexidade pra um projeto solo? O roteador com 12 projetos, provavelmente não. Mas a inversão vale em qualquer tamanho, e ela é barata: pare de perguntar "o que o agente precisa saber sobre o projeto?" e comece a perguntar "o que ele precisa não saber agora?". Isso não exige framework. Exige uma pasta por escopo e a disciplina de não carregar o resto.
O placar, revisitado
225 palavras viraram 553. 103 arquivos num escopo único viraram 106 — três a mais, e o agente lê uma fração deles por vez: 59 globais e 47 espalhados por 12 projetos que se ignoram mutuamente.
O arquivo de regras cresceu 146% e o comportamento melhorou, porque essas duas coisas nunca estiveram na mesma equação. Eu passei duas arquiteturas tentando resolver no conteúdo um problema que era de escopo. O ato 1 me ensinou que memória boa não basta. O ato 2 — o que quase todo mundo chama de solução — me ensinou uma coisa mais cara: dá pra organizar perfeitamente a informação errada.
Se o modelo fica menos confiável conforme a entrada cresce, existem duas saídas: escrever melhor o que entra, ou fazer com que menos entre. Eu queimei duas arquiteturas na primeira.
A pergunta não era como escrever a regra perfeita. Era o que a IA precisa esquecer pra conseguir ler a regra que eu já tinha escrito.