如何迁移到 LangGraph 内存
在 LangChain v0.3 版本中,我们建议 LangChain 用户利用 LangGraph 持久性将 memory
整合到他们的 LangChain 应用程序中。
- 依赖
RunnableWithMessageHistory
或BaseChatMessageHistory
的用户无需进行任何更改,但鼓励考虑使用 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 内存用于处理三个主要用例
用例 | 示例 |
---|---|
管理对话历史记录 | 仅保留用户和 AI 之间对话的最近 n 轮对话。 |
提取结构化信息 | 从对话历史记录中提取结构化信息,例如关于用户学习到的事实列表。 |
复合内存实现 | 组合多个内存源,例如,关于用户的已知事实列表以及在给定对话期间学习到的事实。 |
虽然 LangChain 0.0.x 内存抽象很有用,但它们的功能有限,并且不太适合实际的会话式 AI 应用程序。 这些内存抽象缺乏对多用户、多会话场景的内置支持,而这对于实际的会话式 AI 系统至关重要。
这些实现中的大多数已在 LangChain 0.3.x 中正式弃用,转而支持 LangGraph 持久性。
RunnableWithMessageHistory 和 BaseChatMessageHistory
如果您想在 LangGraph 中使用 BaseChatMessageHistory
(无论是否使用 RunnableWithMessageHistory
),请参阅 如何在 LangGraph 中使用 BaseChatMessageHistory。
从 LangChain v0.1 开始,我们开始建议用户主要依赖 BaseChatMessageHistory。 BaseChatMessageHistory
用作存储和检索对话中消息的简单持久性机制。
当时,编排 LangChain 链的唯一选项是通过 LCEL。 为了将内存与 LCEL
结合使用,用户必须使用 RunnableWithMessageHistory 接口。 虽然对于基本的聊天应用程序来说已经足够了,但许多用户发现该 API 不直观且难以使用。
从 LangChain v0.3 开始,我们建议新的代码利用 LangGraph 进行编排和持久化
- 编排:在 LangGraph 中,用户定义 图,指定应用程序的流程。 这允许用户在需要
LCEL
时继续在各个节点中使用LCEL
,同时可以轻松定义更易读和可维护的复杂编排逻辑。 - 持久化:用户可以依赖 LangGraph 的持久性来存储和检索数据。 LangGraph 持久性非常灵活,可以支持比
RunnableWithMessageHistory
接口更广泛的用例。
如果您一直在使用 RunnableWithMessageHistory
或 BaseChatMessageHistory
,则无需进行任何更改。 我们不计划在不久的将来弃用任何一项功能。 此功能对于简单的聊天应用程序来说已经足够了,并且任何使用 RunnableWithMessageHistory
的代码都将继续按预期工作。
迁移
这些指南假设您熟悉以下概念
1. 管理对话历史记录
管理对话历史记录的目标是以一种对聊天模型最佳的方式存储和检索历史记录。
通常,这涉及修剪和/或总结对话历史记录,以保留对话中最相关的部分,同时使对话适合聊天模型的上下文窗口。
属于此类别的内存类包括
内存类型 | 如何迁移 | 描述 |
---|---|---|
ConversationTokenBufferMemory | 迁移指南链接 | 仅保留对话中最新的消息,约束条件是对话中的 token 总数不超过某个限制。 |
ConversationSummaryMemory | 迁移指南链接 | 持续总结对话历史记录。 摘要在每次对话轮次后更新。 抽象返回对话历史记录的摘要。 |
ConversationSummaryBufferMemory | 迁移指南链接 | 提供对话的运行摘要,以及对话中最新的消息,约束条件是对话中的 token 总数不超过某个限制。 |
2. 从对话历史记录中提取结构化信息
属于此类别的内存类包括
内存类型 | 描述 |
---|---|
BaseEntityStore | 类似于键值存储的抽象接口。 它用于存储在对话期间学习到的结构化信息。 该信息必须表示为键值对的对象。 |
以及抽象的特定后端实现
内存类型 | 描述 |
---|---|
InMemoryEntityStore | BaseEntityStore 的实现,它将信息存储在字面计算机内存(RAM)中。 |
这些抽象自最初发布以来没有得到太多开发。 原因是,为了使这些抽象有用,它们通常需要针对特定应用程序进行大量专门化,因此这些抽象不如对话历史记录管理抽象那样广泛使用。
因此,没有针对这些抽象的迁移指南。 如果您在迁移依赖于这些抽象的应用程序时遇到困难,请在 LangChain GitHub 存储库上提出 issue,解释您的用例,我们将尽力提供有关如何迁移这些抽象的更多指导。
从对话历史记录中提取结构化信息的一般策略是使用具有工具调用功能的聊天模型从对话历史记录中提取结构化信息。 然后,可以将提取的信息保存到适当的数据结构(例如,对象)中,并且可以根据需要从中检索信息并将其添加到提示中。
3. 提供在一个或多个内存实现之上进行复合逻辑的实现
属于此类别的内存类包括
内存类型 | 描述 |
---|---|
CombinedMemory | 此抽象接受 BaseMemory 列表,并根据输入从每个列表中获取相关的内存信息。 |
这些实现似乎没有被广泛使用,也没有提供显著的价值。 用户应该能够在自定义代码中重新实现这些,而不会遇到太多困难。
相关资源
探索 LangGraph 的持久性
使用简单的 LCEL 添加持久性(对于更复杂的用例,请优先选择 langgraph)
使用消息历史记录