如何迁移到 LangGraph 内存
在 LangChain v0.3 版本发布后,我们建议 LangChain 用户利用 LangGraph 持久化 将 memory 集成到他们的 LangChain 应用程序中。
- 依赖
RunnableWithMessageHistory或BaseChatMessageHistory的用户 无需 进行任何更改,但建议在更复杂的使用场景中考虑使用 LangGraph。 - 依赖 LangChain 0.0.x 中已弃用的记忆抽象的用户应遵循本指南,将系统升级至 LangChain 0.3.x 中的新 LangGraph 持久化功能。
为什么使用 LangGraph 进行记忆管理?
LangGraph中持久化的主要优势是:
- 内置对多用户和多轮对话的支持,这是实际对话式人工智能应用中的常见需求。
- 能够在任意时刻保存和恢复复杂的对话。这有助于:
- 错误恢复
- 允许人类干预人工智能工作流程
- 探索不同的对话路径(“时间旅行”)
- 与传统语言模型和现代聊天模型均完全兼容。LangChain 早期的内存实现并非为新的聊天模型 API 设计,导致在工具调用等功能上出现问题。LangGraph 内存可持久化任意自定义状态。
- 高度可定制,允许您完全控制记忆的工作方式,并使用不同的存储后端。
LangChain中记忆的演变
在 LangChain 从最初发布以来,记忆的概念已经发生了显著的演变。
LangChain 0.0.x 内存
从广义上讲,LangChain 0.0.x 的记忆功能主要用于处理三种主要用例:
| 应用场景 | 示例 |
|---|---|
| Managing conversation history | Keep only the last n turns of the conversation between the user and the AI. |
| Extraction of structured information | Extract structured information from the conversation history, such as a list of facts learned about the user. |
| Composite memory implementations | Combine 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 的记忆抽象机制具有一定的实用性,但其功能有限,不太适合实际的对话式人工智能应用。这些记忆抽象机制缺乏对多用户、多对话场景的内置支持,而这类场景对于实用的对话式人工智能系统来说至关重要。
在 LangChain 0.3.x 中,这些实现大多已被官方弃用,取而代之的是 LangGraph 持久化。
RunnableWithMessageHistory 和 BaseChatMessageHistory
请参阅 如何在 LangGraph 中使用 BaseChatMessageHistory,如果您希望在 LangGraph 中使用 BaseChatMessageHistory(无论是否包含 RunnableWithMessageHistory)。
自 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 | Link to Migration Guide | A basic memory implementation that simply stores the conversation history. |
ConversationStringBufferMemory | Link to Migration Guide | A special case of ConversationBufferMemory designed for LLMs and no longer relevant. |
ConversationBufferWindowMemory | Link to Migration Guide | Keeps the last n turns of the conversation. Drops the oldest turn when the buffer is full. |
ConversationTokenBufferMemory | Link to Migration Guide | Keeps 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. |
ConversationSummaryMemory | Link to Migration Guide | Continually summarizes the conversation history. The summary is updated after each conversation turn. The abstraction returns the summary of the conversation history. |
ConversationSummaryBufferMemory | Link to Migration Guide | Provides 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. |
VectorStoreRetrieverMemory | See related long-term memory agent tutorial | Stores the conversation history in a vector store and retrieves the most relevant parts of past conversation based on the input. |
2. 从对话历史中提取结构化信息
请参阅 长期记忆代理教程,了解如何实现一个能够从对话历史中提取结构化信息的代理。
属于此类的内存类包括:
| 记忆类型 | 描述 |
|---|---|
BaseEntityStore | An 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. |
ConversationEntityMemory | Combines the ability to summarize the conversation while extracting structured information from the conversation history. |
以及抽象的特定后端实现:
| 记忆类型 | 描述 |
|---|---|
InMemoryEntityStore | An implementation of BaseEntityStore that stores the information in the literal computer memory (RAM). |
RedisEntityStore | A specific implementation of BaseEntityStore that uses Redis as the backend. |
SQLiteEntityStore | A specific implementation of BaseEntityStore that uses SQLite as the backend. |
UpstashRedisEntityStore | A specific implementation of BaseEntityStore that uses Upstash as the backend. |
这些抽象概念自首次发布以来,开发进展有限。这是因为它们通常需要针对特定应用进行大量定制才能发挥作用,因此其使用范围不如对话历史管理抽象广泛。
出于这个原因,这些抽象层没有迁移指南。如果你在迁移依赖这些抽象层的应用程序时遇到困难,请:
- 请查阅此长期记忆代理教程,这将为您提供从对话历史中提取结构化信息的良好起点。
- 如果你仍然遇到困难,请在 LangChain 的 GitHub 仓库中打开一个问题,说明你的使用场景,我们将尽力提供更详细的指导,帮助你迁移这些抽象。
从对话历史中提取结构化信息的一般策略是使用具备工具调用能力的聊天模型,从对话历史中提取结构化信息。 提取的信息随后可以保存到适当的数据结构(例如字典)中,并根据需要从中检索信息并添加到提示中。
3. 在一个或多个内存实现之上提供组合逻辑的实现
属于此类的内存类包括:
| 记忆类型 | 描述 |
|---|---|
CombinedMemory | This abstraction accepted a list of BaseMemory and fetched relevant memory information from each of them based on the input. |
SimpleMemory | Used to add read-only hard-coded context. Users can simply write this information into the prompt. |
ReadOnlySharedMemory | Provided a read-only view of an existing BaseMemory implementation. |
这些实现似乎并未得到广泛使用,也未提供显著价值。用户应该能够通过自定义代码相对轻松地重新实现这些功能。
相关资源
探索使用LangGraph进行持久化:
通过简单的 LCEL 实现持久化存储(更复杂的用例建议使用 langgraph):
处理消息历史记录: