写入途中崩溃,怎样安全恢复
Agent 调用 write 更新 result.txt。文件系统已经返回,进程却在 tool_finished 写入 Session 之前退出。
重启后只剩一条 tool_started。如果恢复器直接重跑,文件会再写一次;把工具换成发消息、创建工单或提交订单,重复副作用会更加麻烦。
这类故障不能靠聊天摘要解决。系统缺的是一份落在副作用两侧的操作记录。
四份记录各自解决什么
Section titled “四份记录各自解决什么”| 构件 | 它回答的问题 |
|---|---|
| Trace | 这一轮按什么顺序发生了什么 |
| Session | 哪些消息与状态已经持久化 |
| Checkpoint | 恢复时从哪个已确认位置继续 |
| Operation Journal | 某个外部动作是 started、completed 还是 interrupted |
Trace 便于诊断,却不会阻止重复。Checkpoint 能保存待执行 tool call,但如果工具上次已经启动,恢复器仍需要判断能否安全重试。
先判断能不能重试
Section titled “先判断能不能重试”只读查询通常可以重试,写入和外部发布通常不能。教学项目给 Tool 增加 retrySafe 元数据,并按以下顺序执行:
检查 journal 中的旧记录 ↓completed:复用已保存结果 ↓started / interrupted: retrySafe=true 才允许重试 retrySafe=false 返回 blocked ↓journal.start() ↓tool.execute() ↓journal.complete(result)如果同一个 call ID 被拿来执行另一组参数,恢复器也会失败。调用身份与参数摘要必须一起核对。
后面会反复用到三个词:
- 幂等:同一动作执行一次或多次,最终效果相同;
- 幂等键:让外部服务识别“这仍是同一次动作”的稳定标识;
- reconciliation:查询现实状态,再把本地记录与现实对齐。
真实业务更适合使用稳定的 idempotency key,而不只依赖模型生成的 tool call ID。例如:
task-42:update-file:result.txt:content-sha256同一次恢复和重试复用这个 key,目标或内容变化时才生成新 key。外部 API 如果支持幂等键和结果查询,应直接使用它们。
Pi 当前做到哪一步
Section titled “Pi 当前做到哪一步”Pi 的 durable harness 文档列出了未完成模型流、队列持久化、非幂等工具与 operation 记录等故障模型。查看固定版本的故障分析。
同一份文档提出 operation 与 tool 生命周期的记录方案,查看设计草案。这是仍在发展的设计方向,当前 Coding Agent 不能据此被描述为任意位置可恢复。
新的 AgentHarness 已有 Session、turn snapshot 与保存点,但完整恢复、自动 compaction 与通用 hook 仍有待办。查看 AgentHarness 进度。
模拟一次状态不明的写入
Section titled “模拟一次状态不明的写入”第八个 Lab 预先放入一条 started 的 write 记录,随后带着原 Checkpoint 恢复。恢复器能够找到同一个 tool call,但写工具被标记为不可自动重试。
cd agent-harness-labnpm run lab -- 08预期输出:
{ "terminal": "blocked", "reason": "write 上次执行没有完成记录,不能自动重跑", "writes": 0, "recoveryEvent": "write 的副作用状态不确定"}工作区已经含有目标内容,用来模拟“副作用可能发生”。关键观察是本次恢复的 writes 仍为 0。系统没有根据“journal 没写 completed”推断“外部动作一定没有发生”。
接下来应由用户或专用 reconciliation 工具检查真实环境,再决定记录为 completed、回滚,或创建一项人工修复任务。
离开内存实验还要补什么
Section titled “离开内存实验还要补什么”当前 MemoryOperationJournal 只服务离线实验。生产版本至少还要:
- 在数据库事务中追加 operation 与 tool 状态;
- 为外部动作保存业务 ID、参数哈希和结果摘要;
- 明确 crash 后谁负责 reconciliation;
- 对 completed 结果做缓存与重放;
- 记录每次人工决策与操作者;
- 让 Trace、Session 与 Journal 共享稳定的 run ID。
到这里,my-pi-agent 已经覆盖模型接缝、Tool Loop、权限、上下文变换、Session、停止、Verifier 和恢复防线。下一章回到 Pi 的 Extension、Skill 和 SDK,组装一个能在真实仓库里工作的领域 Agent。