2026-09-18 · 让 Agent 在高风险动作前停得下来
为什么今天学这个
Agent 不是后台黑盒。读日历可以自动做,但发邮件、提交报销或扣款前,用户必须看见动作、影响和撤销边界,并能确认或拒绝。
一张图讲清楚
用户目标 → 计划与影响预览 → 风险判断 → 用户确认 → 幂等执行 → 状态/审计 → 成功、未知或人工接管
三个核心要点
- 确认要绑定不可变的计划 ID,参数变化就重新确认。
- 写入、外发、支付和权限变更按风险分级,不让模型自行决定策略。
- unknown 不是 failed;先按幂等键查询外部状态,再决定恢复或人工接管。
最小可运行示例
from hashlib import sha256
def plan_id(tool, recipient, body):
return sha256(f"{tool}|{recipient}|{body}".encode()).hexdigest()[:16]
def execute(plan, confirmed):
return "EXECUTED" if plan_id(*plan) == confirmed else "WAITING_CONFIRMATION"
p = ("send_email_v1", "user@example.com", "会议确认")
print(execute(p, plan_id(*p)))生产环境会怎么翻车
- 确认后参数被替换:绑定计划哈希并执行前复核。
- 取消时外部请求已发出:把不可撤销边界写进预览,必要时使用补偿动作。
- 超时被盲目重试:先按幂等键对账,未知状态转人工。
- 弹窗疲劳:低风险动作策略化聚合,高风险保留单独确认。
动手练习
给 create_reminder_v1 增加 waiting_confirmation 状态,并测试拒绝、重复确认、超时未知三条路径;完成条件是每条都有可读审计记录。
面试表达
30 秒回答
我会把 Agent 拆成计划、确认、执行和对账四段;副作用动作绑定计划版本确认,执行使用幂等键,未知状态先查询不盲重试,所有步骤可审计,超预算人工接管。
追问
模型可以提出风险理由,但服务端策略决定是否确认,因为模型输出会漂移且不可信。
今日自测
为什么确认要绑定计划 ID?
因为确认的是具体参数和副作用,不是整个会话的永久授权。
支付超时 UI 显示什么?
显示结果待核验并触发查询,不显示失败后让用户直接再次支付。
权威来源
明天会用到
把注册、超时、幂等、确认和审计串成求职助理最小系统。