memory-v2

Servidor MCP de memoria persistente inspirado en el cerebro con búsqueda híbrida BM25+vectorial, puntuación de activación ACT-R, decaimiento FadeMem y grafos de conocimiento — 17 herramientas, completamente local mediante Ollama, cero claves API.

Documentación

memory-v2
Memoria Persistente Inspirada en el Cerebro para Asistentes de Codificación de IA

MIT License Python 3.9+ PyPI MCP Tools


¿Por qué memory-v2?

pip install memory-v2-hx

La mayoría de los sistemas de memoria para IA son solo bases de datos con una API de búsqueda. memory-v2 es una arquitectura cognitiva -- modela cómo funciona realmente la memoria humana.

Característicamemory-v2Archivo plano / CLAUDE.mdClaude-brainZep / Graphiti
BúsquedaHíbrido BM25 + vector (fusionado)Ninguno / grepPalabra clave FTS5 (automático) + vector (manual)Vector + grafo
ClasificaciónActivación ACT-R (ciencia cognitiva)NingunoRango FTS5 * recenciaRecencia + similitud de embeddings
OlvidoDecaimiento FadeMem (promoción STM/LTM)Nunca olvida, se desbordaNunca olvidaCaducidad basada en TTL
Estructura de conocimientoGrafo (comunidades Leiden, PPR)Markdown planoTablas planasGrafo (Graphiti)
ConsolidaciónCompresión de 6 pasos CogCanvasManualNingunoNinguno
GobernanzaMemorias protegidas (inmunes al decaimiento)NingunoNingunoNinguno
Multi-agenteCadenas de autoridad, detección de conflictosNingunoNingunoNinguno
Privacidad100% local (Ollama, cero claves API)LocalLocalNube o autoalojado
Herramientas MCP170MCP de solo lecturaVaría

Ponte en marcha en 60 segundos:

# Install
pip install memory-v2

# Start the MCP server
memory-v2-server --db ~/memory.db

# Or add to Claude Code settings.json
{
  "mcpServers": {
    "memory": {
      "command": "memory-v2-server",
      "args": ["--db", "~/memory.db"]
    }
  }
}

Tu asistente de IA ahora tiene memoria persistente que sobrevive a las compactaciones, decae con gracia y construye un grafo de conocimiento mientras trabajas.


Resumen

memory-v2 es un sistema de memoria persistente con base cognitiva diseñado para asistentes de codificación de IA que operan en flujos de trabajo de larga duración y múltiples sesiones. Reemplaza el sistema de primera generación claude-memory con una reescritura desde cero que fusiona técnicas de psicología cognitiva (teoría de activación ACT-R, olvido por ley de potencia), recuperación de información (búsqueda híbrida BM25/vector con Fusión de Rango Recíproco) y representación de conocimiento basada en grafos (detección de comunidades Leiden, recuperación con PageRank Personalizado) en un único almacén respaldado por SQLite.

El sistema actúa como un servidor de Protocolo de Contexto de Modelo (MCP) que expone 17 herramientas, permitiendo que cualquier cliente de IA compatible con MCP -- Claude Code, Claude Desktop o agentes personalizados -- almacene, busque, decaiga, comprima y comparta memorias sin llamadas API externas. Toda la inferencia de embeddings y LLM se ejecuta localmente a través de Ollama, sin requerir claves API y sin transmitir datos fuera de la máquina.

memory-v2 fue construido por un profesional que ejecutó 59 ciclos de compactación en el sistema v1 y decidió que la arquitectura necesitaba ser repensada desde primeros principios. El resultado es un sistema donde las memorias compiten por sobrevivir mediante puntuaciones de activación, donde el contenido protegido está exento de decaimiento, donde múltiples agentes se coordinan a través de cadenas de autoridad, y donde un grafo de conocimiento descubre conexiones que el índice de búsqueda plano no puede.


Tabla de Contenidos


Descripción General de la Arquitectura

                          +-----------------------------+
                          |      MCP Client Layer       |
                          |  (Claude Code / Desktop /   |
                          |   any MCP-compatible agent)  |
                          +-------------+---------------+
                                        |
                              FastMCP Protocol (stdio)
                                        |
                          +-------------v---------------+
                          |     server.py (17 tools)     |
                          |  add | search | graph_search |
                          |  extract | compact | decay   |
                          |  agent_sync | check_integrity |
                          +---+-----+-----+-----+------+
                              |     |     |     |
              +---------------+     |     |     +---------------+
              |                     |     |                     |
   +----------v---------+   +------v-----v------+   +----------v---------+
   |     db.py           |   |   scoring.py      |   | knowledge_graph.py |
   | SQLite + sqlite-vec |   | ACT-R activation  |   | NetworkX DiGraph   |
   | + FTS5              |   | FadeMem decay     |   | Leiden communities |
   |                     |   | Cosine similarity |   | PPR retrieval      |
   | memories (rows)     |   |                   |   |                    |
   | memory_fts (BM25)   |   | base_level_act()  |   | extract_entities() |
   | memory_vec (768-d)  |   | spreading_act()   |   | detect_communities |
   | graveyard           |   | importance_score()|   | ppr_search()       |
   | agent_offsets       |   | decay_value()     |   | visualize_graph()  |
   | conflicts           |   | retrieval_prob()  |   |                    |
   | compaction_receipts |   |                   |   |                    |
   +----------+----------+   +-------------------+   +----------+---------+
              |                                                  |
              |              +-------------------+               |
              +--------------+  embeddings.py    +---------------+
                             | Ollama            |
                             | nomic-embed-text  |
                             | 768-dim vectors   |
                             | Local file cache  |
                             +-------------------+
                                      |
              +-----------------------+-----------------------+
              |                       |                       |
   +----------v---------+  +---------v----------+  +---------v----------+
   |  extraction.py     |  |  compaction.py     |  |  multi_agent.py    |
   | 2-pass LLM pipeline|  | CogCanvas 6-step   |  | Authority chain    |
   | Fact extraction     |  | Protected extract  |  | Consumer offsets   |
   | Novelty checking    |  | Selective deletion |  | Conflict detection |
   | Action decision     |  | Summary + verify   |  | Kafka-style sync   |
   +--------------------+  +--------------------+  +--------------------+
              |
   +----------v---------+  +--------------------+
   |  vault_indexer.py   |  |  security.py       |
   | Markdown chunking   |  | 13 credential pats |
   | SHA-256 delta detect|  | 6 injection pats   |
   | Frontmatter parsing |  | SHA-256 manifests  |
   | Incremental indexing|  | Allowlist filtering |
   +--------------------+  +--------------------+

La arquitectura sigue un diseño en capas donde el servidor MCP (server.py) actúa como el único punto de entrada para los clientes de IA. Las 17 herramientas delegan en subsistemas especializados. La capa de base de datos (db.py) posee el único archivo SQLite, que contiene tres índices co-ubicados: filas relacionales en memories, búsqueda de texto completo BM25 en memory_fts (FTS5) y embeddings vectoriales de 768 dimensiones en memory_vec (sqlite-vec). La capa de puntuación aplica fórmulas de activación cognitiva sobre los resultados de búsqueda. El grafo de conocimiento vive en un archivo pickle separado de NetworkX y proporciona descubrimiento de múltiples saltos que el índice plano no puede.

