外观
持久化让 LangGraph 应用能够在单次图运行之外保留有用的信息。当智能体需要继续对话、从中断后恢复、从故障中恢复,或在多次交互之间记住信息时,这一点至关重要。
LangGraph 提供了两个互补的持久化系统:
- 检查点 将线程的图状态以检查点的形式持久化。用于短期、线程范围内的记忆,包括对话连续性、人在回路工作流、时间旅行和容错。
- 存储 将应用定义的数据持久化在图状态之外。用于长期、跨线程的记忆,包括用户偏好、事实和共享知识。
大多数应用可以同时使用两者:一个检查点追踪当前线程,一个存储追踪跨线程的持久信息。
快速开始
使用检查点、存储或两者同时编译你的图:
python
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.store.memory import InMemoryStore
checkpointer = InMemorySaver()
store = InMemoryStore()
graph = builder.compile(checkpointer=checkpointer, store=store)
result = graph.invoke(
{"messages": [{"role": "user", "content": "Hi, my name is Bob."}]},
{"configurable": {"thread_id": "thread-1"}},
)typescript
import { MemorySaver, MemoryStore } from "@langchain/langgraph";
const checkpointer = new MemorySaver();
const store = new MemoryStore();
const graph = builder.compile({ checkpointer, store });
const result = await graph.invoke(
{ messages: [{ role: "user", content: "Hi, my name is Bob." }] },
{ configurable: { thread_id: "thread-1" } }
);INFO
Agent Server 会自动处理持久化 使用 Agent Server 时,你无需手动实现或配置检查点或存储。服务器会在后台处理所有持久化基础设施。
检查点与存储
| 检查点 | 存储 | |
|---|---|---|
| 持久化内容 | 图状态快照 | 应用定义的键值数据 |
| 作用范围 | 单个线程 | 跨线程 |
| 记忆类型 | 短期、线程范围内的记忆 | 长期、跨线程的记忆 |
| 用途 | 对话连续性、人在回路、时间旅行和容错 | 用户偏好、事实和共享知识 |
| 访问方式 | 在图配置中传入 thread_id | 从节点或应用代码中读写条目 |
| 完整指南 | 检查点 | 存储 |
常见问题排查
PostgresSaver:thread_id 过长
使用 PostgresSaver(或 AsyncPostgresSaver)时,thread_id 存储在长度受限的列中。如果 thread_id 超过列大小,你将会看到数据库错误。
修复方法: 将 thread_id 值保持在 255 个字符以内。如果需要确定性 ID,请使用 UUID 或哈希:
python
import uuid
config = {"configurable": {"thread_id": str(uuid.uuid4())[:255]}}MemorySaver 在重启之间无法持久化
MemorySaver 和 InMemorySaver 将检查点存储在内存(RAM)中。进程重启时,所有检查点都会丢失。
修复方法: 在生产环境中使用持久化检查点:
PostgresSaver:支持异步的 PostgreSQLSqliteSaver:适用于开发环境的本地文件存储
检查点无限增长
在长时间对话中,检查点会不断累积。这会增加延迟和存储成本。
修复方法: 定期清理旧的检查点或设置保留策略:
python
from langgraph.checkpoint.postgres import PostgresSaver
checkpointer = PostgresSaver.from_conn_string("postgresql://...")
checkpointer.setup() # 创建带索引的表
# 考虑添加一个 cron 作业来删除超过 N 天的检查点从父图访问子图的状态
当子图更新状态时,父图可能无法立即看到这些更改。这是因为每个子图都管理自己的检查点命名空间。
修复方法: 对于需要跨越图边界的数据,使用通过存储共享状态,或配置子图写入父检查点。