Tipos de memoria en LangGraph: corto y largo plazo
Concepto clave
En LangGraph, la memoria no es un concepto unitario sino un sistema estratificado que permite a los agentes de IA mantener y acceder a información de manera diferenciada. La memoria a corto plazo (short-term memory) se refiere al estado inmediato y transitorio que persiste durante una sola ejecución o sesión de interacción. Es análogo a la memoria de trabajo humana: almacena información relevante para la tarea actual, como el contexto de la conversación o los resultados intermedios de herramientas, pero se reinicia cuando el agente finaliza su ejecución.
La memoria a largo plazo (long-term memory), en contraste, es persistente y sobrevive entre múltiples ejecuciones del agente. Funciona como una base de conocimiento acumulativo, similar a la memoria episódica o semántica en humanos. En LangGraph, esto se implementa típicamente mediante almacenamiento externo como bases de datos (SQL, vectoriales) o sistemas de archivos, permitiendo que el agente "recuerde" interacciones pasadas, preferencias del usuario o aprendizajes derivados de ejecuciones anteriores.
"La memoria a corto plazo gestiona el 'aquí y ahora', mientras que la memoria a largo plazo construye la identidad y experiencia del agente a lo largo del tiempo."
Cómo funciona en la práctica
En LangGraph, la memoria se gestiona a través del estado del grafo (graph state), que es un diccionario mutable compartido entre todos los nodos. Para la memoria a corto plazo, se utilizan variables de estado como messages o context que se actualizan durante la ejecución pero no se persisten automáticamente. Por ejemplo, en un agente conversacional, el historial de mensajes recientes se almacena en memoria a corto plazo para mantener coherencia en el diálogo.
Para implementar memoria a largo plazo, LangGraph se integra con sistemas de persistencia. Un flujo típico incluye:
- Definir un esquema de estado que incluya campos para datos persistentes (ej.,
user_id,session_history). - Configurar checkpointers que serialicen y guarden el estado en una base de datos al final de cada ejecución.
- Implementar lógica de recuperación que cargue el estado persistente al iniciar una nueva ejecución, basándose en identificadores únicos.
Ejemplo de código para memoria a corto plazo:
from langgraph.graph import StateGraph, END
from typing import TypedDict
class AgentState(TypedDict):
messages: list # Memoria a corto plazo: historial de conversación
tool_results: dict # Resultados recientes de herramientas
def process_message(state: AgentState):
# Lógica que usa y actualiza la memoria a corto plazo
state['messages'].append({"role": "assistant", "content": "Respuesta generada"})
return stateCaso de estudio
Consideremos un agente de soporte técnico avanzado construido con LangGraph. Este agente usa herramientas para diagnosticar problemas, memoria a corto plazo para seguir el flujo de la conversación actual, y memoria a largo plazo para recordar interacciones previas con el mismo usuario.
Implementación:
- Memoria a corto plazo: Almacena el historial de mensajes de la sesión actual en el estado del grafo, permitiendo referencias a respuestas anteriores dentro del mismo ticket.
- Memoria a largo plazo: Usa una base de datos SQLite para persistir el ID de usuario, problemas resueltos anteriormente, y preferencias de comunicación. Al iniciar una nueva interacción, el agente carga este historial y ajusta su comportamiento (ej., evitando soluciones ya intentadas).
Tabla de datos de ejemplo en memoria a largo plazo:
| user_id | issue_type | resolution_date | preferred_language |
|---|---|---|---|
| U123 | login_error | 2024-01-15 | español |
| U456 | payment_failed | 2024-01-20 | inglés |
Este enfoque reduce el tiempo de resolución en un 30% al evitar repeticiones y personalizar respuestas.
Errores comunes
- Confundir persistencia con serialización: Asumir que guardar el estado en un archivo JSON es suficiente para memoria a largo plazo, sin considerar escalabilidad o concurrencia. Solución: Usar bases de datos apropiadas (ej., PostgreSQL para datos relacionales, Chroma para embeddings).
- Sobrecargar la memoria a corto plazo: Almacenar todo el historial de conversación en memoria RAM, causando lentitud o caídas en sesiones largas. Solución: Implementar ventanas deslizantes o resúmenes para limitar el tamaño.
- Ignorar la consistencia en memoria a largo plazo: No manejar casos donde múltiples ejecuciones del agente actualicen los mismos datos persistentes, llevando a condiciones de carrera. Solución: Usar transacciones o mecanismos de bloqueo en el almacenamiento.
- No definir claramente los límites temporales: Tratar datos que deberían ser transitorios (ej., tokens temporales) como persistentes, o viceversa. Solución: Documentar el ciclo de vida de cada variable de estado en el diseño.
Checklist de dominio
- He diseñado un esquema de estado que distingue explícitamente entre variables para memoria a corto y largo plazo.
- He implementado checkpointers para persistir el estado en una base de datos externa y recuperarlo en ejecuciones posteriores.
- He probado que la memoria a corto plazo se reinicia adecuadamente entre sesiones independientes.
- He asegurado que la memoria a largo plazo maneja correctamente identificadores únicos (ej., user_id) para asociar datos.
- He optimizado el tamaño de la memoria a corto plazo para evitar problemas de rendimiento.
- He documentado la estrategia de persistencia y los sistemas de almacenamiento utilizados.
- He considerado la privacidad y seguridad de los datos almacenados en memoria a largo plazo (ej., enmascaramiento, cifrado).
Implementa un agente con memoria dual para gestión de tareas
En este ejercicio, construirás un agente de LangGraph que gestione una lista de tareas, usando memoria a corto plazo para la sesión actual y memoria a largo plazo para el historial de tareas completadas. Sigue estos pasos:
- Configuración inicial: Crea un entorno Python con LangGraph instalado. Define un esquema de estado TypedDict que incluya:
current_tasks: lista de tareas activas (memoria a corto plazo).completed_tasks_history: lista de tareas completadas (memoria a largo plazo, a persistir).user_id: identificador para recuperación persistente.
- Grafo de flujo: Implementa un StateGraph con dos nodos:
add_task: Añade una nueva tarea acurrent_tasks.complete_task: Mueve una tarea decurrent_tasksacompleted_tasks_historyy actualiza la base de datos.
- Persistencia: Integra SQLite para memoria a largo plazo. Al inicio, carga
completed_tasks_historydesde la base de datos basado enuser_id. Al completar una tarea, guarda el estado actualizado. - Pruebas: Ejecuta el agente múltiples veces con el mismo
user_idy verifica que el historial de tareas completadas persiste entre ejecuciones, mientras quecurrent_tasksse reinicia.
Pistas
- Usa el modulo sqlite3 de Python para la base de datos; considera crear una tabla con columnas user_id, task_description, y completion_date.
- En el nodo complete_task, asegurate de remover la tarea de current_tasks y añadirla a completed_tasks_history antes de persistir.
- Para simular múltiples ejecuciones, puedes usar un script que llame al grafo, luego termine el proceso y lo reinicie.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.