Cada llamada de embedding y LLM se enruta a través de Ollama, que se ejecuta localmente. El sistema nunca se comunica con el exterior.


Fundamentos Teóricos

Modelo de Activación ACT-R

El marco de Control Adaptativo del Pensamiento -- Racional (ACT-R), desarrollado por John Anderson y colegas en Carnegie Mellon, proporciona la teoría central de cómo las memorias compiten por la recuperación. La afirmación central es que la recuperación de la memoria humana es una adaptación racional a la estructura estadística del entorno: los elementos que se han utilizado recientemente y con frecuencia tienen más probabilidades de ser necesarios nuevamente (Anderson & Schooler, 1991).

memory-v2 implementa la ecuación de activación ACT-R como una superposición de puntuación sobre los resultados de búsqueda. Cada memoria tiene un valor de activación que determina su probabilidad de ser recuperada. La activación tiene tres componentes: activación de nivel base (con qué frecuencia y cuán recientemente se accedió a la memoria), activación propagada (preparación contextual de la consulta actual) y ruido (variación estocástica que evita el comportamiento determinista).

Activación de Nivel Base

La activación de nivel base aproxima el análisis racional completo utilizando la forma cerrada optimizada:

B_i = ln(n / (1 - d)) - d * ln(L)

Donde:

  • n = recuento total de accesos a la memoria
  • d = parámetro de decaimiento (fijado en 0.5, el valor canónico de ACT-R)
  • L = vida útil de la memoria en horas (tiempo desde su creación)

Esta aproximación evita almacenar el historial completo de accesos mientras preserva la propiedad clave: la activación aumenta con la frecuencia y disminuye con el tiempo, siguiendo una ley de potencia.

Activación Propagada

Las etiquetas de contexto de la consulta actual preparan las memorias asociadas:

S_i = SUM_j [ W_j * (S_max - ln(fan_j)) ]

Donde:

  • W_j = 1 / |context_tags| (peso de atención, dividido equitativamente entre las fuentes de contexto)
  • S_max = 1.6 (fuerza asociativa máxima)
  • fan_j = número de memorias que comparten la etiqueta j (el "abanico" de la fuente)

La idea clave: las etiquetas que aparecen en muchas memorias proporcionan menos activación (son menos discriminatorias), mientras que las etiquetas raras proporcionan más. Esto es el equivalente ACT-R de la ponderación IDF.

Ruido

La activación incluye un término de ruido estocástico extraído de la distribución logística:

epsilon ~ Logistic(0, s)       where s = 0.25

Generado como:

epsilon = s * ln(u / (1 - u))       where u ~ Uniform(0, 1)

Este ruido evita que el sistema se vuelva determinista y permite recuperaciones ocasionalmente sorprendentes, una propiedad que refleja la memoria humana.

Activación Completa y Probabilidad de Recuperación

La ecuación de activación completa:

A_i = B_i + S_i + epsilon

La probabilidad de recuperación exitosa dada la activación:

P(retrieve) = 1 / (1 + exp(-(A_i - tau) / s))

Donde:

  • tau = -0.5 (umbral de recuperación)
  • s = 0.25 (escala de ruido, igual que el parámetro de ruido)

Esta es una función sigmoide centrada en el umbral. Las memorias con activación muy por encima del umbral se recuperan casi con certeza; las memorias muy por debajo se olvidan casi con certeza.

Piso protegido: Las memorias marcadas como protegidas reciben un piso de activación de tau + 1.0 = 0.5, asegurando que siempre sean recuperables independientemente de la edad o el patrón de acceso.

Reordenamiento Final

Después de que la búsqueda híbrida produce una lista clasificada inicial, la activación ACT-R se utiliza para reordenar:

final_score = 0.6 * hybrid_rrf_score + 0.4 * (activation / 10.0)

La activación se divide por 10 para normalizarla en el mismo rango que la puntuación RRF (típicamente 0.0 a 0.03). La división 60/40 pondera la relevancia léxica+semántica por encima de la activación cognitiva, mientras aún permite que las memorias accedidas con frecuencia y preparadas contextualmente asciendan.


Sistema de Decaimiento FadeMem

Mientras que ACT-R maneja la competencia de recuperación en el momento de la consulta, FadeMem maneja el ciclo de vida de fondo de las memorias. Implementa una arquitectura de memoria de doble capa (Memoria a Corto Plazo y Memoria a Largo Plazo) con decaimiento de ley de potencia, promoción/democión basada en importancia y archivo.

Puntuación de Importancia

La importancia de cada memoria es una combinación ponderada de tres señales:

I(t) = 0.4 * relevance + 0.3 * frequency + 0.3 * recency

Donde:

  • relevance = puntuación de relevancia contextual (0.5 durante barridos de fondo cuando no hay contexto de consulta disponible)
  • frequency = log(access_count + 1) / log(max_access_count + 1) (frecuencia de acceso log-normalizada)
  • recency = exp(-decay_rate * hours_since_access) (decaimiento exponencial de recencia)

Los pesos (0.4, 0.3, 0.3) reflejan una elección de diseño: de qué trata una memoria importa ligeramente más que con qué frecuencia o cuán recientemente fue accedida.

Función de Decaimiento de Ley de Potencia

La función de decaimiento central:

v(t) = v(0) * exp(-lambda * t^beta)

Donde:

  • v(0) = fuerza inicial de la memoria
  • lambda = tasa de decaimiento por memoria (por defecto 0.1)
  • t = tiempo desde el último acceso en horas
  • beta = exponente dependiente de la capa:
    • beta_LTM = 0.8 (sub-lineal -- las memorias LTM decaen más lento que exponencial)
    • beta_STM = 1.2 (super-lineal -- las memorias STM decaen más rápido que exponencial)

El parámetro beta es la innovación clave sobre el decaimiento exponencial estándar. En beta < 1, la curva de decaimiento se dobla hacia arriba en relación con la exponencial, lo que significa que las memorias antiguas decaen más lentamente cuanto más viejas son: están "endurecidas" por el tiempo. En beta > 1, la curva se dobla hacia abajo, lo que significa que las memorias nuevas que no logran consolidarse decaen de manera acelerada.

Promoción y Democión de Doble Capa

Las memorias se mueven entre capas según umbrales de importancia:

Promotion:   STM --> LTM    when  importance >= 0.7
Demotion:    LTM --> STM    when  importance <= 0.3
Archive:     STM --> grave   when  importance < 0.1  AND  age > 30 days

La brecha entre 0.3 y 0.7 es una zona de histéresis: las memorias en este rango permanecen en su capa actual. Esto evita la oscilación en el límite.

Etiquetas Protegidas

Las memorias etiquetadas con cualquiera de las siguientes son inmunes al decaimiento y al archivo:

correction, decision, identity, emotional_anchor,
commitment, exact_value, chain_of_command, person

Estas representan categorías de información donde la pérdida sería perjudicial independientemente de la frecuencia de acceso.


