Início
» Domínios
»
Como Corrigir a Perda de Memória do Agente LangChain em Conversas Longas
Como Corrigir a Perda de Memória do Agente LangChain em Conversas Longas
Se um agente LangChain esquecer detalhes durante uma conversa longa, corrija a arquitetura antes de aumentar a janela de contexto do modelo. Nos agentes atuais no estilo LangChain v1, a continuidade da conversa é construída a partir de duas camadas separadas: um checkpointer para estado de curto prazo com escopo de thread e um store para informações de longo prazo que devem sobreviver entre threads. Conversas longas então exigem uma terceira preocupação: gerenciamento de contexto, geralmente aparando ou resumindo mensagens antigas antes que elas sobrecarreguem o modelo.
Este guia segue a documentação oficial do LangChain verificada em 11 de setembro de 2026. A documentação atual recomenda langchain.agents.create_agent para novos agentes e descreve a persistência do LangGraph como o sistema de memória subjacente. Exemplos antigos baseados em ConversationChain, ConversationBufferMemory ou initialize_agent ainda podem aparecer em material legado, mas o guia de migração do LangChain v1 moveu chains legadas e outras funcionalidades depreciadas para langchain-classic. Veja o guia oficial de migração do LangChain v1.
Ilustração gerada por IA: O sintoma é simples: um fato foi fornecido anteriormente, mas uma resposta posterior não o utiliza mais. A ilustração é conceitual, não uma interface capturada do LangChain.
O Que “Perda de Memória” Realmente Significa no LangChain
Antes de alterar o código, separe três problemas que frequentemente parecem idênticos do ponto de vista do usuário.
Sintoma
Causa provável
Camada correta para corrigir
O agente esquece após o reinício do servidor
O estado foi armazenado apenas na memória do processo
Checkpointer ou store persistente
O agente esquece entre duas requisições no mesmo chat
Nenhum checkpointer, ou um thread_id diferente foi usado
Persistência de thread
O agente lembra dos turnos iniciais no armazenamento, mas para de usá-los em chats muito longos
O contexto do modelo ficou grande demais ou ruidoso
Resumificação, aparar, recuperação
O agente lembra de uma preferência em um chat, mas não em um novo chat
Ilustração gerada por IA: Pense na memória de curto prazo como o estado de uma thread de conversa. O LangChain atual implementa essa continuidade através de um checkpointer, em vez das classes de memória legadas frequentemente mostradas em tutoriais antigos.
O Que Você Precisa Antes de Começar
Você precisa de uma aplicação LangChain/LangGraph atual, uma integração de modelo e um lugar para persistir o estado. Para um experimento local, InMemorySaver é suficiente. Para produção, use um checkpointer baseado em banco de dados. A documentação oficial do LangChain mostra PostgreSQL através do pacote separado langgraph-checkpoint-postgres.
Mantenha quatro identificadores claros:
ID de conversa ou chat: o identificador que sua aplicação expõe aos usuários.
thread_id: a chave de persistência do LangGraph usada para retomar o estado de uma thread.
ID de usuário: a identidade durável usada para namespacear memórias de longo prazo.
Chave de memória: a chave para um item durável dentro de um namespace de store.
Eles não devem ser automaticamente o mesmo valor. Um usuário pode ter muitas threads, e uma thread pode conter muitos fatos.
Passo 1: Reproduza a Falha com um Teste de Duas Requisições
Comece com o menor teste possível. Peça ao agente para lembrar de um detalhe único, então invoque-o novamente e pergunte por esse detalhe. Não teste a memória com uma única chamada invoke(), porque o modelo pode ver tudo naquela única requisição, mesmo quando a persistência está quebrada.
config = {"configurable": {"thread_id": "debug-thread-001"}}
agent.invoke(
{"messages": [{"role": "user", "content": "Lembre-se de que o codinome do meu projeto é Juniper."}]},
config,
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "Qual é o codinome do meu projeto?"}]},
config,
)
Se a segunda requisição esquecer “Juniper”, inspecione a configuração do checkpointer e o thread_id real antes de alterar os prompts.
Passo 2: Adicione um Checkpointer para Memória na Mesma Thread
Um checkpointer persiste snapshots do estado do grafo do agente. O LangGraph usa isso para memória de curto prazo, recuperação de interrupções, fluxos human-in-the-loop e tolerância a falhas. O guia de persistência atual descreve os checkpointers como com escopo de thread e diz que a aplicação acessa o estado passando um thread_id. Veja o guia oficial de persistência do LangGraph.
InMemorySaver é excelente para confirmar que seu cabeamento de thread funciona, mas ele armazena checkpoints na RAM. O LangGraph avisa explicitamente que MemorySaver/InMemorySaver não persistem entre reinícios de processo.
Passo 3: Mantenha o Mesmo thread_id para a Mesma Conversa
O bug mais comum no nível da aplicação é criar um novo thread_id em cada requisição HTTP. O banco de dados pode estar funcionando perfeitamente enquanto cada requisição inicia uma thread LangGraph diferente.
Por exemplo, suponha que seu front-end tenha o ID de chat chat_8bf4. Mapeie esse valor determinísticamente para a thread LangGraph e reutilize-o para cada turno naquele chat. Um novo chat deve receber um novo ID de thread.
Ilustração gerada por IA: A persistência não remove o limite de contexto do modelo. Uma thread estável pode conter mais histórico do que o modelo deve receber em cada chamada.
Não use um thread_id permanente único para todos os chats pertencentes ao mesmo usuário. Isso mescla conversas não relacionadas em um único fluxo de estado. Se você usa PostgreSQL, a orientação atual de solução de problemas do LangGraph também diz que thread_id deve permanecer abaixo de 255 caracteres; um UUID ou hash determinístico é mais seguro do que um objeto serializado enorme.
Passo 4: Substitua a Persistência em Memória Antes da Produção
Uma vez que o teste de duas requisições passe, teste um reinício de processo. Salve um fato, pare a aplicação, inicie-a novamente, então pergunte pelo fato com o mesmo ID de thread. Se você ainda usa InMemorySaver, esquecer é o comportamento esperado.
Os documentos oficiais de memória de curto prazo mostram uma configuração de produção baseada em PostgreSQL usando PostgresSaver:
from langchain.agents import create_agent
from langgraph.checkpoint.postgres import PostgresSaver
DB_URI = "postgresql://user:password@db-host/app"
with PostgresSaver.from_conn_string(DB_URI) as checkpointer:
checkpointer.setup()
agent = create_agent(
model="your-provider:your-model",
tools=[],
checkpointer=checkpointer,
)
Para a configuração do pacote atualmente documentada pelo LangChain, veja Memória de curto prazo. Não coloque credenciais reais do banco de dados diretamente no código-fonte; use seu sistema normal de gerenciamento de segredos.
Ilustração gerada por IA: Um item especialmente importante é o armazenamento local do processo: um checkpointer em memória é intencionalmente perdido após o reinício, então testes de reinício pertencem à suíte de testes de memória.
Passo 5: Gerencie Histórias Longas em Vez de Enviar Tudo Para Sempre
Uma janela de contexto é a quantidade de contexto de entrada e saída que um modelo pode lidar em uma chamada de modelo. O checkpointing pode preservar uma conversa muito longa no armazenamento, mas isso não significa que cada mensagem histórica deva ser enviada de volta ao modelo para sempre.
O guia de memória de curto prazo do LangChain diz que histórias longas podem exceder a janela de contexto do modelo e que até modelos capazes de aceitar o histórico completo podem ser distraídos por conteúdo obsoleto ou fora do tópico, com maior latência e custo. As estratégias documentadas são aparar, deletar, resumir ou aplicar uma política personalizada.
Use resumificação quando detalhes antigos ainda importam
SummarizationMiddleware é a opção integrada atual para substituir o histórico antigo por um resumo compacto, mantendo as mensagens recentes. Seu gatilho pode ser baseado na contagem de tokens, contagem de mensagens ou uma fração do contexto do modelo.
Os números acima são uma política de exemplo, não configurações universais. Escolha os limites após medir seus próprios prompts, saídas de ferramentas, limites de contexto do modelo, latência e qualidade do resumo. Veja a documentação de middleware integrado do LangChain para as opções de gatilho e manutenção atualmente suportadas.
Ilustração gerada por IA: Teste a recuperação após turnos suficientes para ativar sua política de aparar ou resumir; um chat curto pode esconder bugs de contexto longo.
Não apare mensagens de ferramenta cegamente
Se você implementar exclusão ou aparar personalizados, preserve uma sequência de mensagens válida. O LangChain avisa que muitos provedores exigem que uma mensagem de assistente contendo chamadas de ferramenta seja seguida pelas mensagens de resultado da ferramenta correspondentes. Remover uma metade desse par pode criar erros do provedor ou comportamento confuso do modelo.
Passo 6: Mova Fatos Duráveis Para um Store de Longo Prazo
Um store é a camada de persistência do LangGraph para dados definidos pela aplicação fora do estado do grafo de uma thread. A documentação atual do LangChain usa stores para informações que devem estar disponíveis entre conversas, como preferências do usuário, fatos ou conhecimento compartilhado da aplicação.
Itens do store de longo prazo são documentos JSON organizados por um namespace e uma chave. Um namespace prático frequentemente contém um identificador de usuário ou organização:
Isso é diferente de salvar a transcrição inteira. Armazene a informação que seu produto trata intencionalmente como durável. Se um fato for privado ou regulado, aplique suas políticas normais de retenção, autorização, criptografia e exclusão, em vez de assumir que a “memória do agente” está isenta delas.
Ilustração gerada por IA: Esta ilustração usa rótulos conceituais amplos, em vez de nomes de API atuais literais. Para novo código LangChain v1, use a distinção checkpointer/store descrita no texto e na documentação oficial.
Use um store baseado em banco de dados na produção
O guia oficial de memória de longo prazo mostra tanto InMemoryStore quanto PostgresStore, e observa explicitamente que a implementação em memória deve ser substituída por um store baseado em banco de dados para produção. Ele também lista integrações de store além do PostgreSQL. Use o backend que se adequa aos seus requisitos de implantação e operacionais, em vez de selecionar um banco de dados vetorial meramente porque a palavra “memória” está envolvida.
Adicione busca semântica apenas quando precisar de recuperação difusa
Stores do LangGraph podem ser configurados com um índice para que store.search() possa recuperar itens por similaridade semântica. Isso é útil quando você tem muitas memórias e não conhece a chave exata. Para um pequeno conjunto de preferências estruturadas, a busca direta por namespace/chave é frequentemente mais simples e determinística.
Passo 7: Torne os Caminhos de Leitura e Escrita da Memória Explícitos
Persistir um item de longo prazo não garante que o agente o utilizará. A aplicação ainda precisa de um caminho de recuperação. Os agentes LangChain atuais permitem que ferramentas acessem o store fornecido através de ToolRuntime.
from dataclasses import dataclass
from langchain.tools import tool, ToolRuntime
@dataclass
class Context:
user_id: str
@tool
def get_response_style(runtime: ToolRuntime[Context]) -> str:
store = runtime.store
if store is None:
return "No memory store configured"
namespace = ("users", runtime.context.user_id, "preferences")
item = store.get(namespace, "response_style")
return item.value["value"] if item else "default"
Você também pode construir prompts dinâmicos ou middleware que lê o estado e a memória durável antes de uma chamada de modelo. A regra de design importante é que o caminho de recuperação deve ser observável e testável. “A informação existe em algum lugar no banco de dados” não é suficiente.
Ilustração gerada por IA: Um teste de regressão útil pede um fato anterior após muitos turnos e verifica que a resposta vem da camada de memória pretendida, não de texto de prompt duplicado acidentalmente.
Passo 8: Teste as Quatro Fronteiras de Memória Separadamente
Uma suíte de testes de memória confiável deve cobrir mais do que “o modelo lembrou meu nome uma vez”. Use pelo menos estes quatro casos:
Teste
Resultado esperado
Duas invocações, mesmo ID de thread
Informação com escopo de thread está disponível
Duas invocações, IDs de thread diferentes
O histórico de thread de curto prazo não vaza
Reinício da aplicação, mesmo ID de thread com checkpointer persistente
O estado da thread pode retomar
Nova thread, mesmo usuário com store de longo prazo
Apenas fatos duráveis armazenados intencionalmente podem ser recuperados
Então adicione um teste de conversa longa que exceda seu limite de resumificação. Afirme que fatos duráveis importantes sobrevivem, sequências recentes de chamadas de ferramenta permanecem válidas e o tamanho do prompt permanece dentro do seu orçamento de contexto alvo.
Ilustração gerada por IA: Trate isso como uma lista de verificação conceitual de QA. A arquitetura LangChain v1 atual deve ser validada contra as APIs oficiais de checkpointer, store e middleware, em vez de exemplos de classes de memória legadas.
Uma Arquitetura de Produção Mínima
Para muitas aplicações de agentes, um design robusto parece com isto:
A API recebe user_id, conversation_id e a nova mensagem do usuário.
A aplicação mapeia conversation_id para um thread_id LangGraph estável.
Um checkpointer persistente restaura o estado da thread.
Um store de longo prazo recupera apenas fatos duráveis do usuário ou da aplicação necessários para a requisição.
Resumificação ou aparar mantém o histórico voltado para o modelo dentro de um orçamento de contexto medido.
O agente executa ferramentas e o modelo.
O checkpointer comete o estado da thread atualizado.
Apenas fatos aprovados são escritos no store de longo prazo.
Se você implantar através do LangGraph Agent Server, o guia de persistência atual diz que o servidor lida com a infraestrutura de persistência automaticamente, então não duplique essa camada sem verificar o modelo de implantação.
Erros Comuns Que Fazem a Memória Parecer Quebrada
Gerando um novo thread_id para cada requisição
Isso cria um novo estado de conversa a cada turno. Registre o ID da thread ao lado do ID do chat da sua aplicação e verifique a reutilização.
Usando InMemorySaver em um serviço multi-worker ou reiniciável
O estado local da RAM desaparece com o processo e pode não ser compartilhado entre workers. Use um backend persistente para continuidade na produção.
Assumindo que um checkpointer resolve o problema da janela de contexto
Um checkpointer preserva o estado; ele não garante que uma transcrição em constante crescimento seja útil para o modelo. Adicione uma política explícita de gerenciamento de contexto.
Colocando cada fato histórico no prompt
Mais contexto não é automaticamente melhor contexto. Recupere informações relevantes para o turno atual e preserve a continuidade conversacional recente separadamente.
Tratando resumos como um banco de dados perfeito
Resumos são representações comprimidas geradas pelo modelo. Se um fato deve ser exato—um identificador de conta, restrição contratual, preferência aprovada pelo usuário ou estado do fluxo de trabalho—armazene-o como dados estruturados, em vez de esperar que ele sobreviva à resumificação repetida.
Misturando escopos de curto e longo prazo
O histórico da thread não deve silenciosamente se tornar um perfil global do usuário. Inversamente, uma preferência do usuário destinada a segui-lo entre chats não deve viver apenas em uma thread.
Copiando tutoriais de memória pré-v1 sem verificar imports
Se um exemplo começa com chains legadas ou classes de memória antigas, compare-o com a migração v1 atual e a documentação de memória antes de usá-lo em uma nova aplicação.
Lista de Verificação de Depuração
Confirme que o agente foi criado com um checkpointer.
Registre e compare thread_id entre requisições consecutivas.
Inspecione o estado da thread armazenado antes de culpar o modelo.
Reinicie o processo e repita o mesmo teste de thread.
Substitua InMemorySaver por um checkpointer persistente para produção.
Meça o crescimento de mensagens/tokens em chats longos.
Ative resumificação ou aparar antes que o histórico se torne excessivo.
Mantenha sequências de chamada/resultado de ferramenta válidas ao remover mensagens.
Mova fatos entre threads para um store de longo prazo com namespace.
Teste uma nova thread para o mesmo usuário para verificar a recuperação de longo prazo intencional.
Teste um usuário diferente para verificar o isolamento de memória.
Rastreie quais itens de memória foram recuperados para cada resposta.
Conclusão
A perda de memória do agente LangChain raramente é resolvida por uma janela de contexto maior. Primeiro, torne o estado da thread persistente com um checkpointer e um thread_id estável. Então, controle histórias longas com aparar ou SummarizationMiddleware. Finalmente, coloque fatos que devem sobreviver entre conversas em um store de longo prazo com namespace e recupere-os deliberadamente.
Essa separação lhe dá algo muito mais útil do que “memória”: um sistema que você pode reiniciar, escalar, testar, auditar e analisar quando um usuário pergunta: “Por que o agente esqueceu?”