Una memoria que puede cambiar de opinión


El mes pasado tu cliente trasladó su base de datos de pedidos de Postgres a MariaDB. Se lo contaste al agente y lo apuntó. Este mes preguntas, de pasada, qué base de datos usa el servicio de pedidos, y responde Postgres sin dudar. Cuando vas a mirar, el hecho nuevo está ahí, el viejo sigue estando también, y nada en ninguno de los dos dice a cuál deberías creer. La parte difícil de una memoria nunca fue el almacenamiento. Es cambiar de opinión: el mundo se mueve, una nota resulta haber sido errónea, una afirmación deja de sostenerse, y «olvidar» no debería significar «el texto sigue sentado en el archivo».

El almacén local de hechos holographic ha pasado las últimas semanas rellenando justo esa mitad. Antes vivía dentro del árbol de Hermes como proveedor empaquetado; el 11 de octubre se mudó al repositorio de su mantenedor y empezó a distribuirse como plugin del catálogo, y el 13 de octubre se actualizó a la 0.13.0. Esa actualización trajo bastante más que un cambio de dirección.

De sobrescribir a revisar: cinco acciones

Hasta hace poco había más o menos dos cosas que se podían hacer con un hecho recordado: añadirlo, o borrarlo y volver a añadirlo. La segunda opción cambiaba el id del hecho sin avisar, así que cualquier cosa que apuntara a ese id se rompía. Ahora un hecho tiene su propia historia, y las acciones se reparten en cinco:

Acción Cuándo usarla Qué significa
change el mundo se movió (misma cosa, respuesta nueva) una versión nueva del mismo hecho; el id se mantiene
correct la nota era errónea cuando se escribió una corrección; el texto superado deja de aparecer
end ya no se sostiene, pero nunca fue errónea ciérralo, conserva la historia
revert quieres deshacer la última edición vuelves a la versión anterior
history quieres ver por qué ha pasado este hecho lista todas las versiones

La compatibilidad está resuelta: las grafías antiguas siguen funcionando. add supersedes se trata como change (y ya no cambia el id), update content como correct y remove como forget. Tus scripts actuales no necesitan reescribirse.

Preguntar «qué creíamos entonces»: as_of

Una vez que existe la historia, aparece una pregunta nueva: ¿quieres saber lo que es cierto ahora o lo que creías el 10 de septiembre? Las dos respuestas pueden diferir, y durante un incidente lo normal es que necesites la segunda.

Por eso la búsqueda y el listado aceptan un argumento as_of, como as_of: 2026-09-10. Responde solo con las versiones que valían en esa fecha y devuelve una lista aparte de undetermined para los hechos cuyo estado en esa fecha no se puede establecer. Un inicio desconocido se reporta como desconocido en lugar de inventarse, que es la parte que merece la pena destacar. La búsqueda por defecto sigue viendo solo hechos actuales: el texto histórico vive en su propia tabla e índice, así que nunca contamina los resultados del día a día.

Cada versión también registra dónde se escribió —plataforma, id de chat o de hilo, id de sesión, e id y nombre del autor del turno—. Los títulos de chat nunca se guardan, así que la procedencia no arrastra en silencio los nombres de tus grupos hasta la base de datos.

Olvidar de verdad

En muchos sistemas «borrar» levanta una bandera mientras el texto se queda en el archivo y en las copias de seguridad. forget va más lejos: se eliminan el hecho y todas sus versiones, se reconstruyen ambos índices de texto completo, la operación se ejecuta con secure_delete y después hace VACUUM y trunca el WAL, con el objetivo de que el texto salga del archivo, no solo de los resultados de la consulta.

Lo que queda es una lápida que guarda el id y un hash con clave, nunca el texto. Eso evita que la extracción automática resucite el hecho y permite que otras herramientas limpien sus propias copias por id. El coste merece decirse sin rodeos: esto no se puede deshacer.

Un bot, muchos grupos sin relación: scope: chat y scope: thread

Si tu bot está en varios grupos de clientes, meter todos los hechos en una sola base de datos es un riesgo. scope: chat da a cada conversación su propia base de datos; scope: thread afina un nivel más, por tema de foro. Ambos usan los ids de chat y de hilo que el núcleo ya pasa a los proveedores de memoria: sin cambios en el núcleo y sin lógica de enrutado propia.

Tres líneas de seguridad: credenciales, imágenes, texto no confiable

Un almacén de memoria tiene una superficie de riesgo fácil de pasar por alto: todo lo que guarda se inyecta en cada turno posterior. Por eso escribir no basta: el contenido también se revisa a la salida.

  • Las credenciales con valor nunca se guardan. Una palabra de credencial con su valor al lado (password hunter2, API key sk-…) se rechaza con un motivo; la palabra sola sigue siendo un hecho legítimo («uso un gestor de contraseñas»). La 0.13.0 amplió la ventana a tres palabras a la vez que recortaba las falsas alarmas: the token is 0.125 USD es un precio, no una contraseña.
  • Una imagen no es un hecho. La sintaxis de imagen de Markdown o HTML nunca se trata como un hecho, porque el cliente que la renderiza va a buscar esa dirección por su cuenta, y los datos pueden viajar en la ruta o en la cadena de consulta.
  • El recall vuelve a comprobar antes de inyectar. En la 0.13.0 un hecho se reexamina a la salida: el marcado con rol de chat o de llamada a herramienta, las frases con tono de instrucción, una credencial con su valor, los caracteres invisibles y las imágenes dejan un hecho fuera del recall, registrado una vez por proceso. Ojo: esto no borra nada; search, list y history siguen mostrándolo, porque tú lo pediste y tienes derecho a corregirlo u olvidarlo.

