AI Engineering Academy · Aula

Persistindo o histórico de conversas no Redis e no PostgreSQL

Armazene o histórico de conversas externamente usando RedisChatMessageHistory e PostgresChatMessageHistory para que a memória sobreviva às reinicializações da aplicação e seja dimensionada para várias instâncias.

Aula 4 de 413 etapas

Persistindo o histórico de conversas no Redis e no PostgreSQL é uma aula grátis de AI Engineering Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de AI Engineering Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de AI Engineering Academy inclui 4 aulas no total.

Por que persistir o histórico do chat externamente?

O histórico de conversas mantido na memória desaparece quando sua aplicação é reiniciada ou distribuída entre várias instâncias. A persistência externa resolve três problemas: o histórico sobrevive a falhas, várias instâncias do servidor compartilham o mesmo histórico e você pode carregar sessões anteriores para usuários que retornam. Redis e PostgreSQL são os dois serviços de armazenamento mais populares para isso.

Interface de histórico de mensagens de chat do LangChain

LangChain define uma interface BaseChatMessageHistory com dois métodos: add_message(message) e messages (propriedade). Qualquer sistema de armazenamento que implemente essa interface pode ser usado como memória em qualquer cadeia do LangChain. As implementações para Redis e PostgreSQL seguem essa interface.

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])

Conectando o histórico do Redis a uma cadeia

Envolva sua cadeia com RunnableWithMessageHistory e forneça uma função de fábrica que retorne o objeto de histórico correto para cada sessão. O LangChain carrega automaticamente o histórico antes de cada chamada e salva as novas mensagens após cada resposta.

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'
)

Invocando a cadeia com um ID de sessão

Ao invocar uma cadeia envolvida com um histórico de mensagens, passe o ID da sessão no dicionário config, dentro de configurable. O LangChain direciona automaticamente cada chamada para o armazenamento de histórico correto, portanto Alice e Bob têm históricos de conversa 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.'

Definição de chaves do Redis para o histórico de conversas

O Redis armazena as mensagens de cada sessão como uma lista sob uma chave derivada do ID da sessão. Use um esquema de chaves estruturado, como chat:<app>:<user_id>:<session_id>, para evitar conflitos entre aplicações e permitir uma varredura eficiente por usuário. Defina um TTL para chaves de sessões antigas a fim de impedir o crescimento ilimitado do armazenamento.

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)

Definição da tabela de histórico de conversas no PostgreSQL

Para persistência baseada em SQL, crie uma tabela com colunas para o ID da sessão, a função da mensagem, o conteúdo e o registro de data e hora. O PostgreSQL é ideal quando o histórico de conversas precisa ser consultado, auditado ou associado a dados de contas de usuários. O pacote langchain_postgres fornece uma implementação pronta.

-- 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 no LangChain

A classe PostgresChatMessageHistory de langchain_postgres funciona exatamente como a versão para Redis, mas armazena as mensagens no seu banco de dados PostgreSQL. Passe uma string de conexão e o ID da sessão, e ela cuidará automaticamente da criação da tabela e da serialização das mensagens.

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')

Carregando sessões anteriores para usuários que retornam

Quando um usuário retorna à sua aplicação depois de fechá-la, você pode restaurar a última sessão carregando o histórico do Redis ou do PostgreSQL. Apresente ao usuário um resumo de onde ele parou ou continue de forma transparente, inserindo o histórico armazenado no próximo 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

Reduzindo o histórico no banco de dados

Sessões de longa duração podem acumular milhares de mensagens. Implemente uma estratégia de redução que exclua mensagens mais antigas que um limite ou mantenha apenas as últimas N mensagens no banco de dados. Isso mantém a recuperação rápida e impede que as janelas de contexto transbordem quando você carrega o histórico.

# 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()

Escolhendo entre Redis e PostgreSQL

Ambos os sistemas de armazenamento estão prontos para produção, mas têm pontos fortes diferentes. O Redis oferece leituras em menos de um milissegundo, sendo ideal para conversas em tempo real, nas quais a latência é o fator mais importante. O PostgreSQL oferece consultas SQL completas, transações ACID e integração fácil com seu banco de dados de usuários existente para análises e auditorias. Muitos sistemas de produção usam o Redis como cache principal e o PostgreSQL para arquivamento durável.

Segurança: isolando históricos de vários locatários

Em aplicações com vários locatários, você deve garantir que os usuários não possam acessar os históricos uns dos outros. Sempre inclua o ID do usuário na chave da sessão, valide se o ID da sessão pertence ao usuário autenticado antes de carregar o histórico e nunca exponha chaves de sessão brutas em URLs ou cookies do lado do cliente.

  • Chave correta: chat:app1:user:42:session:abc
  • Chave incorreta: session:abc (previsível, sem escopo de usuário)

Verificação rápida

Teste sua compreensão sobre a persistência externa do histórico de conversas.

Recapitulação da lição

Nesta lição, você aprendeu que: RedisChatMessageHistory armazena o histórico de conversas no Redis com chaves por sessão, PostgresChatMessageHistory permite um armazenamento durável consultável por SQL e RunnableWithMessageHistory conecta qualquer sistema de armazenamento à sua cadeia por meio de uma fábrica session_id. A seguir, vamos nos aprofundar na estrutura ReAct para criar agentes capazes de raciocinar e agir.

Grátis para começar

Aprenda Python com um tutor de IA — grátis

Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.

Cursos
30
Aulas
120

Perguntas Frequentes

A aula “Persistindo o histórico de conversas no Redis e no PostgreSQL” é grátis?

Sim — o texto completo de “Persistindo o histórico de conversas no Redis e no PostgreSQL” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de AI Engineering Academy, atualize para CoddyKit PRO. O curso de AI Engineering Academy inclui 4 aulas no total.

O que vou aprender em “Persistindo o histórico de conversas no Redis e no PostgreSQL”?

Armazene o histórico de conversas externamente usando RedisChatMessageHistory e PostgresChatMessageHistory para que a memória sobreviva às reinicializações da aplicação e seja dimensionada para vária… Você pratica AI Engineering Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar AI Engineering Academy?

Nenhuma experiência prévia é necessária. AI Engineering Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Persistindo o histórico de conversas no Redis e no PostgreSQL”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de AI Engineering Academy?

Sim. Cada aula de AI Engineering Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Por que LLMs sem estado precisam de memória externa
  2. Memória de buffer e de janela
  3. Memória de resumo e truncamento consciente dos tokens
  4. Persistindo o histórico de conversas no Redis e no PostgreSQL
← Voltar para AI Engineering Academy