问题与目标
内存中的图在进程退出后会丢失进度,长任务失败后从头执行还可能重复昂贵调用或副作用。LangGraph 的 Checkpointer 在执行步骤保存状态快照,并用 thread_id 组织同一任务或会话的状态历史。
本篇为图加入内存 Checkpointer,查看当前状态和历史,并说明重试、缓存、故障续跑与时间回溯的边界。内存存储只用于本地学习,生产必须使用持久后端。
核心概念
- Checkpoint:某个执行步骤后的状态快照;
- Thread:一组连续 Checkpoint 的逻辑标识;
- Checkpointer:负责保存与读取快照的实现;
- Durable execution:流程重启后从已保存进度继续,而不是重新执行全部步骤;
- State history:用于检查、回放或从历史分支出新的执行路径。
thread_id 是持久游标,不是授权机制。服务端必须把它与已认证用户和租户绑定,不能允许用户读取任意线程。
可运行实现
python -m pip install "langgraph>=1,<2"
from typing_extensions import TypedDict
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.graph import END, START, StateGraph
from langgraph.types import RetryPolicy
class State(TypedDict):
device_id: str
status: str
attempts: int
def read_device(state: State) -> dict:
return {"status": "offline", "attempts": state["attempts"] + 1}
def summarize(state: State) -> dict:
return {"status": f"{state['device_id']}:{state['status']}"}
builder = StateGraph(State)
builder.add_node(
"read_device",
read_device,
retry_policy=RetryPolicy(max_attempts=3),
)
builder.add_node("summarize", summarize)
builder.add_edge(START, "read_device")
builder.add_edge("read_device", "summarize")
builder.add_edge("summarize", END)
graph = builder.compile(checkpointer=InMemorySaver())
config = {"configurable": {"thread_id": "u-17:task-88"}}
print(graph.invoke({"device_id": "AX-3", "status": "", "attempts": 0}, config))
print(graph.get_state(config).values)
for snapshot in graph.get_state_history(config):
print(snapshot.next, snapshot.values)
RetryPolicy 应只覆盖可重试异常。节点包含写操作时还要使用幂等键,因为重试、恢复或时间回溯都可能重新执行节点。
生产环境应替换为数据库 Checkpointer,并测试:进程重启、并发线程、Schema 升级、存储故障、保留期和加密。缓存用于避免重复计算,不等同于 Checkpoint,也不能保存带权限差异的结果而忽略缓存键。
常见问题与排查
使用 Checkpointer 却没有传 thread_id
持久化图需要稳定线程标识。检查配置是否放在 configurable.thread_id,并确认每个用户或任务使用正确的隔离键。
所有异常都交给 RetryPolicy
参数、权限和业务冲突不应重试。网络瞬时失败可以退避,外部写入还必须验证幂等性。
进程重启后内存 Checkpoint 消失
InMemorySaver 只适合测试。生产选择 SQLite、PostgreSQL 等持久实现,并做备份恢复与版本兼容测试。
时间回溯被当成撤销外部操作
Checkpoint 只能回放图状态,不能自动撤销已经发出的邮件、支付或工单。外部副作用需要补偿事务或人工处理。
小结
Checkpoint 让 Agent 从一次性循环变成长时间存在的任务状态机。Thread 负责关联历史,Retry 处理可恢复失败,状态历史支持排查和分支;外部副作用仍需要幂等与补偿机制。
许可协议:CC BY-NC 4.0
更新于 1 小时前
觉得文章有帮助?点个赞吧!
0 条评论