Una trampa que conviene conocer: escrituras desde cron

Si haces mantenimiento de la memoria con una programación —una limpieza nocturna, por ejemplo— había un bug que se mantuvo callado mucho tiempo: desde la 0.2.0, las escrituras en memoria desde un trabajo cron simplemente no surtían efecto. El núcleo pasa agent_context: "cron" y el plugin trataba cualquier contexto así como de solo lectura, de modo que tu trabajo de mantenimiento seguía reportando éxito mientras no guardaba nada. El plugin de consolidación nocturna es justo el tipo de cosa que se topa con esto.

Eso ya está separado: las llamadas explícitas a fact_store / fact_feedback desde cron vuelven a escribir (cron_writes, activado por defecto), mientras que las escrituras automáticas —extracción automática, espejado, recuentos de recall— siguen desactivadas ahí. Un script manual de limpieza puede hacer su trabajo sin acumular hechos en silencio y sin supervisión.

Sobre la mudanza: no tienes nada que hacer

Holographic vivía en el árbol del núcleo (plugins/memory/holographic/); desde el 11 de octubre es un plugin del catálogo mantenido por itpartypattaya. La buena noticia es que solo el código cambió de dirección:

  • el nombre del proveedor no cambia: memory.provider: holographic sigue funcionando;
  • la sección de configuración no cambia: sigue siendo plugins.hermes-memory-store;
  • la base de datos no cambia: sigue siendo $HERMES_HOME/memory_store.db, o el db_path que hayas puesto;
  • las herramientas no cambian.

La ruta de actualización es automática: hermes update instala el plugin del catálogo en cada home de perfil que nombre el proveedor, y si actualizas desde la app de escritorio, el agente lo instala y te lo dice la primera vez que arranca. Si la instalación no puede hacerse, no te quedas sin memoria en silencio: con security.allow_lazy_installs: false, sin conexión o con una instalación rechazada, el aviso nombra el comando exacto hermes plugins install holographic para ese perfil. Dos comandos confirman el estado:

hermes memory status
hermes plugins list

El flujo completo de instalación y cambio:

hermes plugins install holographic   # desde el catálogo de plugins
hermes memory setup                  # elige un proveedor de forma interactiva
# o configúralo directamente:
hermes config set memory.provider holographic

La mecánica de la mudanza coincide con lo que contamos en proveedores de memoria que salen del núcleo; la diferencia esta vez es lo que el plugin creció después. (Si instalaste la copia provisional de Nous Research desde su propio repositorio, hermes plugins update holographic te mueve a la entrada del catálogo y tus datos se quedan donde están.)

Cómo se compara

Opción Qué guarda Para qué va mejor
MEMORY.md / USER.md integrados preferencias y hechos que quieres cargados siempre todo el mundo (siempre activo)
holographic (esta entrada) un almacén local de hechos en SQLite con historial de versiones y puntuaciones de confianza totalmente local, cuando necesitas revisiones y borrado real
Memoria semántica (LanceDB) memoria de largo plazo recuperada por similitud vectorial recuperar por significado en lugar de por hecho
Consolidación nocturna (dreaming) corrobora hechos candidatos durante la noche y propone qué conservar ya mantienes un almacén de hechos y quieres que converja

El recall multilingüe también ha ganado terreno. El chino simplificado y el tradicional se reconocen entre sí, las variantes ortográficas del japonés coinciden, los compuestos alemanes se separan en ambos sentidos, las palabras rusas de la misma raíz vienen de un diccionario, y las formas de palabra en inglés, español, francés y portugués están cubiertas —datos de Open English Wordnet, jieba, SudachiDict, Wikidata Lexemes y DerivBase.Ru, bajo licencias CC BY 4.0, MIT, Apache-2.0 y CC0 respectivamente—. Los números del conjunto ciego del mantenedor: las preguntas en chino escritas en el otro sistema pasaron de un 33% a un 100% de recall, y las preguntas rusas de la misma raíz, de un 83% a un 92%. Esas cifras son mediciones del propio mantenedor: útiles, no dogma. Si quieres menos ruido, recall_indicator (activado por defecto) y auto_extract (desactivado por defecto) son los dos interruptores a los que recurrir; la confianza sube +0.05 con un comentario útil y baja −0.10 con uno inútil.

La versión corta

  • El mundo cambia y las notas resultan erróneas. Una memoria que puede revisarse a sí misma merece ese nombre: change / correct / end / revert conservan las versiones, y as_of te devuelve a lo que valía un día concreto.
  • Olvidar es una operación destructiva: cada versión, cada índice, cada resto en el archivo, dejando una lápida sin texto, y no se puede deshacer.
  • Volver a comprobar el contenido antes de inyectarlo es lo que hace que este almacén sea seguro de confiar: credenciales, imágenes y texto con tono imperativo nunca se cuelan en el siguiente turno sin que se note.
  • Si ya tienes holographic configurado, la actualización no te pide nada. Si no lo tienes, ahora es un plugin del catálogo y un solo comando lo instala.