Trabajo en varias máquinas y cambio de agente de código según la tarea. Cada uno de ellos llega a mis proyectos como un desconocido. El razonamiento del "martes pasado" desaparece cuando termina la sesión. Cada agente nuevo, en cada equipo nuevo, parte de cero.

A comienzos de este año, Software Forgets: Agent Traces Are the Memory planteó que los agentes de código ya producen el registro que seguimos perdiendo. Mientras buscan en una base de código, prueban enfoques, chocan con errores, leen documentación y cambian de rumbo, dejan atrás una crónica densa no solo de qué cambió, sino de por qué.

El diagnóstico es correcto, pero las trazas son apenas memoria potencial. Los registros de sesión de un agente siguen siendo un archivo muerto. No se puede llegar con un grep hasta "¿por qué dejamos atrás el analizador de streaming?" a lo largo de diez mil turnos. Para que un agente use esas trazas mientras trabaja, hacen falta indexación, recuperación, ranking y procedencia exacta.

Eso es lo que entrega funes. Es una capa de memoria durable para tus agentes (Claude Code, Codex, pi y Hermes). Se construye a partir de las sesiones que ya están en tu máquina, funciona de forma local y pasa a ser parte del flujo normal del agente con un solo comando. Cuando lo quieras, también puede viajar a un conjunto de datos de Hugging Face de tu propiedad, privado por defecto.

¿Cómo se agrega memoria al agente que ya usas?

Funes es un binario único. Su motor de inferencia por defecto no tiene dependencias de entorno de ejecución de aprendizaje automático, y tanto el embedding como el reordenamiento ocurren en tu máquina. Se instala así:

Código
curl -fsSL https://huggingface.co/buckets/huggingface/funes/resolve/install.sh | sh

Y luego se suma a un agente:

Código
funes add claude

Ese único comando add construye el primer índice, entrega al agente las herramientas recall y get, e instala la automatización que indexa cada turno completado. La indexación es incremental: las ejecuciones nuevas agregan turnos nuevos en vez de volver a procesar toda la historia. El contenido más antiguo y profundo puede completarse después, en pasos acotados.

Desde ahí, simplemente trabajas. Cuando una tarea toca una decisión, un fundamento o un hallazgo previo, el agente puede recurrir a recall por su cuenta. No necesitas recordar la sesión antigua ni pegar su contexto en la nueva.

Un agente de código recurre a funes por su cuenta, recuerda una decisión anterior y fundamenta su respuesta en la sesión recuperada
Un agente de código recurre a funes por su cuenta, recuerda una decisión anterior y fundamenta su respuesta en la sesión recuperada
Con funes agregado, el recuerdo ocurre dentro de la conversación. El agente busca en su memoria por iniciativa propia y nombra la sesión detrás de su respuesta.

recall devuelve el texto original, no un resumen, y muestra exactamente de dónde vino: el agente, la marca de tiempo, la sesión y el turno. Cada resultado incluye un comando get que abre el turno completo y su contexto circundante.

Por debajo, un único flujo determinista interpreta cada traza soportada hacia la misma forma de turnos y bloques, la fragmenta, la procesa con un modelo local fijado y la escribe en un conjunto de datos Lance local. Una consulta combina búsqueda vectorial y BM25, fusiona sus rankings, reordena los candidatos con un cross-encoder, los repondera por recencia y adjunta los fragmentos vecinos.

Ese diseño le da a funes tres propiedades importantes:

  • Una memoria a través de agentes distintos: Claude Code, Codex, pi y Hermes escriben todos hacia la misma forma. recall abarca sus historiales, y cada resultado dice qué agente lo produjo.
  • La evidencia cruda queda intacta: nada se destila en un hecho al momento de escribir. Un resultado siempre puede llevar de vuelta al turno que lo produjo.
  • recall es local por defecto: no se requiere cuenta ni repositorio en el Hub. Ningún modelo alojado procesa tus sesiones para indexarlas; el embedding y el reordenamiento corren en tu máquina, y tu agente de código hace el razonamiento.

Una memoria es un conjunto de datos, no un servicio

Para que una memoria siga tu trabajo, se enlaza una al agregar funes a un agente:

Código
funes add codex acme/funes-memory

El enlace publica ahí tu memoria actual. Funes luego la mantiene al día, indexando cada turno localmente y publicando en los límites de sesión. El agente recuerda desde ella durante todo el trabajo. Si corres el mismo comando en otra máquina, la memoria te sigue hasta allá.

Por debajo, la memoria local es un conjunto de datos Lance, y la memoria compartida es un conjunto de datos de Hugging Face (privado por defecto) de tu propiedad.

Antes de que algo llegue al Hub, las credenciales ya fueron censuradas durante la indexación. La publicación luego revisa cada fragmento otra vez y retiene cualquier cosa que todavía parezca un secreto. El escáner detrás de esto está documentado en SECURITY.md, incluyendo qué cubre y qué no.