Búsqueda Híbrida con Fusión de Rango Recíproco

memory-v2 ejecuta dos algoritmos de búsqueda independientes y los fusiona:

  1. Búsqueda de palabras clave BM25 mediante SQLite FTS5 -- sobresale en coincidencia exacta de términos, nombres de archivos, códigos de error
  2. Búsqueda de similitud vectorial mediante sqlite-vec (768-dim, distancia coseno) -- sobresale en similitud semántica

La fusión utiliza Fusión de Rango Recíproco (Cormack et al., 2009), que ha demostrado superar a los métodos de clasificación individuales y a la fusión de Condorcet:

score(d) = SUM_i [ 1 / (k + rank_i(d)) ]

Donde:

  • k = 60 (la constante RRF; valores más altos reducen la influencia de los resultados mejor clasificados)
  • rank_i(d) = posición del documento d en la i-ésima lista clasificada (indexada desde 0)
  • La suma se ejecuta sobre ambas listas de resultados BM25 y vectoriales Los documentos que aparecen en ambas listas reciben puntuación de ambas. Los documentos que aparecen solo en una lista reciben puntuación únicamente de esa lista (el otro término es 0). El resultado es una clasificación fusionada que captura tanto la precisión léxica como la amplitud semántica.

Cada búsqueda recupera limit * 3 candidatos antes de la fusión para garantizar una recuperación adecuada. Los resultados fusionados se pasan luego a la capa de puntuación ACT-R para la reclasificación final.


Grafo de Conocimiento y PageRank Personalizado

El grafo de conocimiento es un grafo dirigido de NetworkX (DiGraph) que representa entidades y relaciones extraídas de los documentos del vault. Proporciona una vía de recuperación complementaria: mientras que la búsqueda plana encuentra documentos que contienen palabras o vectores similares, el recorrido del grafo descubre conceptos estructuralmente relacionados incluso cuando no comparten similitud léxica ni de embeddings.

Esquema

10 tipos de nodos:

person, project, concept, decision, tool,
event, emotion, conversation, chunk, community

11 tipos de aristas:

discussed_in, decided, built, uses, part_of,
related_to, preceded_by, caused, felt, evolved_from, member_of

Las entidades se normalizan a minúsculas. Las aristas llevan peso (incrementado ante observación repetida), metadatos temporales (valid_from, valid_until), puntuaciones de confianza y procedencia del archivo fuente.

Extracción de Entidades

La extracción de entidades y relaciones utiliza un LLM local (por defecto: qwen2.5:3b vía Ollama) con un prompt estructurado que produce salida JSON. Se instruye al modelo para normalizar nombres, omitir relaciones triviales y usar formas canónicas. Se procesan los primeros 4000 caracteres de cada documento (respetando la ventana de contexto del modelo pequeño).

Detección de Comunidades Leiden

El grafo se particiona mediante el algoritmo de Leiden (Traag et al., 2019), que garantiza comunidades bien conectadas — una mejora sobre el método anterior de Louvain que podía producir comunidades arbitrariamente mal conectadas. La implementación usa python-igraph y leidenalg (dependencias opcionales).

Las asignaciones de comunidad se almacenan como atributos de nodo y se exponen a través de la herramienta MCP list_topics, proporcionando una agrupación automática de la base de conocimiento sin taxonomía manual.

Recuperación PPR Estilo HippoRAG

La herramienta graph_search implementa la recuperación con PageRank Personalizado (PPR) inspirada en HippoRAG (2024):

  1. Identificación de semillas: Extraer entidades de la consulta; emparejarlas con nodos del grafo por solapamiento de palabras. Si no hay coincidencia directa, recurrir a similitud de embeddings contra los nombres de los nodos.
  2. Vector de personalización: Construir una distribución uniforme sobre los nodos semilla (todos los demás reciben peso 0).
  3. Cálculo de PPR: nx.pagerank(G_undirected, alpha=0.85, personalization=p)
  4. Extracción de resultados: Devolver los K nodos principales por puntuación PPR, incluyendo membresía de comunidad, recuento de menciones y procedencia de la fuente.

La probabilidad de teletransporte alpha = 0.85 significa que el 85% del recorrido aleatorio sigue aristas y el 15% teletransporta de vuelta a los nodos semilla. Esto logra el equilibrio estándar entre exploración y relevancia.

La ventaja clave sobre la búsqueda plana: PPR descubre nodos alcanzables mediante recorridos de múltiples saltos desde las entidades de la consulta, incluso si esos nodos no comparten similitud de embeddings ni léxica con la consulta. Esto permite el razonamiento de tipo "¿qué más está conectado a esto?".


Esquema de Base de Datos

Todo el estado persistente (excepto el pickle del grafo de conocimiento) reside en un único archivo de base de datos SQLite.

Diagrama Entidad-Relación

