stamatios
← Voltar ao feed
Robô separa avalanche de post-its enviando extras à trituradora, curva de esquecimento para memória de agente
Agentes

Curva de esquecimento para agente complica mais do que ajuda

resumo de ~3 min

Uma curva de esquecimento construída de propósito

Jan Paul Dahlke, desenvolvedor do Eris - um agente local-first escrito em Rust que usa um cofre (vault) em Markdown como memória - conta no dev blog do projeto como implementou uma curva de esquecimento inspirada no rio Lethe da mitologia grega: o esquecimento como parte do design, não como falha. Ele rejeitava a ideia de despejar todo o histórico de chat na memória de longo prazo, que considera acumulação em vez de lembrança. O objetivo era modelar memória humana como comportamento real: itens revisitados sobem de pontuação, itens ignorados decaem.

A mecânica funcionava assim: cada memória em estágio carrega um promotion_score em ponto flutuante. Um processo em segundo plano roda a cada dois minutos, aplica decaimento à pontuação e move a entrada entre três níveis (Session, Scratch, Promote). Estágios explícitos via memory:stage dão um impulso maior; passar de um limiar sobe o nível e alonga o TTL; cair abaixo de metade do limiar rebaixa. Só entradas em Promote são gravadas no cofre pelo commit_all.

Onde o design quebrou

O autor admite que nunca olhou para uma pontuação do nível Scratch para tomar qualquer decisão. A intenção era um futuro modo de curadoria, em que o próprio agente, ocioso, caminhasse pela memória e decidisse o que manter, mesclar ou descartar. Esse leitor das pontuações nunca foi construído - os números rodam para um observador inexistente, com limiares definidos por puro achismo.

O problema prático maior: modelos locais pequenos lidam mal com o fluxo de múltiplos passos (stage, depois commit). O agente chamava commit_all, entradas abaixo de Promote eram silenciosamente puladas, e a chamada parecia bem-sucedida sem nada chegar ao cofre. O agente repetia o processo, se confundia e gastava turnos. A escada, que deveria impedir lixo no cofre, na prática impedia o agente de concluir a tarefa.

O mecanismo de "menção" - que deveria simular relembrar - era apenas sobreposição de strings entre a mensagem do usuário e o canonical_key, sem embeddings. Falhava com sinônimos, referências indiretas ("commit isso", "igual antes") e paráfrases: a memória decaía justamente enquanto a conversa seguia sobre o assunto. O autor reconhece que já tinha nomic-embed no sistema, mas o excluiu da promoção deliberadamente, por determinismo.

Havia ainda uma exceção à própria regra de concorrência do projeto (sem estado mutável compartilhado entre threads): um AtomicBool compartilhado entre o daemon de snapshot e o orquestrador para suprimir decaimento durante os passos lentos do modelo. Para o autor, precisar dessa exceção já indicava design errado.

A inversão e o que ele propõe

A lição central é uma inversão: decidir menos na escrita, classificar mais na leitura. Na escrita, não dá para saber se algo importará em três semanas; embeddings respondem melhor a uma pergunta de leitura - dado o que o usuário acabou de dizer, o que do passado é relevante? O prefetch no início do turno já classificava a memória por similaridade sem usar os níveis, e funcionava.

Em vez de três níveis, o autor defende dois estados (Staged e Committed), commit explícito e ranking no momento da leitura, com o Markdown permanecendo a fonte da verdade - um arquivo binário de memória pode guardar o índice derivado, mas nunca ser a fonte. A lista de exclusão incluiria a escada, a pontuação, o decaimento, o AtomicBool e vários parâmetros de configuração.

Zettelkasten e a admissão de superengenharia

Um segundo projeto frustrado foi transformar o cofre num Zettelkasten à Luhmann, com grafos de notas linkadas - preparado, mas nunca realmente percorrido. Ambos os sonhos, curva de esquecimento e grafo, foram "memória humana, mas engenheirada", e pesaram sobre o agente antes mesmo do laço simples ficar confiável.

O autor admite ter feito superengenharia e não ter testado seriamente abordagens existentes como Memvid, Mempalace e a memória estilo wiki de Karpathy. A conclusão honesta: a mudança sã seria deletar a escada, mas ele não o fez - há um // TODO: kill the ladder no repositório, e a escada permanece "em liberdade condicional", porque Eris é um hobby e cada recurso novo (SQLite, sandbox, backend web) parece mais divertido que a limpeza. O esquecimento continua sendo bom design, afirma; o que estava errado era o lugar onde ele o colocou.