LangGraph Checkpointer 用于保存 Agent 执行状态,支持 HITL(Human-in-the-Loop)中断恢复和会话持久化。
1. 概述
1.1 Checkpointer 的作用
| 功能 | 说明 |
|---|---|
| 会话状态持久化 | 保存 Agent 执行过程中的消息历史、工具调用栈、当前步骤 |
| HITL 中断恢复 | 当工具需要人工审批时,暂停执行并保存状态,审批后恢复 |
| 历史回溯 | 可以回到任意 checkpoint 查看或重放执行过程 |
| 服务重启恢复 | 服务重启后可从最近的 checkpoint 继续执行 |
1.2 与其他组件的区别
| 组件 | 存储内容 | 粒度 | 生命周期 |
|---|---|---|---|
| Checkpointer | Agent 执行状态(消息、工具调用栈) | 每步执行 | 会话级 (thread_id) |
| Backend | 文件系统(用户产物) | 文件操作 | 用户级 (user_id) |
| Memory | 长期记忆(用户知识、偏好) | 概念级 | 永久 |
2. 方案对比
2.1 存储方案选择
| 方案 | 延迟 | 持久性 | 成本 | 适用场景 |
|---|---|---|---|---|
| MemorySaver | ~0.1ms | ❌ 服务重启丢失 | 免费 | 开发环境 |
| PostgresSaver | 5-20ms | ✅ 强持久化 | 低 | 生产环境推荐 |
| RedisSaver | 1-5ms | ⚠️ 需配置持久化 | 中 | 高频 HITL 场景 |
| DrizzleCheckpointSaver (当前) | 50-100ms | ✅ 持久化 | 低 | 兼容 Next.js API |
2.2 推荐:PostgresSaver
理由:- 已有 PostgreSQL 数据库(Supabase/Drizzle),无需新增依赖
- LangGraph 官方支持,稳定可靠
- 延迟可接受(5-20ms)
- 可通过 SQL 查询历史 checkpoint,便于调试
3. 实现方案
3.1 替换 DrizzleCheckpointSaver 为 PostgresSaver
使用 LangGraph 官方提供的AsyncPostgresSaver,通过 DATABASE_URL 环境变量连接数据库。初始化时自动调用 setup() 创建所需的数据库表。
3.2 数据库表结构
PostgresSaver 会自动创建checkpoints 表,包含以下主要字段:
thread_id- 会话标识checkpoint_id- 检查点标识parent_checkpoint_id- 父检查点标识checkpoint- 检查点数据 (JSONB)metadata- 元数据 (JSONB)created_at- 创建时间
(thread_id, checkpoint_id) 的复合键,并在 thread_id 和 created_at 上创建索引。
4. HITL 工作流程
5. 迁移步骤
5.1 从 DrizzleCheckpointSaver 迁移到 PostgresSaver
- 安装依赖 - 安装
langgraph-checkpoint-postgres>=1.0.0 - 修改 base_service.py - 将 DrizzleCheckpointSaver 引用替换为 AsyncPostgresSaver
- 更新 get_checkpointer 方法 - 使用
AsyncPostgresSaver.from_conn_string()初始化 - 运行数据库迁移 - PostgresSaver 会自动创建所需表结构
- 删除旧代码 - 移除 DrizzleCheckpointSaver 和相关 Next.js API
6. 监控与调试
可以通过 SQL 查询 checkpoint 历史记录,包括查看某个会话的所有 checkpoint、查找中断状态的 checkpoint、以及清理过期的 checkpoint 数据。建议添加日志来追踪 checkpoint 的加载、保存和中断操作。7. 总结
| 项目 | 当前状态 | 目标状态 |
|---|---|---|
| Checkpointer | DrizzleCheckpointSaver (HTTP API) | PostgresSaver (直连) |
| 延迟 | 50-100ms | 5-20ms |
| 依赖 | Next.js API | 无额外依赖 |
| 持久化 | ✅ | ✅ |
| HITL 支持 | ✅ | ✅ |