erDiagram
    memories {
        INTEGER id PK
        TEXT content
        TEXT content_type
        TEXT source_file
        INTEGER source_line
        TEXT author
        INTEGER authority_level
        REAL confidence
        INTEGER protected
        TEXT tags
        TEXT created_at
        TEXT updated_at
        TEXT last_accessed_at
        INTEGER access_count
        REAL activation_score
        REAL importance_score
        REAL decay_rate
        INTEGER archived
        INTEGER supersedes FK
        TEXT content_hash
    }

    memory_fts {
        TEXT content
        TEXT tags
        TEXT source_file
    }

    memory_vec {
        INTEGER id PK
        BLOB embedding
    }

    graveyard {
        INTEGER id PK
        INTEGER memory_id FK
        TEXT content
        TEXT metadata
        TEXT archived_at
        TEXT reason
        REAL last_activation_score
    }

    agent_offsets {
        TEXT agent_id PK
        INTEGER last_read_line
        TEXT last_read_time
    }

    file_hashes {
        TEXT file_path PK
        TEXT content_hash
        TEXT indexed_at
        INTEGER chunk_count
    }

    conflicts {
        INTEGER id PK
        INTEGER memory_id_a FK
        INTEGER memory_id_b FK
        TEXT agent_a
        TEXT agent_b
        TEXT description
        INTEGER resolved
        TEXT resolved_by
        TEXT created_at
    }

    compaction_receipts {
        INTEGER id PK
        TEXT timestamp
        INTEGER original_tokens
        INTEGER compressed_tokens
        REAL ratio
        INTEGER protected_items_extracted
        REAL verification_score
        TEXT vault_files_updated
        TEXT receipt_data
    }

    memories ||--o{ graveyard : "archived to"
    memories ||--|| memory_fts : "FTS5 index"
    memories ||--|| memory_vec : "vector index"
    memories ||--o{ conflicts : "involved in"
    memories ||--o| memories : "supersedes"

Detalles de Tablas

TablaPropósitoEstrategia de Índices
memoriesAlmacenamiento principal. Una fila por memoria (o fragmento del vault).Árbol B sobre content_type, archived, protected, source_file, created_at, activation_score
memory_ftsTabla virtual FTS5 sobre content, tags, source_file. Sincronizada automáticamente mediante disparadores AFTER INSERT/UPDATE/DELETE.Índice invertido (BM25)
memory_vecTabla virtual vec0 que contiene embeddings float32 de 768 dimensiones. Una fila por memoria, clave por id.NN aproximado tipo HNSW (interno de sqlite-vec)
graveyardMemorias archivadas. Conserva el contenido completo y los metadatos para posible rehidratación.Ninguno (registro de auditoría de solo añadir)
agent_offsetsDesplazamientos de consumidor estilo Kafka. Cada agente rastrea su última posición leída en el changelog.Clave primaria en agent_id
file_hashesHashes SHA-256 para indexación incremental del vault. Omite archivos sin cambios al reindexar.Clave primaria en file_path
conflictsRegistro de contradicciones. Registra cuando dos agentes escriben memorias conflictivas.Escaneo secuencial (bajo volumen)
compaction_receiptsRastro de auditoría para cada ejecución de compactación. Almacena ratios, puntuaciones de verificación, recuentos de elementos protegidos.Escaneo secuencial

Configuración de SQLite

PRAGMA journal_mode = WAL;     -- Write-Ahead Logging for concurrent reads
PRAGMA foreign_keys = ON;      -- Enforce referential integrity

La extensión sqlite-vec se carga al momento de la conexión mediante sqlite_vec.load(conn). El archivo de base de datos está protegido por un tiempo de espera de 10 segundos para contención de bloqueos.


Servidor MCP y Herramientas

memory-v2 expone 17 herramientas a través del Model Context Protocol mediante FastMCP. El servidor se ejecuta sobre stdio (transporte MCP estándar) y puede registrarse con cualquier cliente compatible con MCP.

Referencia de Herramientas

Operaciones CRUD

HerramientaParámetrosDescripción
add_memorycontent, content_type?, tags?, source?, protected?, author?, confidence?Almacena una nueva memoria con embedding, verificación de novedad y escaneo de credenciales. Devuelve estado memory_id, novelty, importance, protected.
getmemory_idRecupera una única memoria por ID. Actualiza la marca de tiempo y el recuento de accesos (fortalecimiento por recuperación).
updatememory_id, content?, tags?, protected?Actualiza contenido, etiquetas o estado de protección. Re-embediza si el contenido cambia.
forgetmemory_id, reason?Archiva al cementerio. Las memorias protegidas no pueden olvidarse.

Operaciones de Búsqueda

HerramientaParámetrosDescripción
searchquery, limit?, content_type?Búsqueda híbrida BM25 + vectorial con fusión RRF y reclasificación ACT-R. La herramienta de búsqueda principal.
keyword_searchkeywords, limit?Búsqueda de palabras clave BM25 pura. Preferida para términos exactos, nombres de archivo, códigos de error.

Operaciones de Grafo

HerramientaParámetrosDescripción
graph_searchquery, top_k?Recorrido PageRank Personalizado. Descubre conceptos relacionados mediante recorrido de grafo de múltiples saltos.
graph_stats_tool(ninguno)Recuentos de nodos/aristas, distribuciones de tipos, entidades principales por recuento de menciones, densidad del grafo.

Operaciones de Sistema

HerramientaParámetrosDescripción
stats(ninguno)Recuentos totales de activos, archivados, protegidos, cementerio, archivos indexados, distribución de tipos.
list_recenthours?, limit?Memorias creadas recientemente, ordenadas por created_at descendente.
list_topicslimit?Clústeres de temas de comunidades Leiden (si el grafo está construido) o respaldo por estructura de archivos.
reindexforce?Reindexación incremental del vault. Solo procesa archivos cuyo hash SHA-256 cambió. force=True reconstruye todo.

Operaciones Avanzadas

HerramientaParámetrosDescripción
extract_from_conversationtext, source?, author?Pipeline LLM de dos pasadas: extraer hechos, luego decidir ADD/UPDATE/DELETE/NONE para cada uno.
compact_texttext, max_ratio?, verify?Compresión CogCanvas de 6 pasos con extracción de contenido protegido y verificación de fidelidad.
decay_sweep(ninguno)Mantenimiento en segundo plano FadeMem: actualizar puntuaciones de importancia, promover/degradar capas, archivar memorias muertas.
agent_syncagent_idSincronización de changelog estilo Kafka. Devuelve entradas no leídas y actualiza el desplazamiento del consumidor del agente.
check_conflicts(ninguno)Lista todos los conflictos de memoria entre agentes no resueltos.
check_integrity(ninguno)Verifica archivos del vault contra el manifiesto SHA-256. Reporta archivos modificados, nuevos y faltantes.

Inicialización del Servidor

Al iniciar, el servidor:

  1. Registra las 17 herramientas con FastMCP
  2. Lanza un hilo en segundo plano para precalentar el modelo de embeddings de Ollama (evita la penalización de arranque en frío de ~55 segundos en la primera consulta)
  3. Inicializa perezosamente la conexión SQLite en la primera llamada a una herramienta
  4. Se ejecuta sobre stdio con mcp.run(show_banner=False)

Referencia de Subsistemas

Capa de Embeddings

Archivo: src/memory_v2/embeddings.py

PropiedadValor
Modelonomic-embed-text (vía Ollama)
Dimensiones768
BackendInferencia local de Ollama
CachéCaché de archivos con clave SHA-256 en ~/.memory-v2/cache/
API por lotesembed_batch(texts: list[str]) para indexación del vault

La capa de embeddings es intencionalmente delgada: cuatro funciones (embed_text, embed_batch, embed_with_cache, get_client). La selección del modelo de embeddings es configurable mediante MEMORY_V2_EMBED_MODEL para usuarios que quieran intercambiar un modelo de Ollama diferente.

La función get_embedder() en __init__.py proporciona inicialización perezosa con una llamada de calentamiento desechable para evitar la latencia de arranque en frío en la primera consulta real.


Indexador del Vault

Archivo: src/memory_v2/vault_indexer.py

El indexador del vault convierte un directorio de archivos markdown en fragmentos de memoria buscables.

Estrategia de fragmentación:

  • Objetivo: 500 tokens por fragmento (~2000 caracteres a 4 caracteres/token)
  • Solapamiento: 50 tokens entre fragmentos consecutivos
  • Jerarquía de división: límites de párrafo primero, límites de oración para párrafos sobredimensionados
  • Extracción de frontmatter: metadatos YAML (type, tags, author) analizados y aplicados a los fragmentos

Indexación incremental:

  • El hash SHA-256 de cada archivo se almacena en file_hashes
  • Al reindexar, los archivos sin cambios se omiten por completo
  • Los archivos modificados tienen sus fragmentos antiguos eliminados antes de re-fragmentar
  • La bandera force=True omite la verificación de hash para reconstrucciones completas

Detección de tipo de contenido:

  • Derivada de la estructura de carpetas del vault: conversations/ -> episode, decisions/ -> decision, people/ -> person, origins/ -> identity
  • Anulable mediante el campo de frontmatter type:

Manejo del changelog:

  • changelog.md se indexa por separado (una memoria por entrada fechada)
  • Cada entrada que coincida con [YYYY-MM-DD] se convierte en una memoria de tipo episode
  • Se embediza por lotes para mayor eficiencia

Pipeline de Auto-Extracción

Archivo: src/memory_v2/extraction.py

El pipeline de extracción convierte texto de conversación no estructurado en memorias discretas y tipadas mediante un proceso LLM de dos pasadas.

Pasada 1 -- Extracción de Hechos:

El LLM local (qwen2.5:3b) recibe el texto de la conversación y un prompt estructurado dirigido a 7 categorías:

  1. Preferencias personales
  2. Detalles personales (nombres, relaciones, fechas)
  3. Planes e intenciones
  4. Detalles de proyectos (estado, arquitectura, decisiones)
  5. Especificaciones técnicas (rutas de archivo, puertos, configuraciones, errores)
  6. Correcciones
  7. Matices emocionales/relacionales

El prompt instruye explícitamente al modelo a extraer solo de los mensajes del usuario, producir declaraciones autocontenidas y omitir contenido trivial.

Pasada 2 -- Decisión de Acción de Memoria:

Para cada hecho extraído:

  1. Escaneo de credenciales: Bloquear almacenamiento si se detectan credenciales (13 patrones)
  2. Embedding: Generar vector de 768 dimensiones vía Ollama
  3. Verificación de novedad: Buscar memorias similares existentes
    • Similitud > 0.92: NONE (duplicado, omitir)
    • Similitud 0.75--0.92: Invocar LLM para decidir ADD, UPDATE o DELETE
  • Similitud < 0.75: ADD (suficientemente novedoso)
  1. Detección de tipo de contenido: Automatizada mediante heurísticas de palabras clave (correction, decision, episode, fact)
  2. Detección emocional: 20 palabras clave de emociones + 3 patrones de expresiones regulares; el contenido emocional se protege automáticamente
  3. Almacenamiento: Ejecutar la acción decidida con una puntuación de importancia adecuada

Canalización de Compactación CogCanvas

Archivo: src/memory_v2/compaction.py

Inspirada en el marco CogCanvas para la compresión cognitiva en agentes, esta canalización reduce texto verboso mientras preserva información crítica. Sigue un proceso de 6 pasos:

Paso 1 -- Pre-extraer contenido protegido: Escanea cada línea en busca de patrones protegidos (correcciones, decisiones, marcadores emocionales, valores exactos, compromisos, nombres configurados). Las líneas coincidentes se extraen textualmente y se apartan.

Paso 2 -- Eliminación selectiva: Elimina contenido prescindible: listas de URL numeradas, salida de comandos de shell, marcadores de información repetida ("como mencioné"), texto de relleno ("avísame si necesitas ayuda").

Paso 3 -- Resumen estructurado: Si el texto restante supera los 2000 caracteres, invoca el LLM local para resumir. El prompt preserva explícitamente afirmaciones fácticas, nombres, fechas, números, rutas de archivo y relaciones causales. El objetivo de compresión está limitado por max_ratio (predeterminado 3:1).

Paso 4 -- Verificación de fidelidad: Una segunda pasada del LLM compara el resumen con el original, verificando:

  • Alucinaciones (afirmaciones no presentes en el original)
  • Hechos faltantes (información importante omitida)
  • Puntuación general de fidelidad (0.0 a 1.0)

Si se detectan alucinaciones y la puntuación cae por debajo de 0.7, el sistema revierte a la salida solo con eliminación en lugar de confiar en el resumen infiel.

Paso 5 -- Generación de recibo: Cada compactación produce un recibo auditable: recuentos de tokens original/compactado, proporción de compresión, recuento de elementos protegidos, puntuación de verificación, recuento de alucinaciones.

Paso 6 -- Almacenamiento del recibo: Los recibos se persisten en la tabla compaction_receipts para análisis histórico.

Paso 7 (bonus) -- Rehidratación: La función rehydrate() puede intentar recuperar el contenido completo de la bóveda o del cementerio si la versión compactada es insuficiente.


Coordinación Multi-Agente

Archivo: src/memory_v2/multi_agent.py

memory-v2 admite que múltiples agentes de IA compartan una única base de memoria mediante tres mecanismos:

Cadena de Autoridad

Una jerarquía configurable determina quién puede sobrescribir a quién:

{
    "human": 1,           # Manual edits -- highest authority
    "primary_agent": 2,   # Primary AI agent (e.g., Claude Code)
    "coordinator": 3,     # Coordinating agent
    "worker": 4,          # Subordinate worker agent
    "indexer": 5,         # Automated vault indexer
    "extractor": 6,       # Automated fact extraction
}

Número más bajo = mayor autoridad. Cuando una escritura entra en conflicto con una memoria existente:

  • Mayor autoridad: sobrescribe la memoria existente
  • Autoridad igual o menor: registra un conflicto y almacena ambas versiones

La jerarquía se puede anular mediante la variable de entorno MEMORY_V2_AUTHORITY_CHAIN (formato JSON).

Desplazamientos de Consumidor Estilo Kafka

Cada agente tiene un desplazamiento de consumidor rastreado en la tabla agent_offsets. La herramienta agent_sync lee entradas de changelog no leídas y avanza el desplazamiento -- el mismo patrón utilizado por los grupos de consumidores de Apache Kafka, adaptado a un changelog basado en archivos.

Esto permite que los agentes se inicien, se pongan al día con lo que otros agentes escribieron desde su última sesión y continúen sin releer todo el historial.

Detección y Resolución de Conflictos

Cuando una memoria entrante contradice una existente (detectada por pares de palabras clave antónimas: "no"/"es", "falso"/"verdadero", "nunca"/"siempre", etc.), el sistema:

  1. Verifica los niveles de autoridad
  2. Sobrescribe (mayor autoridad) o registra el conflicto
  3. Los conflictos se muestran a través de la herramienta check_conflicts para revisión humana

Módulo de Seguridad

Archivo: src/memory_v2/security.py

Escaneo de Credenciales (13 Patrones)

Cada memoria almacenada a través de add_memory o extract_from_conversation se escanea contra 13 patrones de expresiones regulares:

PatrónObjetivo
api_key/secret/token/password=...Asignaciones genéricas de credenciales
Cadenas Base64 (40+ caracteres)Secretos codificados
sk-[a-zA-Z0-9]{20,}Claves API de OpenAI
sk-ant-[a-zA-Z0-9-]{20,}Claves API de Anthropic
ghp_[a-zA-Z0-9]{36}Tokens de acceso personal de GitHub
gho_[a-zA-Z0-9]{36}Tokens OAuth de GitHub
bearer [token]Tokens de autenticación Bearer
xoxb-... / xoxp-...Tokens de bot/usuario de Slack
AKIA[0-9A-Z]{16}Claves de acceso de AWS
-----BEGIN PRIVATE KEY-----Claves privadas RSA/EC
mongodb://...URIs de conexión de MongoDB
postgres://...URIs de conexión de PostgreSQL

Una lista de permitidos previene falsos positivos en claves redactadas (sk-abc...), marcadores de ejemplo y los hashes SHA-256 de contenido del propio sistema.

Comportamiento al detectar: La memoria se bloquea -- no se almacena. La herramienta devuelve un mensaje de error indicando al llamante que elimine los datos sensibles.

Detección de Inyección (6 Patrones)

El contenido de fuentes externas se escanea en busca de intentos de inyección de prompts:

"ignore previous instructions"
"you are now a"
"system: you"
"forget everything/all/your"
"new instructions:"
"override previous/system/all"

El sistema advierte pero no elimina -- el llamante (el agente de IA) toma la decisión final.

Manifiestos de Integridad

La herramienta check_integrity genera y verifica manifiestos SHA-256 para todos los archivos markdown de la bóveda, detectando:

  • Archivos modificados (discrepancia de hash)
  • Archivos nuevos (no en el manifiesto)
  • Archivos faltantes (en el manifiesto pero no en disco)

Ejemplos Prácticos

Recorrido de Activación ACT-R

Considera una memoria almacenada hace 48 horas con 5 accesos, etiquetada con ["python", "debugging"]. El contexto de consulta actual incluye la etiqueta "python", que aparece en 20 memorias en total.

Paso 1: Activación de nivel base

n = 5 (access count)
L = 48 (hours since creation)
d = 0.5

B_i = ln(5 / (1 - 0.5)) - 0.5 * ln(48)
    = ln(10) - 0.5 * ln(48)
    = 2.3026 - 0.5 * 3.8712
    = 2.3026 - 1.9356
    = 0.3670

Paso 2: Activación de propagación

Etiquetas de contexto: ["python"] (1 etiqueta, por lo que W_j = 1.0) Etiquetas de memoria: ["python", "debugging"] La etiqueta "python" es compartida. Su fan es 20.

S_i = 1.0 * (1.6 - ln(20))
    = 1.0 * (1.6 - 2.9957)
    = max(-1.3957, 0)
    = 0.0

El fan de 20 es demasiado alto -- la fuerza asociativa es negativa, por lo que se recorta a 0. Esta etiqueta es demasiado común para proporcionar un priming útil. Si hubiéramos usado una etiqueta más rara como "asyncio" con un fan de 3:

S_i = 1.0 * (1.6 - ln(3))
    = 1.0 * (1.6 - 1.0986)
    = 0.5014

Paso 3: Ruido

Extraer u = 0.73 de Uniform(0,1):

epsilon = 0.25 * ln(0.73 / 0.27)
        = 0.25 * ln(2.7037)
        = 0.25 * 0.9946
        = 0.2487

Paso 4: Activación completa (usando la etiqueta común "python")

A_i = 0.3670 + 0.0 + 0.2487 = 0.6157

Paso 5: Probabilidad de recuperación

P(retrieve) = 1 / (1 + exp(-(0.6157 - (-0.5)) / 0.25))
            = 1 / (1 + exp(-1.1157 / 0.25))
            = 1 / (1 + exp(-4.4628))
            = 1 / (1 + 0.01155)
            = 0.9886

Esta memoria tiene una probabilidad de recuperación del 98.9% -- alta activación por acceso frecuente y ruido favorable.


Recorrido de Decaimiento FadeMem

Considera tres memorias durante un barrido de decaimiento:

MemoriaRecuento de AccesosAcceso Máximo (global)Horas Desde el AccesoCapa Actual
A12502LTM
B350168 (1 semana)STM
C1501440 (2 meses)STM

Memoria A (memoria LTM activa):

frequency = log(12 + 1) / log(50 + 1) = log(13) / log(51) = 2.565 / 3.932 = 0.652
recency   = exp(-0.1 * 2) = exp(-0.2) = 0.819
I(A)      = 0.4 * 0.5 + 0.3 * 0.652 + 0.3 * 0.819
          = 0.200 + 0.196 + 0.246
          = 0.641

La importancia 0.641 está en la zona de histéresis (0.3 -- 0.7). La memoria A permanece en LTM. Sin acción.

Memoria B (memoria STM descuidada):

frequency = log(3 + 1) / log(51) = log(4) / log(51) = 1.386 / 3.932 = 0.352
recency   = exp(-0.1 * 168) = exp(-16.8) ~ 0.0000005
I(B)      = 0.4 * 0.5 + 0.3 * 0.352 + 0.3 * 0.0000005
          = 0.200 + 0.106 + 0.000
          = 0.306

La importancia 0.306 está justo por encima del umbral de degradación (0.3). Aún en la zona de histéresis -- permanece en STM.

Memoria C (antigua, apenas accedida):

frequency = log(1 + 1) / log(51) = log(2) / log(51) = 0.693 / 3.932 = 0.176
recency   = exp(-0.1 * 1440) = exp(-144) ~ 0.0
I(C)      = 0.4 * 0.5 + 0.3 * 0.176 + 0.3 * 0.0
          = 0.200 + 0.053 + 0.000
          = 0.253

La importancia 0.253 está por debajo del umbral de degradación (0.3). La memoria C se degrada a STM (ya está allí). Dado que 0.253 > umbral de archivo 0.1, NO se archiva aún. Pero si tuviera importancia por debajo de 0.1 y edad > 30 días (cierto a los 60 días), se archivarí­a en el cementerio.


Recorrido de Búsqueda Híbrida

Consulta: "Configuración del bucle de eventos asyncio de Python"

Resultados BM25 (FTS5 MATCH, ordenados por rango BM25):

RangoID de MemoriaContenido (truncado)
042"La configuración del bucle de eventos asyncio para..."
188"Python 3.12 cambió el bucle de eventos predeterminado..."
215"Los archivos de configuración deben usar formato TOML..."

Resultados vectoriales (sqlite-vec, ordenados por distancia de embedding):

RangoID de MemoriaContenido (truncado)
088"Python 3.12 cambió el bucle de eventos predeterminado..."
142"La configuración del bucle de eventos asyncio para..."
2107"uvloop proporciona un reemplazo de bucle de eventos más rápido..."

Fusión RRF (k = 60):

ID 42:  BM25 contribution = 1/(60+0+1) = 0.01639
        Vec contribution  = 1/(60+1+1) = 0.01613
        RRF score         = 0.03252

ID 88:  BM25 contribution = 1/(60+1+1) = 0.01613
        Vec contribution  = 1/(60+0+1) = 0.01639
        RRF score         = 0.03252

ID 15:  BM25 contribution = 1/(60+2+1) = 0.01587
        Vec contribution  = 0 (not in vector top-K)
        RRF score         = 0.01587

ID 107: BM25 contribution = 0 (not in BM25 top-K)
        Vec contribution  = 1/(60+2+1) = 0.01587
        RRF score         = 0.01587

Los IDs 42 y 88 empatan en 0.03252. Ambos aparecieron en ambos conjuntos de resultados, confirmando que son relevantes tanto en ejes léxicos como semánticos. Los IDs 15 y 107 aparecieron solo en uno, recibiendo la mitad de la puntuación RRF máxima.

Después del reordenamiento ACT-R (aplicando la fórmula 0.6 * hybrid + 0.4 * (activation / 10)), la memoria 88 podría superar a la 42 si ha sido accedida con más frecuencia, o la 42 podría ganar si tiene una superposición de etiquetas contextuales más fuerte.


Instalación

Requisitos Previos

  • Python 3.9+
  • Ollama ejecutándose localmente con nomic-embed-text y (opcionalmente) qwen2.5:3b descargados
  • sqlite-vec (instalado automáticamente vía pip)

Desde PyPI

pip install memory-v2

Desde el Código Fuente

git clone https://github.com/Haustorium12/memory-v2.git
cd memory-v2
pip install -e .

Con Dependencias de Grafo

La detección de comunidades Leiden y la visualización PyVis requieren dependencias opcionales:

pip install memory-v2[graph]

Con Dependencias de Desarrollo

pip install memory-v2[all]

Configuración de Ollama

# Install Ollama (https://ollama.com/download)
ollama pull nomic-embed-text     # Required: 768-dim embeddings
ollama pull qwen2.5:3b           # Optional: fact extraction + compaction

El modelo de embeddings es necesario para todas las operaciones de búsqueda y almacenamiento. El modelo LLM es necesario solo para extract_from_conversation, compact_text y build_kg (extracción de entidades del grafo de conocimiento).


Configuración

Variables de Entorno

VariablePredeterminadoDescripción
MEMORY_V2_DB~/.memory-v2/memory.dbRuta al archivo de base de datos SQLite
MEMORY_V2_GRAPH~/.memory-v2/knowledge_graph.pickleRuta al pickle del grafo NetworkX
MEMORY_V2_CACHE~/.memory-v2/cacheDirectorio para caché de archivos de embeddings
MEMORY_V2_VAULT~/.memory-v2/vaultDirectorio raíz de la bóveda markdown
MEMORY_V2_EMBED_MODELnomic-embed-textModelo Ollama para embeddings
MEMORY_V2_LLM_MODELqwen2.5:3bModelo Ollama para extracción/compactación
MEMORY_V2_PROTECTED_NAMES(vacío)Nombres separados por comas para proteger de la compactación
MEMORY_V2_AUTHORITY_CHAIN(ver abajo)Jerarquía de autoridad JSON
MEMORY_V2_KG_HASHES~/.memory-v2/kg_file_hashes.jsonRegistro de hash de archivos para construcciones KG incrementales

Configuración del Cliente MCP

Claude Code (settings.json)

{
  "mcpServers": {
    "memory-v2": {
      "command": "memory-v2-server",
      "env": {
        "MEMORY_V2_DB": "C:\\Users\\you\\.memory-v2\\memory.db",
        "MEMORY_V2_VAULT": "C:\\Users\\you\\vault"
      }
    }
  }
}

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "memory-v2": {
      "command": "memory-v2-server",
      "args": [],
      "env": {
        "MEMORY_V2_DB": "/home/you/.memory-v2/memory.db",
        "MEMORY_V2_VAULT": "/home/you/vault"
      }
    }
  }
}

