取消、恢复与幂等
恢复时要判断哪一步已经产生了副作用、能不能安全重放。CongoRAG 把这件事放在业务层做,不依赖编排框架的 checkpoint。
三种崩溃现场
Section titled “三种崩溃现场”假设一个 4 步的 run 在第 3 步崩溃。库里可能看到三种现场:
| 现场 | 含义 | 恢复动作 |
|---|---|---|
step running,没有 effect 日志 | 没有证据说明工具跑过 | 按工具副作用等级:只读/幂等可重放;不可幂等拒绝 |
step running,有 effect 日志 | 工具确实跑过,但结果没落库 | 一律拒绝自动恢复 |
step completed,有结果 | 这一步其实完成了,只是游标没前进 | 当作已完成,从下一个未完成步骤继续 |
第二行是“账本有、步骤还是 running”。这个现场能识别,靠的是写入顺序:先提交 effect 日志,再更新步骤结果。顺序反了,同一个窗口就变成“步骤 completed、账本缺失”,恢复根本看不见。
拒绝时用户看到什么
Section titled “拒绝时用户看到什么”两种拒绝有不同的错误类型:
tool_effect_already_applied:副作用可能已经发生,平台不能替你决定重不重放。replay_unsafe:工具声明了不可幂等,或者策略是 never。
被拒绝的 run 停在 interrupted,不会自己好。用户能做的只有重新发起一次运行。
“静默重复执行一个已经生效的副作用”不可逆;“用户重发一次”只是多花一次额度。
升级时在途的 run
Section titled “升级时在途的 run”升级/重启时还在飞的 run,会被标成 interrupted。启动扫描不会自动把它们跑完;是否恢复由用户决定。
这样做的代价是升级后可能看到几条待处理的 run;收益是不会在 schema 刚变的时候自动重放旧逻辑。
发消息和发起 run 都接受 Idempotency-Key。同一个键重发时,服务端不重新执行,只把那一轮或那条 run 已经记录的事件按原 event_id 补发一遍。
适合网络超时后重试:你不知道上一次有没有成功,带同一个键重发即可。
幂等重放有窗口限制,具体见 ADR-008。