Cada sessão começa do zero. O meu agente recebe um mapa
A minha IA começa cada sessão sem memória do repo. Este é o mapa de ficheiros que resolveu isso: quatro camadas, uma ordem de autoridade e custos medidos.
Um sistema de gestão de contexto é um conjunto de ficheiros de texto simples, versionados no repo, que põe nas mãos de um agente de IA acabado de arrancar um mapa: o que ler primeiro, onde vive a verdade atual, que decisões estão fechadas. O meu passou por várias reconstruções. Esta é a versão que sobreviveu, com os custos medidos incluídos.
O que é um sistema de gestão de contexto?
Um conjunto de ficheiros que diz ao agente onde olhar em vez de o obrigar a procurar: um ficheiro de instruções que cada sessão carrega sozinha, e que aponta para os poucos documentos que dizem o que é verdade neste momento, o que foi decidido e porquê, e onde vive o código de cada área.
A condição de partida que o justifica está escrita na própria documentação do Claude Code: “Cada sessão do Claude Code começa com uma janela de contexto nova” [1]. Cada sessão é um funcionário novo com amnésia. Capaz, mas que nunca viu o seu repo e nunca se vai lembrar de o ter visto.
A comparação a que volto sempre é o Google Maps. Quando peço uma alteração à faturação num repo mapeado, a primeira leitura encaminha o agente: o ficheiro de regras aponta para um índice, o índice tem uma linha para faturação, a linha nomeia dois documentos e uma pasta. Ele vai lá. Sem o mapa, faz grep, abre o que calhar a corresponder e monta a sua imagem do sistema a partir dos cinco ficheiros que por acaso viu primeiro.
Essa imagem é o produto. Tudo o que o agente fizer a seguir herda dela.
O que custa realmente uma sessão em branco?
Duas coisas: qualidade e tokens. Um agente que se orienta ao acaso das palavras-chave entende o sistema de forma demasiado superficial e entrega alterações plausíveis mas erradas. E a própria orientação queima a janela de contexto antes de o trabalho a sério começar, o que acaba por ser a metade mais cara.
O contexto não é um recurso plano que se gaste à vontade. A Chroma Research avaliou 18 modelos e concluiu que o desempenho degrada à medida que a entrada cresce, mesmo em tarefas que um prompt curto resolve sem esforço [2]. Drew Breunig catalogou os modos de falha: contextos que se envenenam com erros anteriores, que distraem o modelo para repetir ações passadas ou que se contradizem internamente; cita um estudo da Databricks em que a correção começa a cair por volta dos 32.000 tokens no Llama 3.1 405B, e agentes a degradarem-se para lá dos 100.000 tokens em modelos com janelas de um milhão [3]. A equipa de engenharia da Anthropic chama ao orçamento o seu nome verdadeiro, atenção: cada token gasto a orientar-se é atenção que o modelo já não tem para a alteração que lhe pediu [4].
O meu repo principal torna a aritmética concreta. O corpus de documentação são 418 ficheiros markdown, cerca de 7 MB de texto. Ler tudo custaria entre 5,7 e 8,75 vezes uma janela de contexto de 200.000 tokens, conforme o método de estimativa. Não cabe, e nenhum roadmap de modelos o faz caber com elegância. Portanto a pergunta nunca foi se o agente lê um subconjunto. É quem escolhe o subconjunto: o agente, ao acaso do grep, ou eu, por desenho.
Quatro camadas e uma frase
O sistema em que aterrei são quatro camadas de texto simples. Não tem nada de engenhoso, e depois de ver falhar as versões mais engenhosas (já lá vou), considero isso a vantagem.
AGENTS.md # the rules; auto-loaded (CLAUDE.md is a symlink to it)
docs/
STATE.md # current truth: live, in flight, not yet verified
INDEX.md # the router: which docs to read for which task
decisions/ # one numbered file per decision; superseded, never edited
sessions/ # history: what happened when, explicitly not authority
O ficheiro de regras é a porta de entrada porque é o único ficheiro que os agentes carregam sozinhos. O AGENTS.md é um padrão aberto usado por mais de 60.000 projetos open source [5]; o Claude Code lê antes o CLAUDE.md, e a documentação recomenda exatamente a ponte que eu uso, um symlink, junto com um alvo de tamanho abaixo das 200 linhas [1]. O meu passou as primeiras semanas como dois ficheiros separados, mantidos a partir de duas ferramentas diferentes, e as regras divergiram em silêncio até o symlink acabar com o problema por construção. Um ficheiro, todos os agentes, deriva impossível.
O snapshot é o que o ficheiro de regras manda ler primeiro em cada sessão: o que está em produção, o que está a meio e, o mais valioso na prática, o que explicitamente não está verificado. Um agente que sabe que algo não está verificado deixa de confiar nisso. Os registos de decisões seguem o padrão ADR, um ficheiro que captura uma única decisão e o seu raciocínio [6]; o meu repo acumulou 74 em oito semanas, e uma decisão nova substitui o ficheiro antigo em vez de o editar, por isso o rasto mantém-se honesto. O histórico é a pilha de logs de sessão, só de acrescentar, à qual é permitido ser enorme precisamente porque nada tem autorização para depender dela.
Uma única frase mantém as camadas unidas, repetida em cada porta de entrada do repo: o código ganha aos registos de decisões, os registos ganham ao snapshot, o snapshot ganha ao histórico. Essa ordem é o verdadeiro sistema. Uma pesquisa por palavra-chave num repo deste tamanho devolve cinco resultados de cinco épocas; a frase diz ao agente qual ganha e que os perdedores se corrigem ou se assinalam, nunca se acreditam em silêncio.
cada sessão
- AGENTS.md regras e ordem de leitura, carrega sozinho
o mapa
- STATE.md verdade atual, ler primeiro
- INDEX.md que documentos para esta tarefa
a tarefa
- Docs de área e código só o que a alteração toca
- decisions/ porque é que é assim
- sessions/ histórico, nunca autoridade
A camada de histórico exilada ganha a caixa mais pequena do diagrama com um número: os logs de sessão são 73% de todos os bytes de documentação daquele repo. Tire-os do cenário de ler tudo e o corpus restante cai de 8,75 janelas de contexto para cerca de 2,3. Declarar o histórico não autoritativo não é arrumação. É o que torna o resto navegável de todo.
O que impede o mapa de mentir?
Uma regra, acima de tudo: os docs fazem parte da alteração. Uma alteração que muda um facto de arquitetura atualiza o documento afetado no mesmo commit, não numa limpeza que nunca chega. O ficheiro de instruções do agente di-lo, e repete-o numa autoverificação no momento exato em que o agente decide que terminou, porque é quando as instruções têm a sua atenção de forma fiável.
Funciona melhor com máquinas do que alguma vez funcionou com humanos, por uma razão pouco lisonjeira: um agente executa mesmo a verificação prescrita. Quando alarguei a regra à documentação virada para o utilizador, a fração de commits que tocavam na UI e atualizavam os docs correspondentes no mesmo commit passou de 12,3% para 31,9%. Não é cumprimento total, mas é 2,6 vezes mais, e as falhas concentram-se onde nenhum agente foi dono da alteração de uma ponta à outra.
O segundo hábito é mais barato: o agente escreve um log de sessão curto e atualiza o snapshot antes de parar, por iniciativa própria, tratando “o utilizador passou para outra coisa” como sinal de fecho. Documentação que espera que alguém tenha vontade de documentar não sobrevive ao contacto com uma terça-feira qualquer.
Porquê não embeddings ou um servidor MCP de memória?
Porque foi isso que experimentei primeiro, e falhava sempre da mesma maneira: recuperar nunca foi o difícil, a frescura é que era. Um servidor MCP de memória com um índice vetorial à frente dos meus repos devolvia fielmente o tema certo do mês errado, e um embedding da arquitetura de março não tem como saber que o refactor de terça-feira o invalidou. Cada uma dessas montagens era também um segundo sistema cuja veracidade passava a ser eu a manter, que é exatamente a falha que o mapa existe para evitar. E em vários dos frameworks de memória open source que avaliei, a distância entre o que o README prometia e o que o código impunha era larga o suficiente para eu parar de avaliar.
O guia de context engineering da Anthropic aterrou onde eu aterrei: manter no contexto identificadores leves, caminhos de ficheiros e queries, e deixar o agente carregar o detalhe mesmo a tempo em vez de pré-calcular tudo o que possa vir a precisar [4]. Os ficheiros simples têm a propriedade que mais importa para essa estratégia: envelhecem à vista. Dá para lhes fazer grep, diff e revisão no mesmo pull request do código que descrevem. Um markdown desatualizado é, pelo menos, visivelmente desatualizado. Um índice de embeddings desatualizado engana com toda a confiança.
Os custos honestos, medidos
Em julho de 2026 fiz uma auditoria só de leitura ao aparato inteiro no meu repo principal, um monorepo de produção com cerca de 277.000 linhas de TypeScript trabalhado por três ferramentas de agente diferentes. Versão curta: a estrutura aguenta, a disciplina da prosa não.
- dos docs carregado automaticamente
- 0,22%
- um ficheiro de regras de 15,5 KB contra um corpus de 7 MB
- de uma janela 200K para ler tudo
- 8,75×
- 5,7× com a estimativa baseada em palavras
- crescimento do snapshot em 26 dias
- 9,5×
- de 75 linhas para 711, sem nunca encolher
O fosso entre os dois primeiros valores é o desenho inteiro: o agente parte de 0,22% e navega para fora. O terceiro valor é a falha permanente do desenho. O snapshot nasceu com o mandato de ser um ficheiro pequeno reescrito no sítio, e em vez disso cresceu 9,5 vezes em menos de um mês. Pior: à data da auditoria, a afirmação de cabeçalho estava falsa. Avisava que uma pilha de commits esperava push quando o push tinha acontecido dias antes. O ficheiro que cada sessão lê primeiro afirmava um facto desatualizado com toda a confiança.
Não foi a única mentira que a auditoria trouxe à superfície. Da primeira vez que sincronizei a documentação com o código, o doc do esquema afirmava 20 a 25 tabelas onde o código tinha 34, e a passagem apagou documentação de funcionalidades que nunca existiram. De 2.873 ligações relativas nos docs, 82 estavam partidas. E a minha regra tipográfica de estimação mantém-se com exatamente zero violações nas strings de UI, onde um teste a impõe, enquanto cerca de metade dos ficheiros de docs a quebra, onde nada a impõe. O padrão é limpo: uma regra em prosa apodrece na proporção da sua distância a um teste. As únicas partes deterministas do sistema inteiro são um symlink de nove bytes e o verificador de tipos. O registo de decisão que adotou a estrutura disse-o desde o início: “Isto reduz a taxa de falha, não a elimina”.
O problema que não resolvi é a dose. Demasiado pouco no mapa e o agente adivinha; demasiado e reconstruí a degradação de contexto longo daquela curva da Chroma com os meus próprios ficheiros [2]. Reafino o equilíbrio de poucas em poucas semanas, e espero fazê-lo para sempre.
A versão light que uso no trabalho
Tudo o que está acima é a minha montagem de projetos pessoais, e não a levaria a um empregador sem alterações. Em contextos profissionais, pela minha experiência, tanto aparato de agente lê-se como vibe coding, e as equipas que querem a IA como ferramenta de produtividade e não como autora autónoma têm pouco apetite por um repo que parece construído para a máquina. Justo ou não, a perceção faz parte da engenharia.
Por isso, no trabalho corro a mesma ideia disfarçada daquilo que também é, genuinamente: documentação bem feita. Uma porta de entrada clara, docs de área com nomes estáveis, um índice que diz o que vive onde. Ficheiros markdown que um colega novo agradeceria, e que de caminho funcionam como mapa para o agente.
| Camada | Projetos pessoais | No trabalho |
|---|---|---|
| Porta de entrada | AGENTS.md: regras, ordem de leitura, apontadores | um README que diz onde as coisas vivem |
| Verdade atual | STATE.md, reescrito no sítio | o quadro do sprint, fora do repo |
| Decisões | ADRs no repo, substituídos, nunca editados | reuniões; o repo regista os resultados |
| Histórico | logs de sessão, explicitamente não autoridade | o histórico do git e o sistema de tickets |
A separação tem uma causa estrutural, não apenas ótica. No trabalho, as decisões tomam-se fora do repo, em reuniões e no quadro, por isso uma camada do repo a reclamar autoridade sobre decisões mentiria por omissão desde o primeiro dia. Nos projetos pessoais não há fora: se uma decisão não fica escrita no repo, deixa de existir no momento em que a sessão acaba. A versão hardcore não é disciplina extra por gosto. É o que um repo precisa quando é o único sítio onde alguma coisa pode viver.
Por onde começaria
Um ficheiro de regras com menos de 200 linhas que fixe as convenções e a ordem de leitura; a documentação do Claude Code sugere acrescentar-lhe sempre que o agente comete o mesmo erro duas vezes [1], que é também o melhor gatilho de manutenção que conheço. Um ficheiro de estado para onde ele aponte. Um índice na semana em que os docs deixarem de caber num ecrã. Registos de decisões na primeira vez que o agente reabrir algo que você fechou há um mês, e uma pasta de histórico no dia em que quiser um registo sem querer confiar nele.
Depois, trate o mapa como código. Quando o agente erra da mesma forma duas vezes, o bug costuma estar no mapa, e a correção é uma frase no ficheiro certo. A última peça que escrevi defendia backends pequenos o suficiente para um agente os ter na cabeça. Isto é o mesmo argumento, apontado a tudo o que o código não consegue dizer sobre si próprio. O agente nunca vai deixar de começar do zero. O mapa é o que impede que isso saia caro.