Cuando un agente lee una memoria remota, funes cachea localmente los archivos del conjunto de datos, de modo que las consultas en caliente vuelven a la velocidad local. El Hub aporta la propiedad, el control de acceso, el versionado y la distribución que ya aporta para otros conjuntos de datos. Tu memoria no se convierte en una cuenta de un servicio de memoria aparte, y no la arriendas de vuelta a través de una API.

Preguntar primero, integrar después

recall está pensado para agentes. Cuando quieras hacerle tú una pregunta a una memoria, usa ask. Lee tu memoria local por defecto:

Código
funes ask claude
"qué decidimos sobre el analizador de streaming"

O apúntalo a una memoria compartida. Hugging Face publicó una memoria del desarrollo de funes, así que puedes preguntar por qué funes funciona como funciona sin crear una memoria propia:

Código
funes ask claude
"por qué funes es append-only"
 --memory huggingface/funes-memory
Consulta a la memoria publicada de funes sobre por qué es append-only; funes recupera las sesiones relevantes y un agente de código responde desde ellas
Consulta a la memoria publicada de funes sobre por qué es append-only; funes recupera las sesiones relevantes y un agente de código responde desde ellas
funes ask es el hermano de solo lectura y de una sola pregunta de funes add. Recupera los pasajes, se los entrega a un agente de código y devuelve una respuesta fundamentada que nombra sus fuentes. No instala una integración ni cambia la configuración persistente del agente.

Una falla de recuperación no se disimula. Si los pasajes no respaldan una respuesta, el agente lo dice. Puedes reformular la pregunta o agregar funes al agente para que busque en la memoria de forma iterativa durante el trabajo normal.

Cambiar de agente sin perder el hilo

Una memoria compartida no está atada al agente ni al modelo que la creó. Se puede empezar una tarea en Claude Code, continuarla en Codex la semana siguiente, y el segundo agente puede recordar el razonamiento del primero.

Claude Code elige un modelo de embedding y luego Codex recuerda esa decisión en una sesión distinta
Claude Code elige un modelo de embedding y luego Codex recuerda esa decisión en una sesión distinta

Claude toma una decisión, un gancho la indexa, Codex la recuerda en otra sesión. Los resultados más antiguos de la demostración son grabaciones previas del mismo experimento: una memoria de solo anexado también recordó los ensayos.

Esto importa en varios alcances distintos:

  • Entre tus máquinas: enlaza cada agente a una memoria y recupera el historial desde el equipo que estés usando.
  • Dentro de un equipo: el agente de una persona recién llegada puede recuperar meses de decisiones el primer día, incluidos los callejones sin salida y los fundamentos que nunca llegaron a una solicitud de incorporación de cambios.
  • Junto a un proyecto de código abierto: quien mantiene el proyecto puede publicar las sesiones detrás de una versión. Es como un CLAUDE.md consultable que guarda la historia de por qué el proyecto es como es, en vez de una página que alguien debe seguir reescribiendo.

Las memorias publicadas llevan una ficha de conjunto de datos y la etiqueta funes, lo que las hace reconocibles y descubribles en el Hub.

¿Cuánto ahorra frente a un traspaso escrito?

Una investigación larga infla la sesión hasta que cada turno cuesta más cargar el contexto que hacer el trabajo. Las respuestas habituales son dejar que el agente compacte y siga, o escribir un traspaso y empezar de nuevo. El recuerdo es una tercera vía, y Hugging Face las midió entre sí en el benchmark handoff-vs-recall: dos tareas cuya respuesta no puede reconstruirse sin el conocimiento previo de la sesión.

La compactación es lo que la mayoría de los agentes hace por defecto, y fue la única de las tres cuyo resultado se dividió: llegó en una tarea y nunca llegó en la otra. Donde falló, su resumen había aplanado los hallazgos que importaban. El recuerdo devuelve los pasajes mismos, así que un hallazgo no tiene que sobrevivir a una síntesis.

El recuerdo fue el más barato de los tres en ambas tareas: 8 veces más barato que un traspaso escrito en una y 4 veces en la otra.

Tokens ponderados por tarea exitosa para cinco canales en dos tareas, con el recuerdo como la barra más corta en ambas
Tokens ponderados por tarea exitosa para cinco canales en dos tareas, con el recuerdo como la barra más corta en ambas

El segmento más claro de cada barra es el cargo único por preparar el canal, el traspaso o la compactación, pagado antes de la primera pregunta y contado una sola vez. Una cruz marca un canal que nunca llega, y por eso no tiene costo por éxito.

Construido sobre código abierto

Funes inventa poco de esto. Se apoya en modelos de embedding de código abierto lo bastante buenos como para correr localmente, en los conjuntos de datos de solo anexado de Lance con escrituras incrementales baratas, y en el cacheo y la deduplicación de contenido del Hub. El trabajo está en encajarlos dentro de una memoria que un agente pueda usar de verdad.

"Pensar es olvidar diferencias, es generalizar, abstraer". Jorge Luis Borges, Funes el memorioso.

Funes es de código abierto y vive en github.com/huggingface/funes, a un comando de convertir ese registro en una memoria que el siguiente agente pueda leer.