一个 Agent 正在执行“创建订单→扣款→发邮件”。订单已经创建成功,但进程恰好在写入下一步状态前崩了。服务重启后,Agent 从上一个 Checkpoint 恢复,又创建了一遍订单。
这类问题麻烦的地方,不是 Agent 能不能恢复,而是恢复后还能不能判断:哪些事已经做过,哪些事做到一半,哪些事绝不能再做一次。
所以,Checkpoint 真正要解决的,不只是“保存上下文”,而是“让执行过程可以安全继续”。
Checkpoint 太少,恢复点会离真实世界越来越远
Checkpoint 很少,看起来能减少存储和写入成本,但代价是恢复粒度变粗。
假设 Agent 连续执行 5 个步骤,只在开始和结束时保存状态。执行到第 4 步失败,恢复后系统只能回到第 1 步。前 3 步如果只是推理、查询,重做问题不大;如果包含付款、发消息、创建工单,就可能产生重复副作用。
Checkpoint 太少还会丢失“执行证据”。系统无法准确回答某个 Tool 是否调用过、参数是什么、外部系统是否已经返回结果。
因此,Checkpoint 不该按“每几步一次”机械设置,而应围绕关键边界:高成本操作前、产生外部副作用后、关键状态变化时,都值得保存。
Redis 还是数据库?先看你想保住什么
把这个问题简化成“Redis 快,数据库可靠”并不够。
如果 Checkpoint 只是短生命周期的运行快照,用于短时间内重试、暂停和恢复,Redis 很合适:读写快、TTL 方便。
但如果它还承担审计、故障恢复、跨节点接管、长时间挂起等职责,数据库通常更合适,因为你需要持久性、事务能力和可追踪性。
常见做法是分层:Redis 保存活跃运行状态,数据库保存关键执行记录。重点不是选一个,而是区分“可丢的缓存”和“不能丢的事实”。
Tool 执行一半时,Checkpoint 不能暂停现实世界
“Tool 执行一半能不能 Checkpoint?”可以保存状态,但不能假装已经安全暂停。
如果 Tool 是纯计算任务,比如文本处理,可以把中间进度设计为可恢复状态。但如果 Tool 调用了支付、ERP、邮件系统,它的执行边界已经跨出了本地进程。
最危险的情况是:外部操作已经成功,本地却没来得及写成功记录。此时 Checkpoint 只能告诉你“准备执行过”,不能证明“外部世界是否完成”。
对有副作用的 Tool,最好显式记录状态:
pending → executing → succeeded / failed / unknown
unknown 很重要。它表示系统无法确认结果,恢复时不能直接重试,而应先查询外部系统。
Resume 后,不要让模型猜 Tool 是否执行过
恢复后最不可靠的做法,是让模型根据上下文判断:“这个 Tool 好像已经执行过了。”
正确判断应来自结构化执行记录。
每次 Tool 调用都生成唯一 operation_id,并保存 Tool 名称、参数摘要、状态、外部返回标识。恢复时先查这条记录。
状态是 succeeded,就复用结果;failed 可以按策略重试;executing 或 unknown,则先向外部系统查询,而不是立即重放。
这相当于给外部动作一张“执行凭证”。上下文可以丢,模型可以换,但凭证必须稳定存在。
避免重复 Side Effect,关键是幂等
Checkpoint 再频繁,也无法消除崩溃窗口。
“支付成功”和“写入 Checkpoint 成功”之间永远可能宕机。靠多存几次状态解决不了这个问题。
更可靠的方法,是让副作用操作具备幂等性。最典型的是给外部请求带 idempotency key。相同 operation_id 即使重试多次,外部系统也只执行一次。
如果外部系统不支持幂等键,就自己做去重层:调用前登记 operation_id,调用后保存结果;恢复时先查本地记录,再查外部状态,最后决定补偿还是重试。
对于既无法查询、也无法幂等的操作,例如某些消息发送接口,就要提前接受风险:引入 Outbox 等可靠投递机制,或接受“至少一次”语义,并在业务层做去重。
一个实用的设计判断
设计 Agent Checkpoint 时,每一步先问三个问题:失败后能不能安全重做?它有没有修改外部世界?恢复后有没有可靠证据判断它做没做过?
如果答案是“不能、会、没有”,它就是高风险步骤,需要持久化执行记录、幂等控制或结果查询机制。
这也是为什么成熟的 Agent Runtime 更像工作流引擎,而不只是“模型加几个 Tool”。真正困难的不是让模型持续思考,而是让一个可能随时中断的执行过程,在现实世界里保持一致性。
Checkpoint 的价值,不在于保存得多,而在于把“可重算的状态”和“不可重复的事实”分开。前者可以缓存,后者必须可靠落盘。
如果只能记住一个原则:Agent Resume 的目标不是“从哪里继续”,而是“继续时不会把已经发生过的事再发生一次”。

