Memento-cmp
Una arquitectura de memoria de tres capas para LLMs (Redis + Postgres + Vector) MCP
Documentación
AnchorMind
¿Qué es esto? | ¿Cómo funciona? | ¿Cómo se instala? | Preguntas frecuentes
¿Qué es esto?
Es un servidor MCP que proporciona memoria a largo plazo a agentes de IA (Claude Code, Cursor, Codex, etc.) que persiste incluso después de que termina la sesión. Se aloja directamente y la memoria se almacena en PostgreSQL.
Los agentes olvidan conversaciones anteriores cuando termina la sesión. En resumen, hay que volver a explicarles todo. AnchorMind guarda contenido que es tedioso repetir cada vez —como la configuración del proyecto, un error resuelto ayer o las preferencias de estilo de trabajo— en unidades cortas (fragmentos) y recupera solo lo necesario en la siguiente sesión.
Cuándo usarlo
- Usas agentes de IA a diario y repites las mismas explicaciones en cada sesión.
- Quieres compartir la misma memoria entre varios agentes (Claude Code, Cursor, Codex, etc.) y varios dispositivos.
- Quieres separar la memoria por proyecto o por cliente.
- Quieres mantener la memoria en tu propio servidor y tu propia base de datos.
¿Cómo funciona?
- Ejecutas el servidor AnchorMind.
- Lo registras como servidor MCP en el agente.
- Al iniciar la sesión, el agente recibe la memoria clave del servidor. Durante la conversación, busca memoria cuando la necesita y guarda lo que vale la pena conservar.
- El agente responde consultando esa memoria.
Desde la perspectiva del usuario, se ve más o menos así.
[세션 1]
사용자: 우리 프로젝트는 PostgreSQL 15를 쓰고 테스트는 Vitest로 돌려.
에이전트: (remember 호출, 파편 2개 저장)
[다음 날, 새 세션]
에이전트: (시작하며 context 호출, 저장해 둔 파편 2개를 받음)
사용자: 테스트 어떻게 돌리더라?
에이전트: (recall 호출) 이 프로젝트는 Vitest를 쓴다. npx vitest로 실행하면 된다.
No es necesario repetir las mismas explicaciones cada vez que cambia la sesión. El flujo completo se muestra en el siguiente diagrama.
sequenceDiagram
participant U as 사용자
participant A as 에이전트
participant M as AnchorMind 서버
participant D as PostgreSQL
U->>A: 세션 시작
A->>M: context
M->>D: 선호, 에러, 절차, 결정 조회
M-->>A: 핵심 기억
U->>A: 질문
A->>M: recall
M-->>A: 관련 기억
A-->>U: 기억을 참고한 답변
A->>M: remember (새 결정, 해결한 에러)
U->>A: 세션 종료
A->>M: reflect (세션 요약)
Las llamadas a herramientas las realiza el agente. El servidor no inicia la conversación. Para que el agente las llame sin omitir ninguna, debes configurar hooks o un archivo de instrucciones (para que se use automáticamente).
¿Cómo se instala?
Instalación del servidor
Requisitos: Node.js 22+, Docker. Si ya tienes PostgreSQL con pgvector instalado, Docker no es necesario.
1. Base de datos (omítelo si ya tienes una)
docker run -d --name anchormind-db -p 5432:5432 \
-e POSTGRES_PASSWORD=change-me -e POSTGRES_DB=memento \
-v anchormind-pgdata:/var/lib/postgresql/data pgvector/pgvector:pg15
docker exec anchormind-db psql -U postgres -d memento \
-c "CREATE EXTENSION IF NOT EXISTS vector"
2. Servidor
git clone https://github.com/JinHo-von-Choi/anchormind.git
cd anchormind
npm install
cp .env.example.minimal .env
Abre .env y cambia solo dos cosas.
- Cambia
MEMENTO_ACCESS_KEYa un valor distinto dechange-me. Este valor es la clave maestra y se usa como token deAuthorization: Bearer. - Añade las siguientes tres líneas. Es la configuración de incrustación local para usar búsqueda en lenguaje natural sin claves de API externas.
EMBEDDING_PROVIDER=transformers
EMBEDDING_MODEL=Xenova/multilingual-e5-small
EMBEDDING_DIMENSIONS=384
La configuración de la base de datos coincide con el valor de docker run anterior, así que déjala como está. Ahora ejecuta.
npm run migrate
node scripts/post-migrate-flexible-embedding-dims.js
node server.js
En la primera ejecución se descarga el modelo de incrustación. Ocupa unos 120 MB.
3. Verificación
curl http://localhost:57332/health
Si aparece {"status":"healthy", ...}, todo está correcto. Para verificar guardado y consulta de una sola vez, sigue First Memory Flow.
Si necesitas más:
- Crear
.envmientras respondes preguntas, usar API de incrustación externa: INSTALL.md - Delegar la instalación a un asistente de IA: INSTALL.md
- Operar continuamente con Docker: Production Docker
- Windows: Guía de WSL2
- Si te quedas atascado: Solución de problemas
Conexión al agente
Claude Code:
claude mcp add anchormind http://localhost:57332/mcp \
--transport http \
--scope user \
--header "Authorization: Bearer YOUR_ACCESS_KEY"
Si ves Connected en claude mcp list, la conexión está establecida. Claude Code no reconoce servidores MCP HTTP escritos directamente en settings.json, así que debes usar el comando anterior o .mcp.json.
Los métodos de conexión para otros clientes como Cursor, Codex, Windsurf, Claude.ai Web, ChatGPT, etc., están documentados en Conexión por cliente.
Después de conectar, para que el agente use las herramientas de memoria automáticamente, consulta la FAQ a continuación.
Preguntas frecuentes
Solo se incluye una respuesta por pregunta. Si no encuentras lo que buscas, consulta Solución de problemas o Issues.
¿Es la herramienta adecuada?
¿En qué se diferencia de la memoria en archivos como CLAUDE.md o MEMORY.md?
La memoria en archivos debe leerse completa en cada sesión. Cuanto más contenido haya, más tokens se consumen y es más fácil que el contenido antiguo y el nuevo entren en conflicto. AnchorMind solo busca los fragmentos necesarios y los devuelve dentro de tokenBudget.
¿En qué se diferencia de RAG?
RAG indexa documentos existentes y los recupera. AnchorMind es memoria que el agente escribe y relee directamente durante la conversación. La memoria guardada se organiza mediante fusión de duplicados, detección de contradicciones y decaimiento de importancia.
¿Se puede usar como base de conocimiento?
Sí. Si introduces hechos como fragmentos de una o dos frases, se pueden encontrar con recall. No está pensado para indexar documentos largos completos.
¿Se puede usar junto con otras herramientas de memoria que ya uso?
Sí. Como es un servidor MCP, se puede registrar junto con otras en el mismo agente. El nombre del servidor se antepone al nombre de la herramienta, así que se distinguen (por ejemplo: mcp__anchormind__recall).
¿Cómo decido si vale la pena migrar desde mi herramienta actual?
Si se cumple al menos una de las siguientes tres condiciones, vale la pena probarlo. Si no se cumple ninguna, tu herramienta actual es suficiente.
- Necesitas tener los datos en tu propio servidor.
- Necesitas usar la misma memoria desde varios agentes y dispositivos.
- Quieres que el servidor gestione duplicados y contradicciones.
¿En qué casos no es adecuada?
- Si lo que hay que recordar cabe en una página de
CLAUDE.md, un archivo es más simple. - Hay que operar PostgreSQL (pgvector).
- La búsqueda está orientada a hechos. Es débil para preguntas que requieren sintetizar razonamientos largos (benchmark).
Instalación y requisitos
¿Son obligatorios el modelo de incrustación o la clave de OpenAI?
No son obligatorios. Con solo PostgreSQL, funcionan el guardado, la recuperación por palabras clave, los enlaces y las funciones de administración. Sin embargo, sin incrustaciones, las consultas en lenguaje natural (consultas de text) no devuelven resultados: 0 resultados. Por eso el procedimiento de instalación anterior incluye incrustación local.
¿Qué se usa para la incrustación: modelo local o API externa?
- Modelo local: coloca
EMBEDDING_PROVIDER=transformersen.env. No se necesita clave de API y el contenido no sale al exterior. - API externa: usa una clave de API de incrustación como la de OpenAI.
No se pueden mezclar ambos métodos dentro de la misma base de datos, porque las dimensiones vectoriales difieren. Para más detalles, consulta Guía de incrustación local.
¿Se necesita Redis?
No. Si conectas Redis, se activan la caché de búsqueda y el seguimiento de actividad de sesión.
¿Qué cambia si se usa sin Redis?
Un fragmento recién guardado puede tardar hasta 5 minutos en aparecer en la búsqueda en lenguaje natural, porque el servidor genera incrustaciones cada 5 minutos. La búsqueda por palabras clave es inmediata.
¿Cuánta memoria usa el modelo local?
| Modelo | Memoria adicional | Uso |
|---|---|---|
Incrustación local (multilingual-e5-small) | ~150 MB | Búsqueda en lenguaje natural |
| NLI para detección de contradicciones (mDeBERTa) | ~250–280 MB | Determina si un fragmento nuevo contradice uno existente |
Con ambos modelos, el proceso del servidor consume unos 0.4 GB adicionales. El modelo de reordenamiento (reranker) está desactivado por defecto. Si usas una API de incrustación externa, se elimina la memoria que ocupaba la incrustación local. Las cifras por configuración están en Requisitos del sistema.
¿Se puede evitar que el modelo NLI consuma memoria?
Con NLI_SERVICE_URL se puede delegar el NLI a un servicio separado, de modo que el modelo no se cargue en el proceso del servidor. MEMENTO_CONSOLIDATE_DETECT_CONTRADICT=false es la configuración que solo desactiva la detección de contradicciones; el modelo se sigue cargando al iniciar el servidor.
Integración con agentes
¿Cómo hago que el agente use las herramientas de memoria automáticamente?
Hay dos métodos, que se pueden combinar.
- Hooks o plugins: al inicio de la sesión se llama a
contexty al final se deja un resumen automático. Conanchormind init --target claude --writese crea un plugin para Claude Code (instalación del plugin, configuración de hooks). - Instrucciones: después de conectar el MCP, pide al agente que lea la guía de la herramienta
get_skill_guidey que use activamente las herramientas de memoria. La guía la proporciona el servidor.
¿Qué pasa si la memoria entra en conflicto con las reglas de CLAUDE.md?
La memoria inyectada tiene menor prioridad que el prompt del sistema y los archivos de instrucciones. Hechos como "usamos PostgreSQL 15" funcionan bien, pero reglas de comportamiento como "escribe los tests con Given-When-Then" pueden ignorarse si hay conflicto. En resumen: las reglas de comportamiento van en CLAUDE.md, AGENTS.md, hooks y skills.
¿Puede el agente saber cuándo no hay respuesta en la memoria?
Consulta el campo _meta.evidence.status de la respuesta de recall. Si es no_evidence, no se encontró memoria; si es partial, algunas palabras clave de la pregunta no aparecen en los resultados (las palabras faltantes están en uncovered_terms). El agente puede volver a buscar con las palabras faltantes o responder "no está en la memoria". Para preguntas como "¿cuántas veces?" o "¿cuándo?", se incluye una tabla con la evidencia ordenada cronológicamente y un resumen de la línea temporal por tema.
Datos y seguridad
¿Dónde se almacena mi memoria?
En tu propio PostgreSQL.
¿Hay casos en que la memoria sale al exterior?
Solo sale por las rutas que configures.
- Si usas una API de incrustación externa, el contenido guardado se envía a esa API. Con incrustación local no sale.
- Las funciones de LLM como evaluación de calidad y reflexión automática requieren un proveedor de LLM. El valor predeterminado es
gemini-cliy el proveedor se puede cambiar. - Con claves y
egress_policypor workspace se restringen los proveedores externos de LLM, se enmascara el contenido saliente y se registran los envíos (revisión de seguridad y operación).
¿Puedo guardar contraseñas o tokens en la memoria?
No se recomienda. Al guardar, se enmascaran patrones de información sensible, pero no se detectan todos los formatos. Los secretos deben ir en variables de entorno o en un almacén de secretos; en la memoria solo se anota la ubicación.
Calidad de la memoria
¿Se puede evitar que entre contenido incorrecto en la memoria?
No se puede evitar por completo. Incluso los humanos recordamos de forma ligeramente distinta cada vez. Por eso el diseño no se centra en bloquear todo desde el principio, sino en reducir el alcance de la propagación de errores y permitir encontrar y corregir problemas cuando ocurren. Los métodos se detallan en los cuatro puntos siguientes.
¿Cómo se corrige una memoria incorrecta?
Como se guarda por fragmentos, basta con corregir el fragmento incorrecto con amend o eliminarlo con forget. No es una estructura donde un resumen completo se desajuste.
¿Qué pasa si el contenido nuevo contradice al existente?
El servidor detecta la contradicción y expira el fragmento antiguo (excepto los anclados). No lo elimina directamente. Se deja un historial con valid_to y superseded_by; los pasos detallados están en Internals. Cuál es más reciente se determina por el momento en que se dijo (mentionTime, o la hora de guardado si no existe).
Si necesitas el valor anterior, proporciona includeHistory: true en recall. El valor anterior se añade justo después del valor actual. Las contradicciones aún no resueltas se marcan en los resultados con conflicts_with.
¿También se recuerda cuándo ocurrió?
Se distinguen el momento en que se dijo y el momento en que ocurrió el hecho. En remember se pueden proporcionar mentionTime y eventTime; si no se proporciona eventTime, se infiere de expresiones del texto como "ayer", "2026-03-14" o "la semana pasada". Si necesitas el orden de los hechos, usa order: "chronological" en recall; para filtrar por período según la hora del evento, usa timeRange: { from, to, basis: "event" }.
¿Cómo se marcan los contenidos inciertos?
Se guardan con assertionStatus=inferred. Si luego se confirman, se cambian a verified; si resultan incorrectos, a rejected.
¿Se detectan automáticamente los contenidos incorrectos desde el principio?
No. El servidor solo detecta fragmentos contradictorios que entran nuevos. La memoria importante se mantiene como ancla y la revisa una persona. Los fragmentos con baja confianza, como los provenientes de documentos externos, no entran en ANCHOR ni CORE inyectados al inicio de la sesión, y los intentos de sobrescribir las instrucciones del agente se envían a la cola de revisión.
¿Qué pasa si la memoria se acumula?
La fusión de duplicados, la detección de contradicciones, el decaimiento de importancia y la expiración por TTL se ejecutan periódicamente. Los fragmentos que no se usan durante mucho tiempo bajan de nivel hasta desaparecer. Los fragmentos que deben conservarse se pueden marcar como ancla para excluirlos del decaimiento y la expiración. Marcar anclas requiere el permiso anchor.
Solución de problemas
Guardé algo pero no aparece en recall
- Si aparece con
pending_review: true, está en cola de revisión (problema 17 en Solución de problemas). - Si el workspace es distinto, no se ve. Debes usar el mismo
workspacepara guardar y consultar. - Si solo falla la consulta en lenguaje natural, verifica que la incrustación esté activada. Sin Redis, un fragmento recién guardado puede tardar hasta 5 minutos en aparecer en la búsqueda en lenguaje natural. La búsqueda por palabras clave es inmediata.
Otros síntomas están documentados en 17 puntos en Solución de problemas.
¿No se llamaba memento-mcp?
Es el mismo proyecto. Como había muchos proyectos con nombres iguales o similares, se renombró a AnchorMind. Los comandos aceptan tanto anchormind como memento-mcp, y algunas variables de entorno siguen usando el prefijo MEMENTO_.
Unidades de memoria
La memoria se guarda en fragmentos de una o dos frases. Cada fragmento es de uno de 7 tipos.
| Tipo | Contenido |
|---|---|
fact | Hechos como valores de configuración, rutas, versiones |
decision | Decisiones técnicas y su justificación |
error | Errores ocurridos, causas y soluciones |
preference | Estilo y forma de trabajar del usuario |
procedure | Procedimientos repetitivos como despliegue, build, tests |
relation | Relaciones y dependencias entre entidades |
episode | Narrativas con contexto (1000 caracteres; el resto, 300) |
Las herramientas principales son context (restaura la memoria clave al inicio de la sesión), recall (búsqueda), remember (guardado) y reflect (guarda un resumen al final de la sesión). La lista completa de herramientas y reglas de uso está en SKILL.md; la lista completa de funciones, en Detalle de funciones.
Benchmark
Según 500 preguntas de LongMemEval-S (medido el 2026-10-10, líder deepseek-flash, evaluador GPT-4o en configuración oficial, MiniMax, Claude Sonnet 5.5):
| Métrica | Puntuación | Condición |
|---|---|---|
| Proporción de turnos de evidencia completos en top-10 | 91.2% | bge-m3, búsqueda por segmentos activada |
| Recall de búsqueda recall_any@5 | 98.4% | Por sesión |
| Tasa de respuesta correcta en QA (evaluador oficial GPT-4o) | 84.0% | IC 95% 80.5–87.0% |
| Tasa de respuesta correcta en QA (evaluación MiniMax) | 84.0% | IC 95% 80.5–87.0% |
| Tasa de respuesta correcta en QA (evaluación Claude) | 78.0% | IC 95% 74.2–81.4% |
La búsqueda recupera la mayor parte de la evidencia. Los errores restantes se concentran en preguntas que requieren sumar valores de varias sesiones o calcular fechas (multi-session, temporal-reasoning). Condiciones de medición y análisis en Benchmark Report.
Documentación
| Tarea | Documento |
|---|---|
| Instalación inicial y verificación | Requisitos del sistema, Quick Start, First Memory Flow, INSTALL.md |
| Conexión de clientes | Conexión por cliente, Claude Code, Plugin, Hooks |
| Solución de problemas | Troubleshooting |
| Actualizaciones | Notas de actualización |
| Operación | Revisión de seguridad y operación, Copia de seguridad y recuperación, Monitoreo, Consola de administración |
| Valores de configuración | Configuration |
| Funciones completas | Detalle de funciones, Features |
| Interfaces | API Reference, CLI, SKILL.md |
| Estructura interna | Architecture, Internals |
| Historial de cambios | CHANGELOG |
Licencia
Apache 2.0
Hecho por Jinho Choi | Invítame un café