Cadena de Autoridad Personalizada

export MEMORY_V2_AUTHORITY_CHAIN='{"human": 1, "primary_agent": 2, "coordinator": 3, "worker": 4}'

Uso

Como Servidor MCP

La interfaz principal. Inicia el servidor:

memory-v2-server

El servidor se comunica a través de stdio usando el protocolo MCP. Normalmente, lo configuras en los ajustes de tu cliente MCP en lugar de ejecutarlo manualmente.

Como Herramienta CLI

Para scripting y flujos de trabajo no MCP:

# Database statistics
memory-v2 stats

# Store a memory
memory-v2 add '{"content": "Python 3.12 uses per-interpreter GIL", "content_type": "fact", "tags": ["python", "concurrency"]}'

# Search
memory-v2 search "Python GIL changes"

# Keyword search
memory-v2 keyword "GIL"

# Get by ID
memory-v2 get 42

# Update
memory-v2 update '{"memory_id": 42, "content": "Python 3.13 makes per-interpreter GIL stable"}'

# Archive
memory-v2 forget '{"memory_id": 42, "reason": "outdated"}'

# Recent memories
memory-v2 recent

# Reindex vault
memory-v2 reindex

Construyendo el Grafo de Conocimiento

El grafo de conocimiento se construye a partir de archivos de la bóveda usando un CLI independiente que procesa cada documento mediante extracción de entidades LLM:

