如何迁移到 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. 管理对话历史记录
管理对话历史记录的目标是以一种对聊天模型最佳使用方式存储和检索历史记录。
通常,这涉及到修剪和/或总结对话历史记录,以保留对话中最相关的部分,同时使对话适应聊天模型的上下文窗口。
属于此类别的内存类包括
内存类型 | 如何迁移 | 描述 |
---|---|---|
ConversationBufferMemory | 迁移指南链接 | 一个基本的内存实现,仅存储对话历史记录。 |
ConversationStringBufferMemory | 迁移指南链接 | ConversationBufferMemory 的一种特殊情况,专为 LLM 设计,现在已不再相关。 |
ConversationBufferWindowMemory | 迁移指南链接 | 保留对话的最后 n 轮。当缓冲区已满时,删除最旧的一轮。 |
ConversationTokenBufferMemory | 迁移指南链接 | 仅保留对话中最新的消息,约束条件是对话中的令牌总数不超过某个限制。 |
ConversationSummaryMemory | 迁移指南链接 | 持续总结对话历史记录。摘要在每次对话轮次后更新。该抽象返回对话历史记录的摘要。 |
ConversationSummaryBufferMemory | 迁移指南链接 | 提供对话的运行摘要以及对话中最新的消息,约束条件是对话中的令牌总数不超过某个限制。 |
VectorStoreRetrieverMemory | 请参阅相关的 长期记忆 Agent 教程 | 将对话历史记录存储在向量存储中,并根据输入检索过去对话中最相关的部分。 |
2. 从对话历史记录中提取结构化信息
请参阅 长期记忆 Agent 教程,其中实现了一个可以从对话历史记录中提取结构化信息的 Agent。
属于此类别的内存类包括
内存类型 | 描述 |
---|---|
BaseEntityStore | 一个类似于键值存储的抽象接口。它用于存储在对话期间学习到的结构化信息。该信息必须表示为键值对的字典。 |
ConversationEntityMemory | 结合了总结对话和从对话历史记录中提取结构化信息的能力。 |
以及抽象的特定后端实现
内存类型 | 描述 |
---|---|
InMemoryEntityStore | BaseEntityStore 的一个实现,它将信息存储在字面计算机内存 (RAM) 中。 |
RedisEntityStore | BaseEntityStore 的一个特定实现,它使用 Redis 作为后端。 |
SQLiteEntityStore | BaseEntityStore 的一个特定实现,它使用 SQLite 作为后端。 |
UpstashRedisEntityStore | BaseEntityStore 的一个特定实现,它使用 Upstash 作为后端。 |
自最初发布以来,这些抽象的开发受到了限制。这是因为它们通常需要针对特定应用程序进行大量自定义才能有效,因此与对话历史记录管理抽象相比,它们的使用范围较小。
因此,没有针对这些抽象的迁移指南。如果您在迁移依赖于这些抽象的应用程序时遇到困难,请
- 请查看此 长期记忆 Agent 教程,它应该为如何从对话历史记录中提取结构化信息提供一个良好的起点。
- 如果您仍然遇到困难,请在 LangChain GitHub 存储库上打开一个 issue,解释您的用例,我们将尝试提供更多关于如何迁移这些抽象的指导。
从对话历史记录中提取结构化信息的一般策略是使用具有工具调用功能的聊天模型从对话历史记录中提取结构化信息。然后可以将提取的信息保存到适当的数据结构(例如,字典)中,并且可以根据需要从中检索信息并添加到提示中。
3. 在一个或多个内存实现之上提供复合逻辑的实现
属于此类别的内存类包括
内存类型 | 描述 |
---|---|
CombinedMemory | 此抽象接受 BaseMemory 列表,并根据输入从每个列表中获取相关的内存信息。 |
SimpleMemory | 用于添加只读硬编码上下文。用户可以直接将此信息写入提示。 |
ReadOnlySharedMemory | 提供现有 BaseMemory 实现的只读视图。 |
这些实现似乎没有被广泛使用,也没有提供显著的价值。用户应该能够在自定义代码中重新实现这些,而不会遇到太多困难。
相关资源
探索 LangGraph 的持久化
使用简单的 LCEL 添加持久化(对于更复杂的使用场景,请优先使用 langgraph)
使用消息历史记录