Quem trabalha sério com Claude Code chega à mesma receita para dar memória ao agente: manter um lessons_learned.md bem cuidado e reler antes de começar. A receita tem um pedaço verdadeiro. Sem escrever nada, não existe o que recuperar depois; nenhum truque de busca inventa uma lição que ninguém anotou.
Só que escrever é a parte fácil. O gargalo aparece depois que a lição está no arquivo. Tenho vários projetos acumulando lições há meses, cada um com o próprio arquivo, e cada sessão nova do agente começa do zero: só sabe o que alguém mandou reler. Se eu esqueço de apontar o arquivo certo, ou se a lição relevante está no arquivo de outro projeto, ela não existe para aquela sessão. Foi escrita, foi revisada, entrou no commit — e não existe.
A lição não passa a existir na hora em que eu escrevo. Passa a existir na hora em que volta sem eu chamar.
Esse é o critério que uso para dizer se um sistema tem memória ou só tem arquivos. Foi construindo o meu, o MemSearch, dentro do Project_Setup, um projeto interno, que descobri quanto a segunda parte custa mais que a primeira.
Na dúvida, a lição entra como candidata
Toda lição minha segue o mesmo formato de quatro seções: Contexto, O que aconteceu, Insight, Impacto. Mais uma etiqueta de escopo no título: [scope: universal], [scope: domain], [scope: project] ou [scope: candidate]. O formato importa menos do que parece; a etiqueta, mais, porque é ela que decide em qual sessão a lição vai reaparecer.
Os nomes de domínio vivem num vocabulário controlado, em snake_case, e só entram ou saem numa passada semanal dedicada. Nenhum agente inventa categoria na hora. O motivo é prosaico: se um agente escreve api, outro apis e um terceiro rest_api, três lições que deveriam aparecer juntas nunca aparecem. Para a busca, são três strings diferentes. E vocabulário fragmentado não parece bug; parece que a memória "não achou nada".
Por isso candidate é o default quando estou em dúvida. Uma lição candidata entra no índice e fica esperando revisão; uma lição sem etiqueta, ou com etiqueta improvisada, fica fora da busca para sempre. Entre errar a categoria e não ter categoria, errar é recuperável.
Um hook etiqueta e reindexa sem ninguém pedir
Eu não confio na minha disciplina para etiquetar toda lição. Confio num hook. Depois de qualquer edição num arquivo de lições ou de narrativa, ele roda sozinho. Acrescenta [scope: candidate] em qualquer título sem etiqueta e dispara a reindexação incremental do banco de memória. Quando os vizinhos semânticos da lição nova concordam entre si sobre um domínio, ele ainda sugere esse escopo mais específico.
O detalhe que importa é o "sozinho". Sem o hook, uma lição escrita às pressas no fim da sessão fica sem etiqueta, sem índice, invisível. Continua no arquivo, e o arquivo continua dando a sensação de que a memória está lá. O hook fecha essa distância entre "está escrito" e "está no índice" no momento em que o arquivo é salvo.
A busca acontece antes de o modelo responder
O que faz o sistema merecer o nome é a recuperação. Cada prompt que eu digito é transformado em vetor por um modelo de embedding local, rodando via Ollama, e comparado com o banco de lições. O filtro de escopo decide quem participa: universal entra sempre; domain entra se o projeto atual declarou aquele domínio; project entra se a lição é da mesma base de código. Candidatas não entram sozinhas: ficam esperando a revisão semanal. As três lições mais próximas viram contexto adicional antes de o modelo responder. Eu não peço nada. A lição chega.
Foi aí que apareceu o bug mais instrutivo do projeto. Prompts curtos, tipo "sim", "ok", "aprova tudo", também viram vetor, e um vetor de duas palavras acha vizinhos em qualquer lugar. As lições injetadas tinham uma distância entre 0,35 e 0,42, bem abaixo do limiar de 0,7 que eu usava. Um "ok" puxava três lições sem nada a ver com a tarefa. A correção teve duas partes: exigir no mínimo 5 palavras no prompt antes de buscar, e apertar o limiar para 0,45. Menos injeções por sessão, e nenhuma disparada por um "ok".
LEIA TAMBÉM · Caso realO que faz uma lição atravessar de um projeto para outro é a retratação escrita, não a ferramentaTenho vários sistemas que aprendem separados uns dos outros. Abro uma conversa com a IA e peço que ela leia todos e compare. O que encontra vira lista de tarefas — e quando erra, o erro fica escrito ali também.O índice de memória não é o conteúdo
Cada projeto meu tem um arquivo curto de memória, carregado em toda sessão nova: uma linha por tópico, cada linha apontando para um arquivo maior. O conteúdo pesado (arquitetura, histórico, estado atual) mora nos arquivos linkados e só entra quando alguém referencia. No índice, são proibidos: seções de status com vários parágrafos, listas densas, descrições de arquitetura, tabelas. Passou de 150 linhas, um aviso dispara.
Recomendo esse formato, e ele cobra disciplina o tempo todo. A tentação de colar o conteúdo direto no índice é constante: é mais rápido, "é só dessa vez". Ninguém sente esse custo sessão a sessão. Ele só aparece meses depois, quando o índice inchou e cada sessão nova paga por parágrafos que nunca vai usar.
O mesmo princípio me pegou em outra camada. O arquivo inteiro de vocabulário de domínio, quase 9 KB, estava sendo carregado por completo em toda sessão nova. Troquei por um cartão resumido só com os nomes de domínio: cerca de 2.140 tokens a menos por sessão. Material de referência que já é buscado sob demanda, na hora em que faz falta, não tem por que ficar residente no início de toda sessão também.
LEIA TAMBÉM · OpiniãoO CLAUDE.md global e o de projeto respondem a perguntas diferentesO Claude Code lê um arquivo de regras no começo de cada sessão. Existe um arquivo que vale para todos os seus projetos e um por projeto. Colocar a regra no arquivo errado faz você corrigir a mesma coisa muitas vezes.Uma lição só existe quando volta sem ser chamada
O teste é simples de aplicar e difícil de passar: uma lição existe de verdade quando reaparece numa sessão em que eu não estava pensando nela. Se a única forma de uma lição chegar ao agente é alguém reler o arquivo inteiro de cabo a rabo, o sistema de memória ainda não existe. Existe um arquivo.
Posso estar errado sobre o caminho, não sobre o critério. Se alguém mantiver contexto correto entre sessões e entre projetos sem taxonomia, sem hook de etiqueta automática e sem filtro de escopo, a minha tese cai e eu simplifico o sistema com prazer. Não foi o que aconteceu aqui.
