AI Engineering Academy · Lección

Persistencia del historial de chat en Redis y PostgreSQL

Almacenará externamente el historial de conversaciones mediante RedisChatMessageHistory y PostgresChatMessageHistory para que la memoria sobreviva a los reinicios de la aplicación y escale entre varias instancias.

Lección 4 de 413 pasos

Persistencia del historial de chat en Redis y PostgreSQL es una lección gratuita de AI Engineering Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de AI Engineering Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de AI Engineering Academy incluye 4 lecciones en total.

¿Por qué persistir externamente el historial del chat?

El historial de conversaciones almacenado en memoria desaparece cuando la aplicación se reinicia o se escala a varias instancias. La persistencia externa resuelve tres problemas: el historial sobrevive a los fallos, varias instancias del servidor comparten el mismo historial y puede cargar sesiones anteriores para los usuarios que regresan. Redis y PostgreSQL son los dos backends más populares para este fin.

Interfaz de historial de mensajes de chat de LangChain

LangChain define una interfaz BaseChatMessageHistory con dos métodos: add_message(message) y messages (propiedad). Cualquier backend de almacenamiento que implemente esta interfaz puede incorporarse como memoria en cualquier cadena de LangChain. Tanto las implementaciones para Redis como para PostgreSQL siguen esta interfaz.

from langchain_community.chat_message_histories import RedisChatMessageHistory

# Each unique session_id gets its own history namespace
history = RedisChatMessageHistory(
    session_id='user:alice:session:42',
    url='redis://localhost:6379'
)

# Add messages
history.add_user_message('What is RAG?')
history.add_ai_message('RAG stands for Retrieval-Augmented Generation...')

# Retrieve stored messages
for msg in history.messages:
    print(msg.type, ':', msg.content[:50])

Conectar el historial de Redis a una cadena

Envuelva su cadena con RunnableWithMessageHistory y proporcione una función de fábrica que devuelva el objeto de historial correcto para cada sesión. LangChain carga automáticamente el historial antes de cada llamada y guarda los mensajes nuevos después de cada respuesta.

from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import RedisChatMessageHistory
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

llm = ChatOpenAI(model='gpt-4o-mini')
prompt = ChatPromptTemplate.from_messages([
    ('system', 'You are a helpful assistant.'),
    MessagesPlaceholder(variable_name='history'),
    ('human', '{input}')
])

chain = prompt | llm

chain_with_history = RunnableWithMessageHistory(
    chain,
    lambda session_id: RedisChatMessageHistory(
        session_id=session_id,
        url='redis://localhost:6379'
    ),
    input_messages_key='input',
    history_messages_key='history'
)

Invocar la cadena con un ID de sesión

Cuando invoque una cadena envuelta con un historial de mensajes, pase el ID de sesión en el diccionario config, dentro de configurable. LangChain dirige automáticamente cada llamada al almacén de historial correcto, de modo que Alice y Bob tienen historiales de conversación completamente separados.

# First turn for session alice-001
response = chain_with_history.invoke(
    {'input': 'My name is Alice.'},
    config={'configurable': {'session_id': 'alice-001'}}
)
print(response.content)

# Second turn — the chain remembers Alice's name from Redis
response = chain_with_history.invoke(
    {'input': 'What is my name?'},
    config={'configurable': {'session_id': 'alice-001'}}
)
print(response.content)  # Should say 'Your name is Alice.'

Diseño de claves de Redis para el historial del chat

Redis almacena los mensajes de cada sesión como una lista bajo una clave derivada del ID de sesión. Use un esquema de claves estructurado como chat:<app>:<user_id>:<session_id> para evitar colisiones entre aplicaciones y permitir un escaneo eficiente por usuario. Establezca un TTL para las claves de sesiones antiguas a fin de evitar un crecimiento ilimitado del almacenamiento.

import redis

r = redis.Redis.from_url('redis://localhost:6379')

# List all chat sessions for user alice
keys = r.keys('message_store:alice-*')
print('Active sessions:', len(keys))

# Set a 30-day TTL on a session to auto-expire old history
for key in keys:
    r.expire(key, 60 * 60 * 24 * 30)

Diseño de la tabla de historial de chat en PostgreSQL

Para la persistencia basada en SQL, cree una tabla con columnas para el ID de sesión, el rol del mensaje, el contenido y la marca de tiempo. PostgreSQL es ideal cuando necesita consultar o auditar el historial del chat, o combinarlo con los datos de las cuentas de usuario. El paquete langchain_postgres proporciona una implementación lista para usar.

