一个AI客服被授予了一项它根本不需要的权限,然后被派去处理一批底层数据并不支持的任务。结果完全可以预料。

在一次针对客户发票的测试中,这个智能体调出一条记录,确认扣款已经失败、客户账户里根本没有钱离开,然后它还是发起了退款。它毫不犹豫地把这个错误重复了五次。

打开网易新闻 查看精彩图片

这是 Claude Haiku 4.5 在一组专门用来捕捉这类逻辑缺陷的任务上,六次全错。而 Claude Sonnet 5 自己识别出了全部六个边界情况。在 Haiku 的系统提示词里加一行指令,要求它在执行财务操作前先核实交易状态,问题同样被解决了。

手里握着两个可用的修复方案,我一度相当有信心,直到意识到这两个变量我都不控制。下个季度有人为了削减推理成本,把客服流量切到更便宜的模型上,第一个修复就蒸发了。如果有人在实验过程中删改系统提示词,第二个修复也会消失,而且不会留下任何关于它曾维护过一道安全护栏的记录。

唯一扛得住你自己降本动作的安全控制

唯一稳定成立的运行,是那个智能体压根没有权限做决定的那一次。因为它的角色不包含 billing:refund,执行在权限层就失败了,底层用的是哪个模型变得完全无关。

这就是AI架构中最小权限原则的核心论点。它不只关乎恶意行为者或泄露的令牌;它关乎阻止一个行为良好的智能体,以机器速度、在零人工监督下,忠实地执行一条有缺陷的指令。唯一扛得住你自己降本动作的安全控制,是你一开始就没授予的那个权限。

角色是提前画好的,智能体的工作不是

一个标准服务账号获得某个角色,是因为一个微服务永远执行一项可预测的工作。支付服务处理支付;你划定一次范围,每年复核一次,然后就不用管了。

而智能体的工作负载在每次调用时都会变化。同一个客服智能体在09:00读一张工单,09:04发起退款,09:11修改座位数。它一周内可能做的所有事情的并集,和它在单次运行中需要的东西毫无关系。

问“一个智能体用掉了它权限集的多少”得到的是个没用的指标,因为那个数字反映的是你把凭证配得有多慷慨。授予400个范围,利用率看起来惨不忍睹;授予4个,看起来就很高效。你最终衡量的是一个随意的配置选择,而不是系统性风险。

一个有意义的计算,是独立于授权去评估任务分布。这个指标代表爆炸半径乘数。在一次被攻破的运行中,智能体触达的是所有范围的并集,而不是单个任务的子集。在我的测试套件里,这个系数达到了 11.0。20个任务的并集总计22个范围,而中位数任务只需要两个。

实验框架

我搭建了一个测试环境,在一个模拟企业API的九个域里设置了30个范围,覆盖工单、用户、账单、订阅、文件、消息、审计、管理和搜索。其中13个范围会修改或外泄状态。每条命令精确映射到一个范围,系统记录每一次尝试——无论被允许还是被拒绝。

测试套件包含20个任务,每个任务都以一个可机械验证的状态变更结束,而不是靠评估智能体的文字表述(例如关闭工单、退还发票,或计算座位超额并评论总数)。

在运行任何智能体之前,我为每个任务写了一份参考解法,它有两个作用:

  • 确认任务可以通过命令行界面解决,确保运行失败源于智能体,而不是一个不可能的环境。
  • 通过观察正确解法触及的确切端点,确立最小必需范围集。

我评估了四种权限模型,它们的区别严格在于执行那一刻哪些凭证是激活的:

  • 宽泛:一个长期凭证持有全部30个范围。
  • 角色:一个静态客服角色持有17个范围,源自一份典型职位描述。
  • 任务:根据声明的计划按次发放范围,运行结束时过期。
  • 即时(JIT):从零范围开始,按需申请每个范围并说明理由。

每个模型都跑两个LLM层级——Claude Haiku 4.5 和 Claude Sonnet 5——总计160次运行。测试栈严格依赖标准库Python,零外部依赖或API密钥,允许完整复现参考运行和指标。

爆炸半径与完成度

任务级范围划定实现了完整的任务执行,同时只持有宽泛授权十五分之一的凭证。偶尔被拒绝的调用和随后的重试,并没有显著增加整体API调用量,使得爆炸半径的缩减实际上是免费的。

角色级范围划定下那点完成度差距,并非源于权限失败。两个模型都在同样的十个任务上卡住了。单任务差异的出现,是因为一个任务数据集里包含三张主题完全相同的未关闭工单。Sonnet 在角色配置下拒绝猜测该关哪一张,而在另外三个模型下却选了编号最小的那张——即便角色授权包含了那个任务所需的全部范围。这属于模糊提示词下的标准运行间波动。

角色级配置同时太宽又太窄,因为它按职位头衔而非实际工作来分配权限。角色级范围划定在两个维度上表现都最差:它持有的凭证是任务级划定的8.5倍,完成的任务却只有一半。把角色授权和实际任务需求对比就能解释原因:它授予了四个没有任何任务调用过的范围。