Uma memória que consegue mudar de ideia


No mês passado o seu cliente migrou o banco de pedidos do Postgres para o MariaDB. Você contou ao agente, e ele anotou. Neste mês você pergunta, de passagem, qual banco o serviço de pedidos usa — e ele responde Postgres sem hesitar. Quando você vai olhar, o fato mais novo está lá, o mais antigo também continua lá, e nada em nenhum dos dois diz em qual deles você deveria acreditar. A parte difícil da memória nunca foi o armazenamento. É mudar de ideia: o mundo anda, uma nota se revela errada, uma afirmação deixa de valer — e “esquecer” não deveria significar “o texto ainda está parado no arquivo”.

O fact store local holographic passou as últimas semanas justamente completando essa metade. Ele costumava viver dentro da árvore do Hermes como um provider embarcado; em 11 de outubro ele se mudou para o repositório do próprio mantenedor e passou a ser distribuído como plugin de catálogo, e em 13 de outubro foi atualizado para a 0.13.0. Essa atualização trouxe mais do que uma mudança de endereço.

De sobrescrita a revisão: cinco ações

Até pouco tempo atrás, havia mais ou menos duas coisas que você podia fazer com um fato memorizado: adicionar um, ou apagá-lo e adicioná-lo de novo. A segunda opção mudava o id do fato sem avisar, então tudo que apontasse para aquele id quebrava. Agora um fato tem o seu próprio histórico, e as ações se dividem em cinco:

Ação Quando você usa O que significa
change o mundo andou (mesma coisa, resposta nova) uma nova versão do mesmo fato; o id permanece
correct a nota estava errada quando foi escrita uma correção; o texto substituído deixa de aparecer
end não vale mais, mas nunca esteve errado fecha, mantém o histórico
revert você quer desfazer a última edição volta à versão anterior
history você quer ver por tudo que esse fato passou lista cada versão

A compatibilidade está tratada: as grafias antigas continuam funcionando. add supersedes é tratado como change (e não muda mais o id), update content como correct, e remove como forget. Os seus scripts existentes não precisam ser reescritos.

Perguntando “o que achávamos naquela época”: as_of

Agora que existe histórico, surge uma pergunta nova: você quer saber o que é verdade agora, ou o que você acreditava em 10 de setembro? As duas respostas podem diferir, e durante um incidente normalmente é a segunda que você precisa.

A busca e a listagem, portanto, aceitam um argumento as_of como as_of: 2026-09-10. Ela responde apenas a partir das versões que valiam naquela data, e devolve uma lista separada undetermined para os fatos cujo estado naquela data não pode ser estabelecido. Um início desconhecido é reportado como desconhecido em vez de inventado, e é essa a parte que merece atenção. A busca padrão continua enxergando apenas fatos atuais: o texto histórico mora na sua própria tabela e no seu próprio índice, então nunca polui os resultados do dia a dia.

Cada versão também registra onde foi escrita — plataforma, id de chat ou thread, id de sessão, e id e nome do autor do turno. Títulos de chat nunca são armazenados, então a proveniência não arrasta os nomes dos seus grupos para dentro do banco sem avisar.

Esquecer de verdade

Em muitos sistemas, “apagar” vira uma flag enquanto o texto continua no arquivo e nos backups. O forget vai além: o fato e todas as suas versões são removidos, os dois índices de texto completo são reconstruídos, a operação roda com secure_delete e então faz VACUUM e trunca o WAL — a meta é que o texto saia do arquivo, não apenas das consultas.

O que permanece é uma tombstone guardando o id e um hash com chave, nunca o texto. Isso impede que a extração automática ressuscite o fato e permite que outras ferramentas limpem as suas próprias cópias por id. O custo merece ser dito com clareza: isso não pode ser desfeito.

Um bot, vários grupos sem relação: scope: chat e scope: thread

Se o seu bot está em vários grupos de clientes, enfiar todo fato em um único banco é um risco. scope: chat dá a cada conversa o seu próprio banco; scope: thread vai um nível mais fino, por tópico de fórum. Os dois usam os ids de chat e de thread que o core já passa para os providers de memória — sem mudanças no core e sem lógica de roteamento sua.

Três linhas de segurança: credenciais, imagens, texto não confiável

Um armazenamento de memória tem uma superfície de risco fácil de passar batido: tudo o que ele guarda é injetado em cada turno seguinte. Escrever, portanto, não basta — o conteúdo é verificado também na saída.

  • Credenciais com valor nunca são armazenadas. Uma palavra de credencial com o seu valor ao lado (password hunter2, API key sk-…) é recusada com um motivo; a palavra sozinha continua sendo um fato legítimo (“uso um gerenciador de senhas”). A 0.13.0 ampliou a janela para três palavras e ao mesmo tempo reduziu os falsos alarmes: the token is 0.125 USD é um preço, não uma senha.
  • Uma imagem não é um fato. Sintaxe de imagem em Markdown ou HTML nunca é tratada como fato, porque o cliente que a renderiza busca aquele endereço por conta própria, e dados podem viajar no caminho ou na query string.
  • A recall verifica de novo antes de injetar. Na 0.13.0 um fato é reexaminado na saída: markup de papel de chat ou de chamada de ferramenta, frases com cara de instrução, uma credencial com o seu valor, caracteres invisíveis e imagens mantêm um fato fora da recall, e isso é registrado uma vez por processo. Note que isso não apaga nada — search, list e history continuam mostrando o fato, porque você perguntou e tem o direito de corrigi-lo ou esquecê-lo.

