为什么“全自主”是生产环境的最大隐患?
在个人玩具项目中,我们可以允许 AI 自主执行任何命令;但在生产环境中,涉及转账、向数千名客户发送营销短信或执行数据库 DDL 变更的操作,必须由人类决策者签字确认。
挂起-恢复(Suspend-Resume)架构设计
- 工具拦截器标记:将高危 MCP 工具打上
requires_approval: true元数据; - 长事务快照持久化:当调度器遇到该工具调用时,不立即发往执行端,而是将当前完整的 AgentState 序列化存入持久化数据库,并在消息总线上发布审批事件;
- 人类审批与修订:主管在 Slack 机器人或管理后台收到审批推送,可选择批准、拒绝,或者对大模型生成的入参进行微调;
- 反序列化恢复驱动:收到确认信号后,状态机重新加载 State 快照,注入人工确认凭证,驱动工作流继续平稳往下推进。
落地示例:一次 DDL 变更的审批时序
把抽象步骤落到具体消息上,一条最小可用的审批链路包含六个字段:任务标识、发起人、待执行工具名、入参摘要(脱敏后)、风险提示、有效期。缺少有效期是常见事故源——三天后才被点开的"同意",对应的上下文早已失效。
推荐的实现顺序:先在拦截器里只做"记录并放行",观察一周内哪些工具会命中高危名单,再决定审批门槛;随后接入消息总线,把审批做成独立的消费者而不是同步阻塞调用;最后才加上参数修订能力。参数修订必须重新计算入参摘要并再次落快照,否则下游拿到的就是人工改过、模型没见过的参数。
三种审批形态的取舍
| 形态 | 响应延迟 | 实现成本 | 适用场景 |
|---|---|---|---|
| 同步阻塞等待 | 分钟级到小时级 | 低 | 单步高危操作 |
| 异步事件加快照恢复 | 不占用执行资源 | 中 | 长链路多步任务 |
| 阈值以下自动放行 | 无等待 | 中高 | 金额或行数可量化的操作 |
阈值形态最实用也最危险:例如"影响行数低于经验值 1000 行的更新自动通过",一旦阈值设置过宽,审批就会形同虚设,因此阈值本身要纳入审计并可随时收紧。
验证方法
上线前跑三类演练。第一类是恢复正确性:挂起后杀掉进程,重启时确认状态机能从快照继续且不重复执行已审批的工具,这一步验证的是幂等。第二类是审批逃逸:构造一个未标记高危但实际会写库的工具,确认它要么被名单拦住、要么在审计里可追溯。第三类是超时行为:让审批在有效期内无人响应,确认任务进入明确的待办或失败状态,而不是永远挂在运行中。
常见故障速查
| 现象 | 原因 | 处理 |
|---|---|---|
| 恢复后同一操作执行两次 | 快照与副作用非原子提交 | 先写执行意图再调用,按任务标识去重 |
| 审批单里的参数与实际执行不一致 | 人工修订后未重新落快照 | 修订即重建摘要并再次持久化 |
| 任务长期停在挂起状态 | 审批事件丢失无人重试 | 加有效期扫描与到期提醒 |
| 高危工具未被拦截 | 名单靠人工维护已过期 | 以工具元数据为准并定期全量校验 |
| 批准后仍报权限错误 | 人工凭证未注入执行上下文 | 恢复时重建带凭证的执行身份 |
小结
人在回路不是加个弹窗。可执行的判断标准是三个问题:任意时刻杀掉执行端,重启后任务能否继续且不重复副作用;任意一次高危执行能否在审计里找到对应的审批人和当时的参数摘要;审批过期后系统是否会主动收敛到安全状态。三问有一个答不上来,就还不该把生产权限交给 Agent。落地时可以按 基于 LangGraph 构建带状态回滚与人在回路的多 Agent 协作系统 的做法先搭状态机骨架。