Langgraph的持久化管理-记忆模块
持久化就是记忆,就是能让AI记住用户的定制化的核心。
LangGraph 有一个内置的持久层,通过校验指针实现。使用校验指针编译图形时,校验指针会在每个超级步骤superstep中保存图形状态的校验点checkpoint。这些检查点被保存到一个线程中,在图形执行后可以访问该线程。由于线程允许在图形执行后访问图形的状态,因此包括人在回路、内存、时间旅行和容错在内的多种强大功能都成为可能。有关如何在图形中添加和使用定点器的端到端示例,请参阅本指南。下面,我们将详细讨论这些概念。
这个checkpoint的概念非常重要,需要详细理解。
checkpoint
检查点是在每个超级步骤中保存的图形状态快照,由具有以下关键属性的 StateSnapshot 对象表示:
config: Config associated with this checkpoint.
metadata: 与该检查点相关的元数据。
values: 此时状态通道的值。
next 图中下一个要执行的节点名称元组。
tasks:PregelTask 对象的元组,包含下一个待执行任务的信息。如果之前尝试过该步骤,则会包含错误信息。如果图形在节点内被动态中断,任务将包含与中断相关的附加数据。
示例
1 | from langgraph.graph import StateGraph, START, END |
这里有四个检查点
1、以 START 为下一个执行节点的空检查点
2、用户输入 {‘foo’: ‘’, ‘bar’: []},并将 node_a 作为下一个要执行的节点
3、node_a的输出进行检查点 {‘foo’: ‘a’, ‘bar’: [‘a’]},并将 node_b 作为下一个要执行的节点
4、node_b {‘foo’: ‘b’, ‘bar’: [‘a’、’b’]}的输出作为检查点,并且没有下一个节点要执行
好了以上就是你需要理解的概念,我们可以回到主要问题:
如何为graph添加线程级持久性了。
如何为您的图添加线程级持久性
许多AI应用程序需要内存以在多个交互之间共享上下文。在LangGraph中,这种内存可以通过在任何 StateGraph 中添加 线程级持久性 来实现。
在创建任何LangGraph图时,您可以通过在编译图时添加 检查点保存器 来设置其状态保持:
1 | from langgraph.checkpoint.memory import MemorySaver |
这里不涉及多个对话或用户之间共享的内存(跨线程持久性)。如果想,看这里https://langchain-ai.github.io/langgraph/how-tos/persistence/#add-long-term-memory
下面我们搞个例子,方便理解。
基础步骤我就跳过,具体查看https://www.aidoczh.com/langgraph/how-tos/persistence/
1、安装所需的包
2、为 OpenAI(我们将使用的 LLM)和 Tavily(我们将使用的搜索工具)设置 API 密钥。
3、定义图,可以定义我们的 StateGraph 并添加我们的模型调用节点
4、添加持久性
1 | from langgraph.checkpoint.memory import MemorySaver |
定义具有持久性的图表
要为具有子图的图添加持久性,您只需在编译父图时传递一个检查点保存器。LangGraph将自动将检查点保存器传播到子子图。
1 | from langgraph.checkpoint.memory import MemorySaver |
子图的定义:https://langchain-ai.github.io/langgraph/concepts/low_level/#subgraphs
我觉得还是很好理解的,一般子图会应用在多Agent的情况,每个Agent可以看作一个子图,然后由主图控制协调多个Agent的执行。当前我们用的不多,但是是很关键的定义。
使用内存检查点保存器
内存检查点保存器是最简单的检查点保存器,它将图的状态保存在内存中。
如何为您的图添加跨线程持久性
这个概念对我们很重要,所有的AI应用都需要跨线程持久性,否则无法实现多轮对话。Chatgpt就是用类似这种方法进行多线程管理。
LangGraph 还允许您在多个线程之间持久化数据。例如,您可以将用户(他们的姓名或偏好)信息存储在共享内存中,并在新的对话线程中重复使用这些信息。
在本指南中,我们将展示如何构建和使用一个实现了使用Store接口的共享内存的图。
https://www.aidoczh.com/langgraph/how-tos/cross-thread-persistence/#_2
前面的步骤还是一样:
1、装安装包、设置API
2、定义存储
定义存储
在这个例子中,我们将创建一个图形,可以检索用户的偏好信息。我们将通过定义一个 InMemoryStore 来实现
- 这是一个可以在内存中存储数据并查询数据的对象。然后,我们将在编译图形时传递存储对象。这允许图形中的每个节点访问存储:当你定义节点函数时,可以定义 store 关键字参数,LangGraph 将自动传递你编译图形时使用的存储对象。
在使用 Store 接口存储对象时,你需要定义两个东西:
- 对象的命名空间, 一个元组(类似于目录)
- 对象键(类似于文件名)
在我们的例子中,我们将使用 (“memories”,
重要的是,为了确定用户,我们将通过节点函数的 config 关键字参数传递 user_id。
让我们首先定义一个已经填充了一些关于用户记忆的 InMemoryStore。
1 | from langgraph.store.memory import InMemoryStore |
创建图形
1 | import uuid |
后面验证步骤我就不写了
后面还有如何使用用Postgres检查点进行持久性,如何使用 MongoDB 检查点进行持久性如何使用 Redis 创建自定义检查点
我就等之后用到再更新吧