# Incremental build (skip unchanged files)
memory-v2-build-kg

# Full rebuild
memory-v2-build-kg --full

El constructor:

  1. Lee todos los archivos markdown de la bóveda
  2. Extrae entidades y relaciones vía Ollama
  3. Las agrega al grafo NetworkX (fusionando nodos duplicados, incrementando pesos de aristas)
  4. Guarda progreso cada 25 archivos (punto de control)
  5. Ejecuta detección de comunidades Leiden
  6. Genera una visualización HTML interactiva PyVis (graph.html)
  7. Imprime estadísticas del grafo y entidades principales

Migración de v1 a v2

memory-v2 es una reescritura completa. Comparte cero código con claude-memory v1. La tabla a continuación resume todos los cambios arquitectónicos.

Característicav1 (claude-memory)v2 (memory-v2)
AlmacenamientoChromaDB (almacén de documentos embebido)SQLite + sqlite-vec + FTS5 (archivo único, modo WAL)
BúsquedaVector ponderado + BM25 (sistemas separados)Fusión de Rango Recíproco que combina BM25 y vector en una sola canalización de consulta
Modelo de DecaimientoEbbinghaus (5 mecanismos biológicos: curva de decaimiento, exenciones perennes, ponderación de prominencia, fortalecimiento de recuperación, consolidación)FadeMem (decaimiento de ley de potencia con exponentes beta dependientes de capa, promoción/democión STM/LTM con histéresis, archivado ponderado por importancia)
ActivaciónNingunaACT-R completo: activación de línea base + activación de propagación + ruido logístico + probabilidad de recuperación
Grafo de ConocimientoNingunoGrafo dirigido NetworkX con detección de comunidades Leiden y recuperación con Personalized PageRank
InterfazSolo CLIServidor MCP (17 herramientas) + CLI
Tipos de MemoriaSolo fragmentos de archivos6 tipos estructurados: fact, episode, decision, correction, identity, person
Multi-AgenteNingunoCadena de autoridad + compensaciones de consumidor estilo Kafka + detección y registro de conflictos
SeguridadNinguna13 patrones de credenciales + lista de permitidos, 6 patrones de inyección, manifiestos de integridad SHA-256
CompactaciónProceso de vigilancia externoPipeline integrado CogCanvas de 6 pasos con verificación de fidelidad y recibos auditables
ExtracciónManualPipeline LLM de dos pasadas con verificación de novedad, detección de emociones y tipificación automática de contenido
EmbeddingsSentenceTransformers / OpenAIOllama nomic-embed-text (local, cero claves API)
LLMAPI de OpenAIOllama qwen2.5:3b (local, cero claves API)
Dependenciaschromadb, openai, sentence-transformerssqlite-vec, fastmcp, ollama, networkx, numpy
Formato de DatosInterno de ChromaDB (opaco)SQLite (inspeccionable, portátil, archivo único)
Archivo de Base de DatosDirectorio de ChromaDBArchivo único .db (típicamente < 50 MB para ~1000 memorias)

