1583 字
约 5 分钟
7
审批门禁
无标签

系列:ToyAgent 智能体知识库 20/26

审批门禁:高危操作先过人

一句话核心:模型可以决定"做什么",但"能不能做"要过权限矩阵——风险分级、审批挂起、会话免审、超时默认拒绝,四个设计点构成运行期审批链路。

为什么需要

让智能体发邮件、删文件、执行命令——能力越强,误操作(或被诱导)的代价越大。前一章的 ask_user_question 解决"缺信息",这一章解决"缺授权":工具在注册时就标好风险等级,高危动作必须等人点头,模型自己无权放行。

核心设计哲学:模型的决策权与人的一票否决权分离。模型说"我要发邮件",门禁说"你先等等"。注意拒绝后操作根本没发生,而不是发生后再回滚——事后回滚对发邮件、删文件这类副作用操作基本不可行。

核心机制

四个设计点

设计点 教学实现 生产对应
风险分级 get_weather=安全只读;send_email / delete_file=高危写操作 提交期权限矩阵:Shell / 写文件 / 插件默认需人工审批
三档模式 AUTO_MANUAL_SAFE / ALWAYS_ASK / FULL_AUTO 宽松 / 标准 / 严格三档策略
会话免审 「批准并记住」→ 本会话同工具自动放行 会话级免审记忆:信任一次,不再打扰
超时默认 DENY 轨迹提示(教学为同步架构) 审批超时未响应 → 自动拒绝,宁可不执行

挂起-决策链

boolean needAsk = mode == Mode.ALWAYS_ASK
        || (mode == Mode.AUTO_MANUAL_SAFE && dangerous && !trustedTools.contains(tool));

if (needAsk) {
    pendingTool = tool;              // 审批挂起:先答复人,不执行
    return "⚠️ 即将执行高危操作:" + tool + "…… 回复「批准 / 拒绝 / 批准并记住」";
}
// 人回复后进入 resolveApproval:
//   批准 → 执行;拒绝 → 终止;批准并记住 → 加入免审名单后执行

判定逻辑读作:严格模式一律要问;标准模式下高危工具、且不在本会话免审名单里的,才要问。安全只读工具在任何模式都直通。

超时默认 DENY 而非 ALLOW,是把不确定性的代价留给可用性而非安全——任务失败可以重试,误发的邮件收不回来。

graph TD
    A["工具调用请求"] --> B{"权限矩阵评估风险等级"}
    B -->|安全只读工具| P["直通执行"]
    B -->|高危写操作| C{"审批模式判定"}
    C -->|FULL_AUTO 全自动| P
    C -->|AUTO_MANUAL_SAFE 标准| D{"在会话免审名单中?"}
    D -->|已在免审名单| P
    D -->|不在| E["会话挂起 PENDING_APPROVAL<br/>操作根本没发生"]
    C -->|ALWAYS_ASK 严格| E
    E --> F{"等待人的决策"}
    F -->|批准| P
    F -->|拒绝| X["拦截终止 零副作用"]
    F -->|批准并记住| Y["加入 trustedTools 后执行<br/>本会话同工具不再打扰"]
    F -->|超时未响应| X

风险分级判定流程:只读工具任何模式直通;高危工具按三档模式与免审名单决定是否挂起等审批,拒绝与超时都默认 DENY——拦截点在执行之前,保证拒绝即零副作用。

举例

一次"发周报邮件"的完整审批轨迹,覆盖三种人的决策:

用户:给团队发一封周报邮件

→ 权限矩阵评估:send_email 属高危写操作
→ 模式=AUTO_MANUAL_SAFE,trustedTools 不含 send_email → needAsk=true
→ 会话挂起 PENDING_APPROVAL,邮件内容未发送(操作根本没发生)

Agent:⚠️ 即将执行高危操作:send_email(收件人:团队,主题:周报)
       回复「批准 / 拒绝 / 批准并记住」

─── 决策一:批准 ───
用户:批准
→ resolveApproval:放行 → smtp 发送 → 任务完成。下次同工具仍会问。

─── 决策二:拒绝 ───
用户:拒绝
→ 拦截 → 任务终止 → 模型收到「用户已拒绝」的观察,转告用户并收尾。

─── 决策三:批准并记住 ───
用户:批准并记住
→ 执行 + trustedTools.add("send_email")
→ 轨迹出现「会话免审」标记;本会话内再发邮件直接放行,不再打扰。

─── 对照:安全工具 ───
用户:查一下北京天气
→ get_weather 是安全只读 → 权限矩阵直通,全程无审批打扰。

生产场景里"批准并记住"的粒度要谨慎:免审记到"工具级"(send_email)还是"操作级"(send_email 且收件人=团队)?粒度太粗,一次批准等于永久授权;粒度太细,审批打扰回到原点。常见折中是"工具级免审 + 参数白名单"。

面试考点

  1. 审批和 ask_user_question 有什么区别? 前者是"缺授权"(信息齐了,但操作危险),后者是"缺信息"(参数不全)。两者都会挂起会话,但挂起位类型、UI 形态(批准/拒绝按钮 vs 表单输入)和超时策略不同。
  2. 为什么超时默认 DENY? 安全与可用性权衡中,把不确定性代价归到可用性侧:任务失败可重试,误操作不可逆。默认拒绝是安全系统的标准姿势(fail-closed)。
  3. "拒绝后操作根本没发生"为什么重要? 发邮件、删文件、转账这类副作用无法可靠回滚;审批门禁把拦截点放在执行之前,是唯一能保证"拒绝=零副作用"的位置。

生产化路径

  • 审批请求持久化 + 审批人在线通知(IM / 邮件 / Webhook),超时自动 DENY 并记录审计。
  • 免审名单从会话级升级为可配置策略(按用户 / 按租户 / 按时段),并支持一键撤销。
  • 权限矩阵版本化管理:工具风险等级变更要走评审,避免"悄悄把高危工具降级成只读"。
  • 全量审计日志:谁在什么时候批准了什么操作、参数是什么——出事后能完整还原决策链。
审批门禁
https://clxhxhhr.top/posts/4720/
作者
clxstart
发布于
2026-10-13
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。