技术 · 熟练

崩了之后,哪些动作可以重来一遍?

不是「重试」,是「上一次到底做没做」
Agent 跑到一半被关机、超时、或者进程被杀,重启后最常见的动作就是「从头再跑一遍」—— 而真正出事的不是那一次失败,是失败前那个已经生效的写入被做了第二遍:重复下单、重复发信、重复部署。这一页给的是把「可重放」写进工具定义:先按副作用把动作分成只读 / 可重入 / 一次性三类,再给每个工具写一行 replay 策略,最后给写操作配一个幂等键 —— 崩溃之后第一件事是查,不是再跑。
方法 · 一图看懂
1
先按副作用分三类 — 只读(查、读文件、搜索)· 可重入(写同一份结果、置状态)· 一次性(下单、付款、发信、部署)
2
每个工具写一行 replay 策略 — safe(崩了可以重跑)/ never(崩了只能查结果)/ check-then-act(先查再决定)
3
中断要告诉模型 — 返回一条「这条调用被中断、结果未确认」,而不是空结果或让它自己猜
4
给写操作配幂等键 — 同一个 requestId 重发 = 查结果,不是再做一次
原理 · 为什么有效
崩溃恢复真正的问题从来不是「要不要再试一次」,而是「上一次到底做没做」。失败有两种:调用没发出去(重试安全)与调用发出去了、结果没回来(重试就可能做两遍)。两者在日志里长得几乎一样 —— 除非你在调用发起前就把一个可复用的键写进了请求里,让第二次调用变成「查这个键的结果」。这就是幂等键的作用:它把「未知」变成「可查」。而没有这个键时,任何「自动恢复」都只是在赌副作用不会重复。
适用场景
适用:有定时任务 / 无人值守 agent、会调用外部写操作(下单、付款、发信、部署、改配置)的人;也适用于只跑一次的长任务 —— 它崩在 90% 的概率并不低。⛔ 不适用:纯对话、只读检索这类没有副作用的场景(加这层只会增加无谓的复杂度)。
自测 · 5 问
你能说出 agent 会做的全部写操作吗(不是「大概会写文件」,而是具体哪几个接口)?
每个写操作是否有一个调用方生成的唯一键,而不是服务端生成?
崩溃恢复后,代码的第一动作是查还是重跑?
有没有一个动作重跑两次会造成真实损失(钱、对外消息、线上版本)?
中断时模型拿到的是「未确认」还是「空结果」—— 它会不会因此编一个结果继续往下走?
怎么上手 · 验证步骤
先只做一个动作:挑最贵的那一个写操作(扣费 / 发信 / 部署),在调用前生成一个 requestId 并写进请求,重试时带同一个键去查结果。跑通这一个,再把 replay 策略补到其余工具上。全程约 30 分钟,不需要改模型,只改调用侧的两三行。
手动杀一次进程,然后看它恢复后第一件事做什么:如果是「把上次的调用再发一遍」,这条链就还没修好;如果是「拿 requestId 去查状态」,才算过。
[C级]Pi Durable 发布说明(工具级 replay 策略 · 中断后告知模型而不是让它再猜 · requestId 保证 exactly-once) [C级]GitHub Trending 摘要 2026-10-17(Pi 1.0 与 Pi Durable 同周进入前十 · 1,200+ 分) [C级]生产级 MCP server 实践(读工具与写工具分开命名 · destructive 注解只作提示,不作安全边界) [C级]OpenAI 官方 Deprecations(2026-10-23 批量停服:停服后同样的调用直接报错,这与「动作其实已生效」是两件事) 同类:Agent 调工具失败,别只说「重试一下」 · 给它成熟工具,还要它交证据
继续往下读
同级:Agent 调工具失败,别只说「重试一下」 下一级:给它成熟工具,还要它交证据 随机一篇