¿Por qué la Reescritura?

El sistema v1 funcionó durante 6 meses y sobrevivió 59 ciclos de compactación. Sus limitaciones se hicieron evidentes con el uso diario:

  1. Contención de bloqueos en ChromaDB: Dos agentes intentando escribir simultáneamente provocaban un interbloqueo
  2. Sin tipos estructurados: Todo era un "fragmento" — sin forma de distinguir decisiones de hechos
  3. Sin relaciones de grafo: No podía responder "¿qué está relacionado con X?" sin similitud de embeddings
  4. El decaimiento de Ebbinghaus era demasiado simple: Sin arquitectura de doble capa, sin supervivencia ponderada por importancia
  5. Solo CLI: Requería acceso a shell; no podía ser usado por Claude Desktop o agentes basados en web
  6. Dependencias externas para funciones principales: La compactación requería un proceso de vigilancia separado
  7. Dependencia de claves API: Los embeddings requerían OpenAI o SentenceTransformers local (pesado)

Estructura del Repositorio

memory-v2/
|
+-- src/memory_v2/
|   +-- __init__.py              # Package init, lazy embedder warmup
|   +-- db.py                    # SQLite + sqlite-vec + FTS5 (schema, CRUD, hybrid search)
|   +-- server.py                # FastMCP server (17 tools, background warmup thread)
|   +-- embeddings.py            # Ollama nomic-embed-text (embed, batch, cache)
|   +-- scoring.py               # ACT-R activation + FadeMem decay + cosine similarity
|   +-- knowledge_graph.py       # NetworkX graph, Leiden communities, PPR retrieval, PyVis viz
|   +-- vault_indexer.py         # Markdown vault indexing (chunk, embed, delta detect)
|   +-- extraction.py            # Two-pass LLM fact extraction pipeline
|   +-- compaction.py            # CogCanvas 6-step compression with verification
|   +-- multi_agent.py           # Authority chain, consumer offsets, conflict detection
|   +-- security.py              # 13 credential patterns, 6 injection patterns, manifests
|   +-- build_kg.py              # Standalone knowledge graph builder CLI
|   +-- cli.py                   # CLI wrapper for non-MCP usage
|
+-- docs/                        # Additional documentation
+-- examples/                    # Usage examples
+-- tests/                       # Test suite (pytest)
|
+-- pyproject.toml               # Package metadata, dependencies, entry points
+-- CHANGELOG.md                 # Release history
+-- LICENSE                      # MIT License
+-- README.md                    # This file

