Phase 14 - Lesson 09

Hybrid Memory: Vector + Graph + KV (Mem0)

Mem0 (Chhikara et al., 2025) trata la memoria como tres almacenamientos en paralelo — vectorial para similitud semántica, KV para búsqueda rápida de hechos y grafo para razonamiento de entidad-relación. Una capa de puntuación fusiona los tres al recuperar. Este es el estándar de producción de 2026 para memoria externa.

Tipo: Build Lenguajes: Python (stdlib) Prerrequisitos: Phase 14 · 07 (MemGPT), Phase 14 · 08 (Letta Blocks) Tiempo: ~75 minutos

Objetivos de Aprendizaje

  • Explicar por qué un solo almacenamiento (solo vectorial, solo grafo, solo KV) es insuficiente para la memoria del agente.
  • Nombrar los tres almacenamientos paralelos de Mem0 y lo que cada uno optimiza.
  • Describir la puntuación de fusión de Mem0 — relevancia, importancia, recencia — y por qué es una suma ponderada, no una jerarquía.
  • Implementar una memoria simple de tres almacenamientos en stdlib con un add() que escribe en los tres y un search() que fusiona los resultados.

El Problema

Un solo almacenamiento es incorrecto para una de tres clases de consulta:

  • Similitud semántica — "¿qué discutimos sobre agent drift la semana pasada?" El vectorial gana; KV y grafo fallan.
  • Búsqueda de hechos — "¿cuál es el número de teléfono del usuario?" El KV gana; el vectorial es un desperdicio, el grafo es exageración.
  • Razonamiento de relaciones — "¿qué clientes comparten la misma entidad de facturación?" El grafo gana; vectorial y KV no pueden responder.

Los agentes en producción emiten las tres clases en una sola sesión. Una memoria de almacenamiento único siempre estará errada para dos de ellas. La contribución de Mem0 es conectar las tres bajo una sola interfaz de add/search con una función de puntuación que las fusiona.

El Concepto

Tres almacenamientos en paralelo

Mem0 (arXiv:2504.19413, abril de 2025) en add(text, user_id, metadata):

  1. Extrae hechos candidatos a partir del texto (un paso impulsado por LLM).
  2. Escribe cada hecho en el almacenamiento vectorial (embedding) para búsqueda semántica.
  3. Escribe cada hecho en el almacenamiento KV indexado por (user_id, fact_type, entity) para búsqueda O(1).
  4. Escribe cada hecho en el almacenamiento de grafo (Mem0g) como aristas con tipo para consultas de relaciones.

En search(query, user_id):

  1. El almacenamiento vectorial devuelve los top-k por coseno de embedding.
  2. El almacenamiento KV devuelve coincidencias directas indexadas por la consulta derivada (user_id, type, entity).
  3. El almacenamiento de grafo devuelve el subgrafo alcanzable desde las entidades de la consulta.
  4. Una capa de puntuación fusiona los tres.

Puntuación de fusión

score = w_relevance * relevance(q, record)
      + w_importance * importance(record)
      + w_recency * recency(record)
  • Relevancia — coseno vectorial, coincidencia exacta de KV, peso de ruta en grafo.
  • Importancia — etiquetada al momento de la escritura o aprendida (algunos hechos importan más: nombres, IDs, políticas).
  • Recencia — decaimiento exponencial a lo largo del tiempo desde la última escritura o lectura.

Los pesos se ajustan por producto. Mayor w_recency para agentes de chat; mayor w_importance para agentes de cumplimiento (compliance); mayor w_relevance para agentes de búsqueda.

Mem0g y razonamiento temporal

Mem0g añade un detector de conflictos. Cuando un nuevo hecho contradice una arista existente, la arista existente se marca como inválida pero no se elimina. Las consultas temporales ("¿cuál era la ciudad del usuario en marzo?") recorren el subgrafo válido en ese momento.

Este es el comportamiento a nivel de cumplimiento que el patrón de invalidación de Letta generaliza.

Números de benchmark

El artículo de Mem0 reporta (2025):

  • LoCoMo (memoria de conversación larga): 91.6
  • LongMemEval (memoria episódica de largo horizonte): 93.4
  • BEAM 1M (benchmark de memoria de 1 millón de tokens): 64.1

Las líneas de base de comparación (LLM de contexto completo de 128k, almacenamiento vectorial plano, KV plano) pierden por 10+ puntos. Los benchmarks por si solos no justifican la elección —el diseño operativo sí—, pero los números muestran que el diseño de fusión no es un error de redondeo.

Taxonomía de alcance

