Memoria para AI Agents: El Framework de 3 Capas que Persiste Contexto Entre Sesiones
Arquitectura de memoria para AI agents: short-term, long-term y episodic memory. Aprende a diseñar sistemas que persisten contexto entre sesiones para agents en producción.
El 90% de los AI Agents Son Amnésicos por Diseño
Hablas con un agente. Te entiende. Resuelve tu problema. Vuelves al día siguiente y no recuerda nada de la conversación anterior. Esta experiencia no es un fallo aislado: es la norma en la industria actual.
El problema real de los AI agents no es la inteligencia. Es la memoria.
La mayoría de implementaciones actuales tratan cada sesión como una pizarra en blanco. Contexto cero entre interacciones. El usuario repite información que ya dió. El sistema vuelve a aprender lo que ya sabía. He visto equipos enteros optimizando prompts, ajustando temperature, cambiando de modelo. Y el agente sigue siendo inútil en la tercera conversación porque arranca desde cero cada vez.
La analogía es clara: un AI agent sin memoria es como un empleado que padece amnesia progresiva. Puede tener un coeficiente intelectual elevado, pero si cada vez que habla con un cliente tiene que volver a preguntarle cómo se llama, qué compró la última vez y qué problema quería resolver, ese empleado es inservible para cualquier tarea que requiera continuidad.
Si estás aprendiendo how to build ai agents 2026, el primer skill que necesitas no es prompt engineering. Es arquitectura de memoria. No importa cuán bueno sea tu prompt si el agente no recuerda lo que hizo hace cinco minutos ni lo que aprendió la semana pasada.
El Problema: La Amnesia Estructural de los LLMs
Los modelos de lenguaje no tienen memoria nativa. Lo sabes. Pero el 90% de los equipos ignoran las implicaciones reales de esta limitación fundamental.
Un LLM recibe un contexto limitado (la ventana de tokens). Cuando la sesión termina, ese contexto desaparece. No hay persistencia. No hay acumulación. No hay aprendizaje entre interacciones. El modelo, por sí mismo, no distingue entre una conversación nueva y la continuación de una anterior. Es, por diseño, un sistema amnésico.
❌ Enfoque típico: Meter todo el historial en el system prompt. Se rompe cuando superas los 8K tokens. El modelo empieza a ignorar el principio del contexto. La calidad de las respuestas se degrada exponencialmente. Es el fenómeno conocido como *lost in the middle*: los LLMs tienden a recordar mejor el principio y el final de un contexto largo, pero pierden información en el medio.
❌ Enfoque aún peor: No hacer nada y asumir que el usuario "ya sabe" que el agente no recuerda. Esto genera una experiencia frustrante que mata la adopción.
✅ Enfoque correcto: Una arquitectura multicapa donde cada tipo de memoria tiene su propósito, su almacenamiento y su estrategia de recuperación.
La memoria no es un detalle de implementación. Es la columna vertebral de cualquier agente que pretenda ser autónomo.
El Framework de 3 Capas para Memoria de AI Agents
Tras enviar varios agents a producción —desde sistemas jurídicos hasta directorios de empresas— he refinado un patrón que funciona. Lo llamo el Patrón de Memoria de 3 Capas.
Cada capa resuelve un problema específico y, lo más importante, cada capa tiene un ciclo de vida, un almacenamiento y una estrategia de recuperación distintos. Mezclarlas o tratarlas como una única "base de datos de memoria" es el error más común que cometen los equipos noveles.
1. Short-Term Memory (Working Memory)
La memoria a corto plazo es el contexto de la sesión activa. Lo que el agente "tiene en mente" mientras mantiene una conversación. Es volátil, efímera y está diseñada para desaparecer cuando la sesión termina.
Almacenamiento: Redis con TTL. O un array en memoria si es single-instance. No necesitas persistencia aquí porque la sesión es efímera. Usar PostgreSQL para esto sería como usar un almacén de archivos históricos para guardar una nota adhesiva.
Estrategia: Sliding window de los últimos N mensajes. No cargues todo el historial. Un agente no necesita recordar el saludo inicial para resolver la petición actual. La ventana debe ser dinámica: si la conversación es técnica y densa, necesitas más contexto reciente. Si es transaccional (un "sí" o un "no"), puedes permitirte ventanas más pequeñas.
```typescript
interface ShortTermMemory {
sessionId: string;
messages: Message[];
activeContext: {
currentGoal: string;
pendingSteps: string[];
extractedEntities: Record<string, string>;
};
maxTokens: number; // 4096 es un buen límite
}
function compressWorkingMemory(memory: ShortTermMemory): string {
// Mantén solo los últimos mensajes hasta alcanzar maxTokens
const recentMessages = memory.messages.slice(-6);
return compressToContext(recentMessages);
}
```
Regla: Si la sesión dura más de 30 minutos o supera los 4K tokens, comprime. No acumules basura conversacional. Una sesión larga no es mejor sesión; es una sesión que probablemente ha perdido el foco.
Un truco adicional: cuando comprimes la working memory, no descartes la información sin más. Extrae un resumen de una línea de lo que se ha cubierto hasta ahora y mantenlo como un "marcador de contexto". Así, si el usuario retoma un tema antiguo, el agente tiene una referencia, aunque los detalles concretos se hayan ido.
2. Long-Term Memory (Persistent Knowledge)
La memoria a largo plazo es todo lo que el agente sabe sobre el usuario, el dominio y las preferencias. Persiste entre sesiones. Se carga al inicio de cada interacción.
Almacenamiento: PostgreSQL (relacional) + vector database (semántico). Usa Supabase o Turso para la parte relacional. Usa pgvector o Pinecone para embeddings. La combinación de ambos es clave: los datos estructurados (nombre, empresa, plan de suscripción) van en SQL. El conocimiento difuso (preferencias, intereses, conocimiento del dominio) va en vectores.
Estrategia de carga: No cargues todo. Carga solo lo relevante para la sesión actual. Usa embeddings para recuperar chunks semánticos. Si el usuario pregunta sobre facturación, no necesitas cargar sus preferencias de color de interfaz. El arte está en saber qué cargar y qué omitir.
```typescript
interface LongTermMemory {
userId: string;
factualMemory: Record<string, any>;
// Datos estructurados: nombre, empresa, preferencias
semanticMemory: VectorEntry[];
// Embeddings de conocimiento del dominio
interactionHistory: SummaryEntry[];
// Resúmenes comprimidos de sesiones anteriores
}
async function loadRelevantMemory(
userId: string,
query: string
): Promise<LongTermMemoryFragment> {
const userContext = await db.user.findUnique({ where: { id: userId }});
const semanticChunks = await vectorDb.search({
query: embed(query),
userId,
limit: 5
});
return {
factual: userContext,
semantic: semanticChunks.map(c => c.content)
};
}
```
Patrón crítico: Cada vez que termina una sesión, extrae facts clave. No guardes el historial completo. Guarda lo importante: decisiones tomadas, preferencias descubiertas, tareas completadas.
Un error frecuente es guardar en long-term memory todo lo que el usuario dice. Esto contamina la memoria con ruido. No todo lo que un usuario dice es un hecho permanente. Si dice "hoy hace calor", no es un dato climático que deba persistir. Si dice "prefiero respuestas en español", eso sí es un hecho relevante.
Implementa un filtro de relevancia antes de persistir: ¿esto es verdadero hoy? ¿Lo será mañana? ¿Afecta al comportamiento futuro del agente? Si la respuesta a las tres es "sí", persiste. Si no, déjalo en la sesión y que se borre.
3. Episodic Memory (Experiential Context)
La memoria episódica es lo que diferencia un agente que "sabe" de un agente que "aprende". No es información factual. Es experiencia acumulada: qué funcionó, qué falló, cómo reaccionó el usuario.
Mientras que la long-term memory responde a la pregunta "¿qué sabe el agente sobre este usuario?", la episodic memory responde a "¿qué ha aprendido el agente de interacciones previas?". Esta distinción es sutil pero fundamental.
Almacenamiento: Base de datos temporal con marcado de relevancia. No todo episodio merece persistencia. Los episodios se almacenan con un campo de relevancia que se actualiza cada vez que el patrón se repite.
Estrategia: Después de cada interacción significativa —un error, un éxito, una corrección del usuario— guarda un resumen estructurado del episodio. No guardes la interacción completa; guarda la lección aprendida.
```typescript
interface EpisodicMemory {
agentId: string;
episodes: Episode[];
}
interface Episode {
timestamp: Date;
trigger: 'error' | 'success' | 'correction' | 'milestone';
context: string; // Resumen de 200 chars máximo
outcome: string;
lessonLearned: string;
relevance: number; // 0-1, se incrementa con repetición
}
async function storeEpisode(
agent: string,
episode: Omit<Episode, 'timestamp'>
): Promise<void> {
// Si el mismo patrón aparece 3+ veces, sube automaticamente a long-term
const similar = await findSimilarEpisodes(agent, episode);
if (similar.length >= 3) {
await promoteToLongTerm(agent, episode);
}
await db.episodic.create({
data: { agentId: agent, ...episode, timestamp: new Date() }
});
}
```
La memoria episódica es el verdadero diferenciador. Sin ella, tu agente comete el mismo error cada vez que un usuario hace la misma pregunta. Con ella, aprende y mejora con cada interacción.
Imagina un agente de soporte técnico. Sin memoria episódica, cada vez que un usuario reporta un error concreto, el agente sigue el mismo procedimiento genérico. Con memoria episódica, recuerda que la última vez que alguien reportó ese error, la solución era reiniciar el servicio X, no seguir el manual estándar. Ese conocimiento no está en la documentación; está en la experiencia acumulada.
El sistema de promoción es igualmente importante: cuando un patrón se repite tres o más veces, el episodio merece promoverse a long-term memory. Deja de ser una anécdota y se convierte en conocimiento consolidado.
El Ciclo de Vida de la Memoria: Cómo Conectar las 3 Capas
El poder del patrón no está en las capas individuales. Está en cómo se conectan. Una arquitectura de memoria no es una pila de almacenes inconexos; es un sistema orquestado donde la información fluye entre capas según su relevancia y madurez.
Flujo completo de una interacción:
1. Inicio de sesión: Carga Long-Term Memory del usuario (facts + embeddings). Identifica al usuario mediante algún identificador (JWT, API key, cookie de sesión).
2. Durante la conversación: Short-Term Memory mantiene el contexto activo. Cada mensaje se añade a la ventana deslizante. Si la sesión se alarga, se comprime.
3. Cuando ocurre algo significativo: Guarda un episodio en Episodic Memory. ¿El usuario corrigió al agente? Eso es un episodio. ¿El agente resolvió un problema complejo? Eso es un episodio. ¿El usuario repitió la misma pregunta tres veces? Eso también es un episodio, y de los importantes.
4. Al finalizar la sesión: Comprime el historial, extrae nuevos facts, actualiza Long-Term Memory. Es el momento de "dormir" y consolidar lo aprendido.
5. Entre sesiones: Consulta Episodic Memory para detectar patrones recurrentes. Un trabajo batch nocturno puede analizar episodios y promover los patrones repetidos a long-term memory.
```typescript
class AgentMemorySystem {
private shortTerm: ShortTermMemory;
private longTerm: LongTermMemory;
private episodic: EpisodicMemory;
async handleMessage(userId: string, message: string): Promise<string> {
// 1. Cargar memoria relevante
const context = await this.loadSessionContext(userId);
// 2. Preparar prompt con las 3 capas
const prompt = this.buildPrompt({
workingMemory: this.shortTerm.compress(),
longTermContext: context.longTerm,
episodicExamples: context.relevantEpisodes
});
// 3. Procesar con el LLM
const response = await this.llm.generate(prompt);
// 4. Actualizar short-term memory
this.shortTerm.addMessage({ role: 'user', content: message });
this.shortTerm.addMessage({ role: 'assistant', content: response });
// 5. Evaluar si hay episodio que guardar
if (this.detectsSignificantEvent(message, response)) {
await this.episodic.storeEpisode(userId, {
trigger: this.classifyEvent(message, response),
context: this.summarizeInteraction(message, response),
outcome: response,
lessonLearned: this.extractLesson(message, response)
});
}
return response;
}
private buildPrompt(context: any): string {
return `
[CURRENT GOAL]
${context.workingMemory.activeGoal}
[USER KNOWLEDGE]
${context.longTermContext.factual}
[RELEVANT PAST EXPERIENCES]
${context.episodicExamples.map(e => `- ${e.lessonLearned}`).join('\n')}
[RECENT CONVERSATION]
${context.workingMemory.recentMessages}
`.trim();
}
}
```
El método `detectsSignificantEvent` es crucial. No implementes esto como una simple comprobación de palabras clave. Un evento significativo puede ser: que el usuario muestre frustración, que el agente necesite cambiar de estrategia, que se complete una subtarea importante, o que el usuario proporcione información que contradiga un hecho almacenado en long-term memory.
Cómo Implementarlo Hoy (Sin Morir en el Intento)
No necesitas una arquitectura compleja para empezar. Necesitas las piezas correctas. El error más común es intentar construir un sistema de memoria perfecto desde el día uno. No lo hagas. Empieza con short-term memory, añade long-term memory cuando la necesites, y deja la episodic memory para cuando tengas suficientes datos de interacción.
Stack recomendado para implementar how to build ai agents 2026 con memoria real:
LLM: Claude API o GPT-4o (ventanas de contexto grandes ayudan, pero no resuelven el problema de persistencia). Un modelo con 128K de contexto no elimina la necesidad de memoria; solo disimula la mala arquitectura durante más tiempo.
Base de datos relacional: Supabase (PostgreSQL) para long-term memory estructurada. Es barato, escalable y tiene pgvector integrado.
Vector store: pgvector en el mismo Supabase (evita tener dos bases de datos). Si tu volumen de embeddings es pequeño (< 10.000), no necesitas Pinecone.
Cache efímero: Redis Upstash para short-term memory con TTL. La capa gratuita es suficiente para empezar.
Embeddings: OpenAI text-embedding-3-small o Voyage AI. El modelo pequeño de OpenAI es rentable y preciso para la mayoría de casos.
Reglas de oro:
1. Comprime siempre: No guardes logs enteros. Guarda resúmenes y facts extraídos. Un buen resumen de sesión no debería ocupar más de 500 tokens.
2. Prioriza relevancia sobre cantidad: 5 facts bien extraídos valen más que 500 líneas de historial. La memoria no es un vertedero; es un archivo curado.
3. Distingue entre olvido y archivo: La short-term memory se borra. La long-term se actualiza. La episódica se consulta por patrón. No mezcles los ciclos de vida.
4. Mide el impacto: Si tu agente responde igual con o sin memoria, tu sistema de memoria está mal diseñado. Define métricas claras: tasa de repetición de preguntas, tiempo hasta resolución, satisfacción del usuario en la segunda interacción.
5. Implementa la memoria por fases: No intentes las tres capas desde el día uno. Empieza con short-term. Cuando veas que los usuarios repiten información entre sesiones, añade long-term. Cuando detectes que el agente comete los mismos errores, añade episodic.
El Futuro es Recordar
La próxima generación de AI agents no se medirá por lo bien que responden una pregunta aislada. Los benchmarks actuales de QA están desfasados: miden capacidad de respuesta, no capacidad de relación.
Se medirá por lo bien que recuerdan quién eres, qué necesitas y cómo has cambiado desde la última vez que hablaste.
No se trata solo de persistencia técnica. Se trata de continuidad experiencial. Un agente con buena memoria no solo recuerda tus datos; recuerda tu tono, tus frustraciones, tus preferencias no dichas. Y con cada interacción, refina ese conocimiento.
El salto cualitativo llegará cuando los sistemas de memoria no sean un añadido externo, sino un componente nativo de los modelos. Pero hasta entonces, la responsabilidad recae en los arquitectos de sistemas. En vosotros.
Cuando entiendes que la memoria no es un feature sino la fundación del agente autónomo, dejas de preguntarte qué modelo usar. Empiezas a preguntarte qué debe recordar.
Esa pregunta cambia todo.
Lee el artículo completo en brianmenagomez.com
Más sobre mis servicios en brianmenagomez.com
Herramientas: Conversor IAE CNAE · Gestorias cerca de ti · Calculadora IRPF

