Skip to main content
Open on GitHub

如何迁移到 LangGraph 内存

自 LangChain v0.3 版本发布以来,我们建议 LangChain 用户利用 LangGraph 持久化 功能,将 memory 集成到他们的 LangChain 应用中。

  • 依赖 RunnableWithMessageHistoryBaseChatMessageHistory 的用户 无需 进行任何更改,但建议考虑在更复杂的使用场景中使用 LangGraph。
  • 依赖 LangChain 0.0.x 中已弃用的内存抽象的用户,应遵循本指南,将 LangChain 0.3.x 中的新 LangGraph 持久化功能升级至该版本。

为什么使用 LangGraph 进行记忆?

LangGraph 中持久化的主要优势包括:

  • 内置支持多用户和对话功能,这是现实世界对话式 AI 应用的典型需求。
  • 能够在任意时刻保存和恢复复杂对话。这有助于:
    • 错误恢复
    • 允许在 AI 工作流中进行人工干预
    • 探索不同的对话路径("时间旅行")
  • 完全兼容传统的语言模型和现代的聊天模型。LangChain 早期的内存实现并非为新的聊天模型 API 设计,导致工具调用等功能出现问题。LangGraph 的内存可以持久化任何自定义状态。
  • 高度可定制,允许您完全控制内存的工作方式并使用不同的存储后端。

LangChain 中记忆的演变

自 LangChain 首次发布以来,记忆的概念已发生了显著演变。

LangChain 0.0.x 记忆

广义上,LangChain 0.0.x 的内存用于处理三个主要用例:

应用场景示例
Managing conversation historyKeep only the last n turns of the conversation between the user and the AI.
Extraction of structured informationExtract structured information from the conversation history, such as a list of facts learned about the user.
Composite memory implementationsCombine multiple memory sources, e.g., a list of known facts about the user along with facts learned during a given conversation.

虽然 LangChain 0.0.x 版本的内存抽象机制很有用,但其功能有限,并不适合现实世界的对话式 AI 应用。这些内存抽象缺乏对多用户、多会话场景的原生支持,而这对实际落地的对话式 AI 系统至关重要。

这些实现中的大多数已在 LangChain 0.3.x 中被正式弃用,转而推荐使用 LangGraph 的持久化功能。

RunnableWithMessageHistory 和 BaseChatMessageHistory

注意

请参阅 如何在 LangGraph 中使用 BaseChatMessageHistory,如果您希望在 LangGraph 中使用BaseChatMessageHistory(无论是否配合RunnableWithMessageHistory使用)。

自 LangChain v0.1 起,我们建议用户主要依赖 BaseChatMessageHistoryBaseChatMessageHistory 用作存储和检索对话消息的简单持久化方案。

当时,编排 LangChain 链的唯一方式是通过 LCEL。要将记忆功能与 LCEL 结合使用,用户必须采用 RunnableWithMessageHistory 接口。虽然这对于基本的聊天应用已足够,但许多用户发现该 API 不够直观且难以使用。

自 LangChain v0.3 起,我们建议代码利用 LangGraph 进行编排和持久化:

  • 编排:在 LangGraph 中,用户定义 图形 来指定应用程序的流程。这使得用户在需要时可以在各个节点内继续使用 LCEL,同时轻松定义更易于阅读和维护的复杂编排逻辑。
  • 持久化:用户可以依赖 LangGraph 的 持久化 功能来存储和检索数据。LangGraph 的持久化机制极其灵活,能够支持的使用场景远比 RunnableWithMessageHistory 接口广泛。
重要

如果您一直在使用 RunnableWithMessageHistoryBaseChatMessageHistory,则无需进行任何更改。我们近期不打算弃用其中任何一项功能。此功能足以满足简单聊天应用的需求,且所有使用 RunnableWithMessageHistory 的代码将继续按预期工作。

迁移

前置条件

1. 管理对话历史