Mem0 divide la memoria por alcance:

  • Memoria de usuario (User memory) — persiste entre sesiones, indexada en user_id.
  • Memoria de sesión (Session memory) — persiste dentro de un hilo de conversación.
  • Memoria de agente (Agent memory) — estado de la instancia por agente.

Cada escritura elige un alcance. La recuperación puede realizar consultas entre alcances con pesos por alcance. Mezclar alcances sin cuidado es la receta para incidentes del tipo "el asistente le contó a Alice sobre el proyecto de Bob".

Dónde este patrón falla

  • Desviación de embedding (Embedding drift). Los resultados vectoriales que parecen correctos en las primeras cien consultas se degradan a medida que el corpus crece. Añada re-embedding periódico de los top-N registros más usados.
  • Crecimiento desordenado del esquema KV (KV schema creep). (user_id, type, entity) parece simple hasta que cada equipo añade su propio type. Realice una auditoría del conjunto de tipos trimestralmente.
  • Explosión de grafo (Graph explosion). Un extractor ruidoso añade 50 aristas por mensaje. Limite las escrituras de grafo por llamada add; descarte las aristas de baja confianza.

Build It

code/main.py implementa el patrón de tres almacenamientos en la biblioteca estándar (stdlib):

  • VectorStore — similitud ingenua de superposición de tokens como un sustituto para embeddings.
  • KVStore — dict indexado por (user_id, fact_type, entity).
  • GraphStore — aristas con tipo (sujeto, relación, objeto, válido).
  • Mem0 — fachada de alto nivel con add(), search(), puntuación de fusión y recuperación consciente del alcance.
  • Una simulación paso a paso de una conversación con múltiples usuarios y sesiones.

Ejecútelo:

python3 code/main.py

La salida muestra tres rutas de recuperación separadas más los top-k fusionados. Cambie los pesos de puntuación en la parte superior de main() y observe cómo cambia la clasificación.

Use It

  • Mem0 (Apache 2.0) — listo para producción. Hospédelo por su cuenta con Postgres + Qdrant + Neo4j, o use la nube gestionada.
  • Letta — núcleo de tres niveles (core/recall/archival); traiga sus propios backends vectoriales y de grafos.
  • Zep — alternativa comercial con KG temporal y extracción de hechos.
  • Builds personalizados — para cuando necesita un control exacto sobre el extractor (cumplimiento) o pesos de fusión (agentes de voz donde predomina la recencia).

Ship It

outputs/skill-hybrid-memory.md genera una estructura de memoria de tres almacenamientos con un puntuador de fusión, taxonomía de alcance e invalidación temporal integrados.

Exercises

  1. Reemplace la similitud vectorial simulada con un modelo de embedding real (sentence-transformers, Ollama, OpenAI embeddings). Mida el recall@10 en una conversación larga sintética. ¿La clasificación sufre desviación a lo largo de 1000 escrituras?
  2. Añada una consulta temporal: search(query, as_of=timestamp). Devuelva solo los registros válidos en la fecha/hora especificada o antes de ella. ¿Qué almacenamiento requiere más trabajo?
  3. Implemente un detector de conflictos: si un hecho entrante contradice una arista del grafo, invalide la arista antigua y registre ambos. Pruebe con "usuario vive en Berlín" -> "usuario vive en Lisboa".
  4. Adapte el puntuador de fusión para incluir una dimensión de retroalimentación del usuario (user_feedback, ej. pulgar arriba en los registros recuperados). ¿Cómo evitar la manipulación (ej. que el agente solo devuelva registros que ya le gustaron)?
  5. Lea los documentos de Mem0 (docs.mem0.ai). Adapte la simulación para llamadas de cliente mem0. Compare la calidad de la recuperación en las mismas 20 consultas de prueba.

Key Terms

Term What people say What it actually means
Hybrid memory "Vector más grafo más KV" Tres almacenamientos escritos en paralelo, fusionados al recuperar
Fact extraction "Ingesta de memoria" Paso de LLM que divide el texto en tuplas (entidad, relación, hecho)
Fusion scoring "Clasificación de relevancia" Suma ponderada de relevancia, importancia y recencia
Scope "Namespace de memoria" user / session / agent — determina quién ve qué
Mem0g "Grafo de memoria" Aristas con tipo con validez temporal para consultas de relaciones
Temporal invalidation "Eliminación lógica (soft delete)" Marcar aristas contradichas como inválidas; nunca eliminar
Embedding drift "Rot de recuperación (retrieval rot)" La calidad del vector se degrada a medida que el corpus crece; re-embed periódicamente

Further Reading

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).