Uma armadilha que vale conhecer: escritas vindas do cron

Se você roda a manutenção da memória em um agendamento — uma faxina noturna, digamos — havia um bug que ficou quieto por muito tempo: desde a 0.2.0, escritas de memória vindas de um job de cron simplesmente não tinham efeito. O core passa agent_context: "cron", e o plugin tratava todo contexto desse tipo como somente leitura, então o seu job de manutenção seguia reportando sucesso sem armazenar nada. O plugin de consolidação noturna é o tipo de coisa que esbarra nisso.

Isso agora está separado: chamadas explícitas de fact_store / fact_feedback vindas do cron voltam a escrever (cron_writes, ligado por padrão), enquanto escritas automáticas — extração automática, espelhamento, contagens de recall — permanecem desligadas ali. Um script de faxina manual consegue fazer o seu trabalho sem acumular fatos sem supervisão, na surdina.

Sobre a mudança: não há nada para você fazer

O holographic costumava viver na árvore do core (plugins/memory/holographic/); desde 11 de outubro ele é um plugin de catálogo mantido por itpartypattaya. A boa notícia é que só o código mudou de endereço:

  • o nome do provider não mudou — memory.provider: holographic continua funcionando;
  • a seção de configuração não mudou — continua plugins.hermes-memory-store;
  • o banco não mudou — continua $HERMES_HOME/memory_store.db, ou o db_path que você definir;
  • as ferramentas não mudaram.

O caminho de upgrade é automático: hermes update instala o plugin de catálogo para cada profile home que nomeia o provider, e se você atualiza pelo app desktop o agente instala e avisa na primeira vez que inicia. Se a instalação não puder acontecer, você não fica sem memória em silêncio — com security.allow_lazy_installs: false, offline, ou uma instalação recusada, o aviso nomeia o comando exato hermes plugins install holographic para aquele profile. Dois comandos confirmam o estado:

hermes memory status
hermes plugins list

O fluxo completo de instalação e troca:

hermes plugins install holographic   # do catálogo de plugins
hermes memory setup                  # escolha um provider de forma interativa
# ou defina diretamente:
hermes config set memory.provider holographic

A mecânica da mudança bate com o que escrevemos em providers de memória saindo do core; a diferença desta vez é o que o plugin ganhou depois. (Se você instalou a cópia interina da Nous Research a partir do repositório dela, hermes plugins update holographic te move para a entrada do catálogo e os seus dados ficam onde estão.)

Como se compara

Opção O que armazena Melhor para
MEMORY.md / USER.md embutidos preferências e fatos que você sempre quer carregados todo mundo (sempre ativos)
holographic (este post) um fact store SQLite local com histórico de versões e scores de confiança totalmente local, quando você precisa de revisões e exclusão de verdade
Memória semântica (LanceDB) memória de longo prazo recuperada por similaridade vetorial recall por significado, e não por fato
Consolidação noturna (dreaming) corrobora fatos candidatos durante a noite e propõe o que manter você já mantém um fact store e quer que ele convirja

A recall multilíngue também ganhou terreno. Chinês simplificado e tradicional passam a se reconhecer mutuamente, variantes ortográficas do japonês se combinam, compostos do alemão se separam nos dois sentidos, palavras russas da mesma raiz vêm de um dicionário, e formas de palavras em inglês, espanhol, francês e português estão cobertas — dados do Open English Wordnet, jieba, SudachiDict, Wikidata Lexemes e DerivBase.Ru, sob as licenças CC BY 4.0, MIT, Apache-2.0 e CC0, respectivamente. Os números do conjunto cego do mantenedor: perguntas em chinês escritas no outro alfabeto passaram de 33% para 100% de recall, e perguntas russas da mesma raiz de 83% para 92%. Esses números são medições do próprio mantenedor — úteis, não dogma. Se você quer menos ruído, recall_indicator (ligado por padrão) e auto_extract (desligado por padrão) são os dois interruptores a procurar; a confiança sobe +0,05 para feedback útil e cai −0,10 para feedback inútil.

A versão curta

  • O mundo muda e as notas se revelam erradas. Uma memória que consegue se revisar merece o nome: change / correct / end / revert guardam as versões, e as_of te leva de volta ao que valia em um dia específico.
  • Esquecer é uma operação destrutiva: cada versão, cada índice, cada sobra no arquivo, deixando apenas uma tombstone sem texto — e não pode ser desfeita.
  • Reverificar o conteúdo antes de injetar é o que torna este armazenamento confiável o suficiente para se confiar: credenciais, imagens e texto com cara de ordem nunca entram no próximo turno sem ser notados.
  • Se o holographic já está configurado, a atualização não pede nada de você. Se não está, ele agora é um plugin de catálogo e um comando o instala.