Búsqueda y Recuperación de Memorias
El motor de búsqueda: SQLite FTS5
Engram usa FTS5 (Full Text Search 5), el motor de búsqueda de texto completo de SQLite, para indexar todas las memorias. FTS5 es una extensión de SQLite que permite búsquedas de texto completo con relevancia ponderada sobre millones de registros sin configuración adicional.
Lo que FTS5 indexa de cada observación:
title— título de la memoriacontent— contenido completo en formato What/Why/Where/Learnedtool_name— nombre de la herramienta que creó la memoriatype— categoría (bugfix, architecture, pattern, etc.)project— nombre del proyecto
Esto significa que una búsqueda como "JWT expired session" puede encontrar memorias donde esas palabras aparecen en cualquier campo, con relevancia calculada automáticamente.
La herramienta mem_search
mem_search es la herramienta de búsqueda principal:
mem_search(
q: string, # consulta de búsqueda
type?: string, # filtrar por tipo (bugfix, architecture, etc.)
project?: string, # filtrar por proyecto (override del auto-detectado)
scope?: string, # "project" o "personal"
limit?: number # número máximo de resultados (default: 10)
)
Ejemplos de búsquedas:
# Buscar todo relacionado con autenticación
mem_search(q="autenticación JWT")
# Solo bugs relacionados con la base de datos
mem_search(q="database connection pool", type="bugfix")
# Decisiones de arquitectura sobre el módulo de pagos
mem_search(q="pagos stripe", type="architecture")
# Con límite específico
mem_search(q="rate limiting", limit=5)
La respuesta devuelve resultados compactos con ID, título, tipo, fecha y un extracto del contenido (truncado para ahorrar tokens). Cada resultado incluye el observation_id que puedes usar para profundizar.
El patrón de 3 capas: Progressive Disclosure
El principio más importante para recuperar memorias eficientemente es Progressive Disclosure: no vuelques toda la información de golpe, profundiza en capas según lo que necesitas.
flowchart LR
L1["Capa 1: mem_search<br/>~100 tokens por resultado<br/>Lista compacta con IDs"] --> L2
L2["Capa 2: mem_timeline<br/>Contexto temporal<br/>¿Qué pasó antes y después?"] --> L3
L3["Capa 3: mem_get_observation<br/>Contenido completo<br/>Sin truncar"]
Este patrón es eficiente en tokens porque:
- Primero obtienes una lista de candidatos compactos (Capa 1)
- Si necesitas contexto de cómo evolucionó una memoria, usas el timeline (Capa 2)
- Solo cuando identificas exactamente lo que necesitas, cargas el contenido completo (Capa 3)
Ejemplo del patrón en acción:
# Capa 1: ¿Hay algo sobre el bug de autenticación?
mem_search(q="auth middleware 401 error")
# Resultado: [id=42, "Fixed 401 race condition in auth middleware", 2026-01-15]
# Capa 2: ¿Qué pasó alrededor de esa sesión?
mem_timeline(observation_id=42, before=5, after=3)
# Resultado: contexto de las 5 memorias previas y 3 posteriores en esa sesión
# Capa 3: ¿Cuál es el detalle completo?
mem_get_observation(id=42)
# Resultado: contenido completo sin truncar
Esta secuencia usa significativamente menos tokens que cargar el contenido completo de todos los resultados de búsqueda directamente.
mem_context: el contexto de bienvenida
mem_context es diferente a mem_search. No busca por query — recupera el contexto más reciente del proyecto actual, diseñado para ser inyectado automáticamente al inicio de cada sesión.
mem_context(
project?: string, # override del proyecto auto-detectado
scope?: string # "project", "personal", o ambos
)
La respuesta incluye:
- El resumen de la última sesión completada (de
mem_session_summary) - Las memorias más recientes del proyecto
- Estadísticas básicas del proyecto (cuántas memorias hay)
Esto es lo que el agente debería llamar al inicio de cada conversación, antes de hacer cualquier otra cosa. Con el plugin instalado, esta llamada ocurre automáticamente.
¿Por qué mem_context en lugar de mem_search?
mem_context está optimizado para el “inicio de sesión”: devuelve información reciente que probablemente sea relevante sin requerir que el agente conozca qué buscar. Es el equivalente a leer las notas del día anterior antes de empezar a trabajar.
mem_search se usa cuando el agente sabe qué está buscando: “recuerdo que había un bug con el rate limiter, búscalo”.
mem_timeline: contexto cronológico
mem_timeline devuelve memorias en orden cronológico alrededor de una observación específica:
mem_timeline(
observation_id: number, # ID de la observación central
before?: number, # cuántas memorias antes (default: 5)
after?: number # cuántas memorias después (default: 5)
)
Esto es valioso cuando quieres entender no solo una memoria sino el contexto de trabajo en el que fue creada. Si encuentras un bugfix del 15 de enero, el timeline te muestra qué más estaba pasando ese día: qué decisiones se tomaron antes del bug, qué se descubrió después de solucionarlo.
Caso de uso típico:
Estás trabajando en el módulo de autenticación y encuentras una memoria sobre un bug de JWT. El timeline te muestra que ese bug fue descubierto después de migrar de HS256 a RS256, y que después del fix se agregó una prueba de integración específica. Sin el timeline, solo verías el bug aislado. Con el timeline, ves la narrativa completa.
mem_get_observation: el contenido completo
Cuando sabes exactamente qué observación necesitas (por su ID), mem_get_observation devuelve el contenido completo sin ningún truncamiento:
mem_get_observation(id: number)
Esta es la herramienta para la Capa 3 del patrón de Progressive Disclosure. La usas cuando ya identificaste la memoria correcta y necesitas todos los detalles.
Búsqueda desde la CLI
Además de las herramientas MCP, puedes buscar memorias directamente desde la terminal sin ningún agente:
# Búsqueda básica
engram search "autenticación JWT"
# Ver contexto del proyecto actual
engram context
# Ver la línea de tiempo de una observación
engram timeline 42
# Estadísticas del proyecto
engram stats
La CLI usa la misma base de datos SQLite que el servidor MCP, así que los resultados son idénticos a los que vería el agente.
El estado de sesiones y proyectos
mem_stats devuelve estadísticas del sistema de memoria:
mem_stats(project?: string)
Respuesta típica:
{
"project": "mi-proyecto",
"observations_total": 142,
"observations_project": 98,
"observations_personal": 44,
"sessions_total": 23,
"sessions_completed": 20,
"top_types": [
{"type": "bugfix", "count": 45},
{"type": "architecture", "count": 28},
{"type": "pattern", "count": 25}
]
}
Esto te da una idea de cuánto conocimiento has acumulado. 142 observaciones en 23 sesiones significa un promedio de ~6 memorias por sesión, que es razonable para trabajo significativo.
La API HTTP para búsquedas programáticas
Si quieres buscar memorias desde scripts o herramientas externas, el servidor HTTP expone el mismo motor de búsqueda:
# Iniciar el servidor HTTP
engram serve
# Buscar via HTTP
curl "http://localhost:7437/search?q=autenticacion+JWT&type=bugfix&limit=5"
# Obtener contexto del proyecto
curl "http://localhost:7437/context?project=mi-proyecto"
# Obtener una observación específica
curl "http://localhost:7437/observations/42"
El servidor HTTP también expone endpoints para gestión de sesiones, exportación/importación, estadísticas, y sincronización. Es útil para integraciones con CI/CD o herramientas de documentación.
Gestión de proyectos múltiples
Si trabajas en varios proyectos, Engram detecta automáticamente cuál es el activo basándose en el directorio donde el servidor MCP está corriendo. Sin embargo, puede haber casos donde el mismo proyecto tiene nombres ligeramente distintos (por ejemplo, si en algún momento el repo cambió de nombre).
mem_merge_projects consolida dos nombres de proyecto en uno canónico:
mem_merge_projects(
old_project: "mi-proyecto-v2",
new_project: "mi-proyecto"
)
Esto mueve todas las observaciones del nombre antiguo al nuevo. Útil después de renombrar un repo o cuando tienes memorias fragmentadas entre variantes del mismo nombre.
La función mem_current_project también ayuda aquí — te dice exactamente qué nombre detectó Engram y qué método usó, para que puedas identificar inconsistencias temprano.
Cuándo buscar vs cuándo confiar en mem_context
Una duda común es cuándo usar mem_search y cuándo basta con mem_context. La regla práctica:
| Situación | Herramienta |
|---|---|
| Inicio de sesión, sin saber por dónde empezar | mem_context |
| Trabajando en algo específico y recordando que “había algo sobre X” | mem_search |
| Quieres ver cómo evolucionó una decisión | mem_timeline + mem_get_observation |
| Necesitas explorar todo el conocimiento del proyecto | mem_search con queries amplias + mem_stats |
| Verificar que el proyecto fue detectado correctamente | mem_current_project |
La combinación de mem_context al inicio + mem_search cuando surge una duda específica + mem_timeline/mem_get_observation para profundizar cubre el 95% de los casos de uso de recuperación de memoria.
En el próximo capítulo veremos cómo compartir estas memorias entre máquinas con Git Sync y la integración cloud opcional de Engram.