Explicação 1 · Memória
Como nossos agentes de IA lembram
A versão curta. Um agente de IA esquece tudo quando a conversa termina. Por isso a gente dá a ele uma pasta de notas curtas, um fato por nota, e um índice de uma página que ele lê no início de toda sessão.
Quando ele aprende algo que vale guardar, como "essa pessoa gosta de respostas curtas", escreve uma nota. Na próxima sessão, já sabe.
O difícil é manter a pasta confiável. As notas ficam velhas, se repetem ou acabam erradas. Quase toda esta página é sobre isso.
Indo mais fundo
O formato de uma nota
Cada memória é um arquivo markdown próprio, com um pequeno bloco de frontmatter. O type é um destes quatro: user (quem é a pessoa e como ela trabalha), feedback (uma correção ou algo que funcionou), project (estado de um trabalho em andamento), reference (onde algo fica). O corpo diz qual é o fato, depois Por quê e Como aplicar. O porquê é o que mais importa. Uma regra sem o motivo acaba aplicada nos casos errados. Estes exemplos são inventados:
--- name: prefers-short-replies description: Keep replies to a few sentences unless asked type: feedback --- Keep replies short and lead with the answer. **Why:** Long answers got skimmed and the one question inside them was missed. **How to apply:** Put detail behind a link. For tone, see [[plain-words-over-polish]].
Os links cruzados usam [[name]], então uma nota pode apontar para as notas de que depende ou que contradiz.
O índice é a parte que importa
Um arquivo, MEMORY.md, é carregado em toda sessão, e esse carregamento tem um limite rígido. O harness de agente que usamos lê só as primeiras 200 linhas ou cerca de 25 KB e descarta o resto sem avisar. Tudo que passa do corte é como se não existisse. Por isso o índice fica curto de propósito: uma linha por memória, um link e algumas palavras sobre por que ela importa, com as regras que nunca podem ser perdidas logo no começo. Miramos um pouco abaixo do limite para que algumas adições não empurrem o final para fora.
Um segundo arquivo, um catálogo completo, lista todas as notas e não é carregado automaticamente. Ele existe para que nenhuma nota fique órfã, sem nada apontando para ela.
O que não guardar
- Qualquer coisa que o código ou o histórico do git já registra. Se dá para ler no repositório, ler lá é a melhor fonte.
- Um fato que já está salvo. Atualize a nota existente em vez de adicionar uma segunda.
- Notas que se mostram erradas. Apague ou corrija. Uma memória errada é pior do que nenhuma, porque o agente confia nela.
Lembrado não quer dizer atual
Uma memória é uma foto do dia em que foi escrita. Antes de agir com base em uma que cita um arquivo, um comando ou um estado do mundo, o agente confere se ainda é verdade. Uma nota dizendo "a configuração fica em X" é uma dica para ir olhar, não um fato para construir em cima.
As ferramentas que mantêm tudo saudável
O verificador. Um pequeno comando checa dois tipos de falha: o índice crescendo além do limite de carga e notas para as quais nenhum índice aponta. Ele pode reconstruir o catálogo completo a partir do frontmatter e sai com código diferente de zero em qualquer problema, então pode ficar em um hook ou em uma tarefa noturna.
A passada de consolidação. Com o tempo, uma pilha de notas apodrece de jeitos previsíveis. Um comando de consolidação encontra isso em etapas baratas:
- Ler cada nota.
- Achar referências mortas: caminhos, comandos e módulos que não existem mais, conferidos no sistema de arquivos real. Sem modelo envolvido, e ele pula o que não consegue resolver em vez de adivinhar.
- Indicar quase duplicatas com um índice simples de similaridade lexical. Ele só precisa de boa cobertura, porque a próxima etapa lê o texto de verdade.
- Indicar notas de incidentes isolados que nunca se generalizaram.
- Pedir a um modelo que leia cada indicação por inteiro e decida. "Não tenho certeza" é uma resposta permitida e deixa o par como está.
O comando é somente leitura. Ele escreve uma proposta para revisão e não muda nenhuma memória. Uma etapa de aplicação separada faz o trabalho, e é cautelosa por projeto. Roda em simulação por padrão, só executa uma fusão ou aposentadoria marcada por uma pessoa, move as notas aposentadas para uma pasta de espera em vez de apagá-las, tira um snapshot antes e pode desfazer a execução inteira. A etapa do modelo nunca roda a partir de uma tarefa agendada, só com uma pessoa acompanhando.
Há também uma checagem antes de escrever: ela lista quase duplicatas com a idade e a origem de cada uma, e recusa uma correspondência forte. É assim que "atualize em vez de duplicar" é aplicado em vez de apenas desejado.
O que dava errado antes de termos isso
Dois posts abaixo contam as histórias reais. Um é sobre um índice que perdeu em silêncio tudo depois da linha 200. O outro é sobre uma passada que não achou nenhuma duplicata porque as notas se contradiziam em vez de se repetirem.