P06 幂等副作用¶
Release Candidate 1
主要章节:第6、9、11章
Context¶
Agent调用支付、退款、发送、删除、部署等写工具;网络可能超时,Worker可能重启,运行可能恢复。
Problem¶
调用方无法仅凭超时判断副作用是否发生。盲目重试可能重复执行,不重试又可能漏执行。
Forces¶
- 质量:业务动作必须准确执行一次;
- 延迟:状态查询增加一次往返;
- 成本:需要幂等记录和权威查询;
- 安全:Replay不能重复副作用;
- 运维:恢复过程必须可解释。
Solution¶
使用稳定业务幂等键绑定主体、资源和已批准动作Digest。工具执行原子地保存键和结果;相同键重复调用返回原结果。超时后先查询幂等记录或权威业务状态,再决定是否重试。
Checkpoint(intent + key)
→ Execute(key)
→ Persist result
→ Verify authoritative state
→ Checkpoint(completed)
Consequences¶
收益¶
- 支持安全重试和进程恢复;
- 防止网络抖动造成重复动作;
- 提升审计和故障处理能力。
代价¶
- 需要业务级键设计和持久存储;
- 请求语义变化必须产生新键;
- 外部系统不支持幂等时需适配层或人工处置。
Failure Modes¶
- 使用随机键,重试时键变化;
- 只按Run ID去重,无法表达业务动作;
- 相同键接受不同载荷;
- 把幂等误解为可撤销;
- 只记录请求,不验证最终状态。
Implementation Sketch¶
def execute(action, key):
existing = store.get(key)
if existing:
assert existing.action_digest == digest(action)
return existing.result
result = provider.execute(action, idempotency_key=key)
store.put_once(key, digest(action), result)
return verifier.check(result)
Evidence¶
- 蓝皮书章节:第6、9、11章;
- 实验卡:恢复、工具和生产实验按场景绑定;
- 外部标准:具体支付或消息系统的幂等契约需逐项核验。
Exit Criteria¶
纯只读或数学计算没有外部副作用时无需业务幂等记录;仍需处理调用去重和资源预算。
Checklist¶
- [ ] 键由业务语义稳定导出。
- [ ] 键绑定动作Digest。
- [ ] 工具可查询权威状态。
- [ ] 超时后先查状态再重试。
- [ ] 重复调用返回相同结果。
- [ ] 补偿与幂等分开设计。