LangGraph 是 LangChain 生态的扩展框架,专注于构建复杂、有状态、多步骤的交互式 AI 系统,特别适合需要动态路由、循环和状态管理的应用场景,例如智能代理和自动化工作流。Checkpointer 是 LangGraph 中的核心组件,用于实现状态的持久化,确保状态图在多次交互中能够保存和加载状态,从而支持会话记忆、错误恢复和人工干预等功能。
1. 定义与功能
1.1 什么是 Checkpointer?
Checkpointer 是 LangGraph 中的一个机制,负责在状态图的每次执行步骤中保存图的当前状态(称为检查点,Checkpoint),并在需要时加载这些状态以恢复执行。它通过持久化状态支持以下关键功能:
- 会话记忆:保存用户交互历史,确保多轮对话或跨会话的上下文一致性。
- 错误恢复:在执行失败时,恢复到最近的成功检查点,继续执行。
- 人工干预:支持人工审核、编辑代理行为或插入输入。
- 时间旅行:允许查看和编辑历史检查点,探索替代执行路径,适用于调试和优化。
Checkpointer 的核心目标是增强状态图的持久性和可恢复性,使其适用于需要长期上下文的复杂应用。
1.2 设计理念
- 灵活性:支持多种存储后端,从内存到生产级数据库,适应不同场景。
- 透明性:对开发者透明,状态保存和加载由 LangGraph 运行时自动处理。
- 版本化:通过检查点版本管理,支持状态历史追踪和回滚,类似文档编辑器的自动保存。
- 异步支持:提供同步和异步接口,优化高并发场景。
2. 实现与接口
2.1 基础类
Checkpointer 的核心抽象类是 langgraph.checkpoint.base.BaseCheckpointSaver
,定义了保存和加载检查点的标准接口。主要方法包括:
- 同步方法:
put
: 保存检查点。get
: 获取指定检查点。list
: 列出检查点历史。
- 异步方法:
aput
: 异步保存检查点。aget
: 异步获取检查点。alist
: 异步列出检查点历史。
关键属性:
serde
: 序列化器(SerializerProtocol
),用于编码/解码检查点数据,默认使用JsonPlusSerializer
。
相关类:
Checkpoint
: 表示状态快照,包含状态数据和元数据。CheckpointMetadata
: 存储检查点的元数据,如时间戳和线程 ID。PersistentDict
: 内存中的持久化字典,用于InMemorySaver
。
2.2 具体实现
LangGraph 提供多种 Checkpointer 实现,适用于不同场景:
实现类型 | 用途 | 安装命令 | 备注 |
---|---|---|---|
InMemorySaver | 测试和调试,内存存储 | 无需额外安装,来自 langgraph.checkpoint.memory | 不适合生产,适合快速原型 |
SqliteSaver | 本地轻量级同步存储 | pip install langgraph-checkpoint-sqlite | 适合本地实验和开发 |
AsyncSqliteSaver | 本地轻量级异步存储 | pip install aiosqlite langgraph-checkpoint-sqlite | 需 aiosqlite 支持,适合异步场景 |
PostgresSaver | 生产环境,PostgreSQL 存储 | pip install langgraph-checkpoint-postgres | 推荐生产环境,需数据库连接 |
AsyncPostgresSaver | 生产环境,异步 PostgreSQL 存储 | pip install langgraph-checkpoint-postgres | 适合高并发生产场景 |
MongoDBSaver | MongoDB 存储 | pip install langgraph-checkpoint-mongodb | 适合 NoSQL 场景,需 MongoDB 集群 |
AsyncMongoDBSaver | 异步 MongoDB 存储 | pip install langgraph-checkpoint-mongodb | 异步版本,需 pymongo 支持 |
RedisSaver | Redis 存储 | pip install langgraph-checkpoint-redis | 适合高性能缓存场景,需 Redis 服务器 |
AsyncRedisSaver | 异步 Redis 存储 | pip install langgraph-checkpoint-redis | 异步版本,适合高并发缓存场景 |
- 生产推荐:
PostgresSaver
或AsyncPostgresSaver
是生产环境的首选,因其稳定性高且支持大规模部署。 - LangGraph API:云端用户无需手动配置 Checkpointer,平台自动处理。
- 子图支持:子图默认继承父图的 Checkpointer,若需独立内存,可在编译时设置
checkpointer=True
。
2.3 状态与线程
- 状态格式:状态通常是字典或
TypedDict
,包含messages
等字段,具体由状态图定义。 - 线程管理:通过
thread_id
(配置中的configurable.thread_id
)区分不同会话或用户,确保检查点隔离。
3. 使用方法
3.1 基本用法
Checkpointer 在状态图编译时通过 checkpointer
参数传入。以下是一个使用 InMemorySaver
的示例:
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.graph import StateGraph
from langchain_core.messages import HumanMessage
# 定义状态
class State(TypedDict):
messages: List[BaseMessage]
# 定义状态图
workflow = StateGraph(State)
workflow.add_node("agent", lambda state: {"messages": state["messages"] + [AIMessage(content="Hello!")]})
# 添加边
workflow.add_edge("agent", END)
workflow.set_entry_point("agent")
# 创建 Checkpointer
checkpointer = InMemorySaver()
# 编译图
graph = workflow.compile(checkpointer=checkpointer)
# 运行,指定 thread_id
config = {"configurable": {"thread_id": "1"}}
input_message = HumanMessage(content="hi")
result = graph.invoke({"messages": [input_message]}, config)
print(result["messages"]) # 输出: [HumanMessage("hi"), AIMessage("Hello!")]
解析
- Checkpointer:
InMemorySaver
保存状态到内存。 - Thread ID:
thread_id="1"
标识会话,允许多个会话并行。 - 状态保存:每次节点执行后,状态自动保存,可通过
thread_id
恢复。
3.2 检查点管理
Checkpointer 提供方法管理检查点:
- 获取状态:
graph.get_state(config)
返回当前检查点。 - 历史记录:
graph.get_state_history(config)
列出所有历史检查点。 - 更新状态:
checkpointer.put(config, checkpoint, metadata)
更新检查点。 - 删除线程:
checkpointer.delete_thread(thread_id)
删除会话数据。
示例:
# 查看当前状态
state = graph.get_state(config)
print(state.values) # 输出: {"messages": [...]}
# 查看历史
for checkpoint in graph.get_state_history(config):
print(checkpoint.values)
3.3 数据库 Checkpointer
以下是使用 PostgresSaver
的生产环境示例:
from langgraph.checkpoint.postgres import PostgresSaver
import psycopg
# 连接 PostgreSQL
with psycopg.connect("dbname=langgraph user=postgres password=secret") as conn:
checkpointer = PostgresSaver(conn=conn)
# 初始化表
checkpointer.setup()
# 编译图
graph = workflow.compile(checkpointer=checkpointer)
# 运行
config = {"configurable": {"thread_id": "2"}}
result = graph.invoke({"messages": [HumanMessage(content="hi")]}, config)
解析
- 数据库连接:使用
psycopg
连接 PostgreSQL。 - 初始化:
checkpointer.setup()
创建检查点表。 - 持久化:状态保存到数据库,支持跨会话恢复。
4. 使用场景
Checkpointer 适用于以下场景:
- 聊天机器人:保存对话历史,支持多轮交互和上下文记忆,例如虚拟客服记录客户问题。
- 自动化工作流:在长运行任务中保存中间状态,方便错误恢复或暂停/恢复。
- 人工干预:实现工具审批或等待人工输入,例如人工审核代理生成的答案。
- 时间旅行:调试复杂工作流,编辑历史状态以测试不同执行路径。
- 教育平台:记录用户学习进度,跨会话恢复状态。
示例场景:
- 客服机器人:用户中断对话后,Checkpointer 恢复历史状态,继续交互。
- 数据管道:任务失败时,恢复到最近检查点,避免重新运行整个流程。
5. 注意事项
-
版本兼容性:
- LangGraph v0.2 及以上支持新 Checkpointer 库,确保使用最新版本(截至 2025 年 5 月 17 日)。
- 安装特定 Checkpointer 的包(如
langgraph-checkpoint-postgres
)。
-
存储选择:
- 测试:使用
InMemorySaver
,但不适合生产环境。 - 生产:优先选择
PostgresSaver
或AsyncPostgresSaver
,确保数据持久性和扩展性。
- 测试:使用
-
线程管理:
- 始终指定唯一的
thread_id
,避免会话冲突。 - 定期清理无用线程,释放存储空间。
- 始终指定唯一的
-
性能优化:
- 高并发场景使用异步 Checkpointer(如
AsyncPostgresSaver
)。 - 优化状态大小,避免保存冗余数据。
- 高并发场景使用异步 Checkpointer(如
-
调试:
- 使用
graph.get_state
和get_state_history
检查状态。 - 启用
debug=True
查看详细日志。 - 使用
graph.get_graph().to_dot()
可视化状态图。
- 使用
-
自定义 Checkpointer:
- 可扩展
BaseCheckpointSaver
实现自定义存储(如 DynamoDB)。 - 社区讨论(如 GitHub)提到 MongoDB 等 NoSQL 实现,但需验证生产就绪性。
- 可扩展
6. 总结
LangGraph 中的 Checkpointer 是一个强大的状态持久化组件,通过保存和加载检查点支持会话记忆、错误恢复、人工干预和时间旅行等功能。它提供多种实现,从内存存储(InMemorySaver
)到生产级数据库(PostgresSaver
),适应测试到部署的各种场景。Checkpointer 与状态图和工具节点无缝集成,增强了代理和复杂工作流的鲁棒性,特别适合聊天机器人、自动化任务等需要长期上下文的应用。正确配置 thread_id
和选择合适的存储后端是确保其有效运行的关键。