-- SQL table for storing chat messages
CREATE TABLE chat_messages (
    id          SERIAL PRIMARY KEY,
    session_id  TEXT NOT NULL,
    role        TEXT NOT NULL,   -- 'human' or 'ai'
    content     TEXT NOT NULL,
    created_at  TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_chat_session ON chat_messages (session_id, created_at);

PostgresChatMessageHistory en LangChain

La clase PostgresChatMessageHistory de langchain_postgres funciona igual que la versión para Redis, pero almacena los mensajes en su base de datos PostgreSQL. Pase una cadena de conexión y un ID de sesión; la clase se encargará automáticamente de crear la tabla y serializar los mensajes.

from langchain_postgres import PostgresChatMessageHistory
import psycopg

CONNECTION_STRING = 'postgresql://user:pass@localhost:5432/mydb'

# Create history object for a session
history = PostgresChatMessageHistory(
    table_name='chat_messages',
    session_id='alice-001',
    connection=psycopg.connect(CONNECTION_STRING)
)

history.add_user_message('Tell me about embeddings.')
history.add_ai_message('Embeddings are dense vector representations...')

print(f'Stored {len(history.messages)} messages')

Cargar sesiones anteriores para usuarios que regresan

Cuando un usuario regrese a su aplicación después de cerrarla, puede restaurar su última sesión cargando el historial desde Redis o PostgreSQL. Muestre al usuario un resumen del punto en el que se quedó o continúe sin interrupciones inyectando el historial almacenado en el siguiente prompt.

def get_or_create_history(user_id: str, session_id: str):
    history = RedisChatMessageHistory(
        session_id=f'{user_id}:{session_id}',
        url='redis://localhost:6379'
    )
    if history.messages:
        print(f'Resuming session with {len(history.messages)} messages.')
    else:
        print('Starting a new session.')
    return history

Recortar el historial en la base de datos

Las sesiones de larga duración pueden acumular miles de mensajes. Implemente una estrategia de recorte que elimine los mensajes anteriores a un límite temporal o conserve únicamente los últimos N mensajes en la base de datos. Esto mantiene la recuperación rápida y evita que las ventanas de contexto se desborden al cargar el historial.

# Keep only the last 20 messages per session in PostgreSQL
CLEAN_SQL = '''
    DELETE FROM chat_messages
    WHERE session_id = %s
    AND id NOT IN (
        SELECT id FROM chat_messages
        WHERE session_id = %s
        ORDER BY created_at DESC
        LIMIT 20
    )
'''

def trim_session(conn, session_id: str, keep_last: int = 20):
    with conn.cursor() as cur:
        cur.execute(CLEAN_SQL, (session_id, session_id))
    conn.commit()

Elegir entre Redis y PostgreSQL

Ambos backends están preparados para producción, pero tienen fortalezas diferentes. Redis ofrece lecturas en menos de un milisegundo, por lo que es ideal para chats en tiempo real donde la latencia es lo más importante. PostgreSQL ofrece capacidad completa de consulta mediante SQL, transacciones ACID y una integración sencilla con su base de datos de usuarios existente para análisis y auditorías. Muchos sistemas de producción usan Redis como caché principal y PostgreSQL para el archivado duradero.

Seguridad: aislar historiales de varios inquilinos

En las aplicaciones multiinquilino, debe asegurarse de que los usuarios no puedan acceder a los historiales de los demás. Incluya siempre el ID de usuario en la clave de sesión, valide que el ID de sesión pertenece al usuario autenticado antes de cargar el historial y nunca exponga claves de sesión sin procesar en las URL ni en las cookies del cliente.

  • Clave correcta: chat:app1:user:42:session:abc
  • Clave incorrecta: session:abc (predecible y sin ámbito de usuario)

Comprobación rápida

Compruebe cuánto entiende sobre la persistencia externa del historial del chat.

Resumen de la lección

En esta lección ha aprendido que RedisChatMessageHistory almacena el historial del chat en Redis mediante claves por sesión, que PostgresChatMessageHistory permite un almacenamiento duradero consultable mediante SQL y que RunnableWithMessageHistory conecta cualquier backend a su cadena mediante una fábrica basada en session_id. A continuación, profundizaremos en el framework ReAct para crear agentes capaces de razonar y actuar.

Gratis para empezar

Aprende Python con un tutor de IA — gratis

Escribe y ejecuta código real en tu navegador, obtén ayuda instantánea de un tutor de IA disponible 24/7 y continúa donde lo dejaste en la web o en la aplicación.

Cursos
30
Lecciones
120

Preguntas frecuentes

¿La lección «Persistencia del historial de chat en Redis y PostgreSQL» es gratis?

Sí — el texto completo de «Persistencia del historial de chat en Redis y PostgreSQL» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de AI Engineering Academy, actualiza a CoddyKit PRO. El curso de AI Engineering Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Persistencia del historial de chat en Redis y PostgreSQL»?

Almacenará externamente el historial de conversaciones mediante RedisChatMessageHistory y PostgresChatMessageHistory para que la memoria sobreviva a los reinicios de la aplicación y escale entre vari… Practicas AI Engineering Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar AI Engineering Academy?

No se requiere experiencia previa. AI Engineering Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Persistencia del historial de chat en Redis y PostgreSQL»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de AI Engineering Academy?

Sí. Cada lección de AI Engineering Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Por qué los LLM sin estado necesitan memoria externa
  2. Memoria de buffer y de ventana
  3. Memoria de resumen y truncamiento consciente de los tokens
  4. Persistencia del historial de chat en Redis y PostgreSQL
← Volver a AI Engineering Academy