Puntos de Entrada

Definidos en pyproject.toml:

ComandoDestinoPropósito
memory-v2memory_v2.cli:mainHerramienta CLI
memory-v2-servermemory_v2.server:runServidor MCP
memory-v2-build-kgmemory_v2.build_kg:mainConstructor de grafo de conocimiento

Trabajo Relacionado

memory-v2 se basa e inspira en un creciente cuerpo de trabajo sobre sistemas de memoria para agentes de modelos de lenguaje:

  • HippoRAG (2024) — Arquitectura RAG neurobiológica que utiliza grafos de conocimiento y Personalized PageRank para la recuperación. La herramienta graph_search de memory-v2 implementa este patrón de recuperación. arXiv.
  • A-MEM (Taller NeurIPS 2025) — Marco de memoria agéntica que explora memoria estructurada para agentes LLM.
  • CogCanvas — Marco de compresión cognitiva para agentes. El pipeline de compactación de memory-v2 adapta su metodología de "extraer, eliminar, resumir, verificar".
  • Focus (arXiv:2601.07190) — Compresión activa de contexto para modelos de lenguaje grandes.
  • ReadAgent — Agente de memoria orientado a la lectura para documentos largos.
  • AgeMem — Gestión de memoria sensible a la edad para agentes de lenguaje.
  • EverMemOS — Sistema operativo de memoria persistente para agentes.
  • Memoria — Marco de agente aumentado con memoria.
  • PlugMem — Módulos de memoria conectables para agentes LLM.
  • AriGraph — Memoria estructurada en grafo para agentes orientados a tareas.
  • Zep / Graphiti — Infraestructura de memoria de producción para aplicaciones de IA, utilizando grafos de conocimiento.
  • TITANS — Entrenamiento de modelos de lenguaje grandes con capas de memoria.

Referencias

  1. Anderson, J.R. & Schooler, L.J. (1991). Reflections of the environment in memory. Psychological Science, 2(6), 396--408.

  2. Anderson, J.R., Bothell, D., Byrne, M.D., Douglass, S., Lebiere, C., & Qin, Y. (2004). An integrated theory of the mind. Psychological Review, 111(4), 1036--1060.

  3. Ebbinghaus, H. (1885/1913). Memory: A Contribution to Experimental Psychology. (Trans. H.A. Ruger & C.E. Bussenius). New York: Teachers College, Columbia University.

  4. Cormack, G.V., Clarke, C.L.A., & Buettcher, S. (2009). Reciprocal Rank Fusion outperforms Condorcet and individual Rank Learning Methods. SIGIR '09: Proceedings of the 32nd International ACM SIGIR Conference on Research and Development in Information Retrieval.

  5. HippoRAG: Neurobiological RAG Architecture (2024). arXiv preprint.

  6. A-MEM: Agentic Memory. NeurIPS 2025 Workshop.

  7. CogCanvas: Cognitive Compression for Agents.

  8. Focus: Active Context Compression. arXiv:2601.07190.

  9. Traag, V.A., Waltman, L., & van Eck, N.J. (2019). From Louvain to Leiden: guaranteeing well-connected communities. Scientific Reports, 9, 5233.


Construido Con

ComponenteRolPor qué
OllamaInferencia LLM local (embedding + extracción)Cero claves API, cero exfiltración de datos, funciona en hardware de consumo
SQLiteBase de datos principalArchivo único, cero configuración, modo WAL para lecturas concurrentes, implementado universalmente
sqlite-vecBúsqueda de similitud vectorialIntegra búsqueda ANN directamente en SQLite, sin proceso separado de base de datos vectorial
SQLite FTS5Búsqueda de texto completo BM25Integrado en SQLite, sincronizado automáticamente mediante disparadores, implementación BM25 probada en batalla
FastMCPMarco de servidor MCPRegistro limpio de herramientas basado en decoradores, maneja transporte stdio
NetworkXGrafo de conocimientoBiblioteca de grafos madura, PageRank integrado, serializable a pickle
python-igraph + leidenalgDetección de comunidadesEl algoritmo Leiden garantiza comunidades bien conectadas
NumPyOperaciones vectorialesSimilitud coseno rápida, serialización de embeddings
PyVisVisualización de grafosSalida HTML interactiva para exploración del grafo de conocimiento

Licencia

Licencia MIT. Copyright (c) 2026 Haustorium12.

Consulte LICENSE para el texto completo.


memory-v2 fue construido porque los asistentes de IA merecen memorias que realmente funcionen como memorias.