管理对话历史的目标是以一种最适合聊天模型使用的方式存储和检索历史记录。

通常这需要修剪和/或总结对话历史,以保留对话中最相关的部分,同时确保对话内容适合聊天模型的上下文窗口。

属于此类别的内存类包括:

内存类型如何迁移描述
ConversationBufferMemoryLink to Migration GuideA basic memory implementation that simply stores the conversation history.
ConversationStringBufferMemoryLink to Migration GuideA special case of ConversationBufferMemory designed for LLMs and no longer relevant.
ConversationBufferWindowMemoryLink to Migration GuideKeeps the last n turns of the conversation. Drops the oldest turn when the buffer is full.
ConversationTokenBufferMemoryLink to Migration GuideKeeps only the most recent messages in the conversation under the constraint that the total number of tokens in the conversation does not exceed a certain limit.
ConversationSummaryMemoryLink to Migration GuideContinually summarizes the conversation history. The summary is updated after each conversation turn. The abstraction returns the summary of the conversation history.
ConversationSummaryBufferMemoryLink to Migration GuideProvides a running summary of the conversation together with the most recent messages in the conversation under the constraint that the total number of tokens in the conversation does not exceed a certain limit.
VectorStoreRetrieverMemorySee related long-term memory agent tutorialStores the conversation history in a vector store and retrieves the most relevant parts of past conversation based on the input.

2. 从对话历史中提取结构化信息

请参阅 长期记忆代理教程,该教程实现了一个可以从对话历史中提取结构化信息的代理。

属于此类别的内存类包括:

内存类型描述
BaseEntityStoreAn abstract interface that resembles a key-value store. It was used for storing structured information learned during the conversation. The information had to be represented as a dictionary of key-value pairs.
ConversationEntityMemoryCombines the ability to summarize the conversation while extracting structured information from the conversation history.

以及抽象层的具体后端实现:

内存类型描述
InMemoryEntityStoreAn implementation of BaseEntityStore that stores the information in the literal computer memory (RAM).
RedisEntityStoreA specific implementation of BaseEntityStore that uses Redis as the backend.
SQLiteEntityStoreA specific implementation of BaseEntityStore that uses SQLite as the backend.
UpstashRedisEntityStoreA specific implementation of BaseEntityStore that uses Upstash as the backend.

这些抽象功能自最初发布以来开发进展有限。这是因为它们通常需要对特定应用进行大量定制才能生效,因此其使用范围不如对话历史管理抽象功能广泛。

出于这个原因,这些抽象没有迁移指南。如果您在迁移依赖这些抽象的应用程序时遇到困难,请:

  1. 请查看此 长期记忆代理教程,它应能为您提供如何从对话历史中提取结构化信息的良好起点。
  2. 如果您仍然遇到困难,请在 LangChain GitHub 仓库中提交一个 issue,说明您的使用场景,我们将尝试提供更详细的指导,帮助您迁移这些抽象概念。

从对话历史中提取结构化信息的一般策略是使用具有工具调用能力的聊天模型来从对话历史中提取结构化信息。 提取出的信息随后可以保存到适当的数据结构(例如字典)中,并根据需要从中检索信息并添加到提示词中。

3. 在一个或多个内存实现之上提供组合逻辑的实现

属于此类别的内存类包括:

内存类型描述
CombinedMemoryThis abstraction accepted a list of BaseMemory and fetched relevant memory information from each of them based on the input.
SimpleMemoryUsed to add read-only hard-coded context. Users can simply write this information into the prompt.
ReadOnlySharedMemoryProvided a read-only view of an existing BaseMemory implementation.

这些实现似乎未被广泛使用,也未提供显著价值。用户应能够在自定义代码中相对轻松地重新实现这些内容。

使用 LangGraph 探索持久性:

使用简单的 LCEL 添加持久化(对于更复杂的使用场景,推荐使用 LangGraph):

处理消息历史: