权限蠕变问题:AI 代理为何会累积本不该拥有的访问权限
Source: Dev.to
权限膨胀问题
我在几乎所有运行 90 天以上的 AI 代理部署中看到一种模式:
代理最初只有只读权限。后来它需要写文件。接着发送通知。再然后发布到 Slack。最后触发 webhook。
每一次单独的添加看起来都有道理。但合在一起,它们让代理拥有了远超预期的强大权限。
这就是权限膨胀——它是 AI 代理运营中最被低估的可靠性风险之一。
为什么会发生
AI 代理在生产环境中不断触碰其配置权限的边界。当它们这样做时,自然的反应是添加访问权限:
- 代理需要记录结果 → 获得对目录的写入权限
- 代理需要在失败时发出警报 → 获得 Slack webhook
- 代理需要更新记录 → 获得数据库写入权限
- 代理需要发送摘要 → 获得发送邮件的权限
这些单独的决定没有错。但很少有人会停下来问一句:“这个代理现在实际上能做什么?”
90 天后,答案通常是:比你想象的要多得多。
错误成本随访问权限而增长
| 代理能做的事 | 错误的代价 |
|---|---|
| 读取文件 | 令人恼火 |
| 写入文件 | 可恢复 |
| 发送内部消息 | 尴尬 |
| 发送外部邮件 | 严重 |
| 转移资金 | 灾难性 |
一个只读的代理出现漂移会产生错误输出。你发现后修复,继续前进。
拥有发送邮件权限的代理出现漂移,会在凌晨 2 点向 200 位客户发送一条混乱的消息。
能力本身没有改变——只是影响范围扩大了。
每月权限审计
-
列出它实际能做的事
不要仅依赖文档。检查它实际拥有的凭证、API 密钥以及可访问的文件路径。现实与文档往往很快出现偏差。 -
问:“这个代理可能执行的最糟糕的单一操作是什么?”
如果该行为会导致灾难性后果,无论其看起来多么不可能,你都存在问题。 -
应用最小必要访问原则
对于每项权限:它是否是代理核心功能所必需的?还是随着时间累积的便利性? -
记录你移除的内容
记录每一项被剥除的权限。如果后来发现它是合法必需的,你需要有记录说明为何将其移除。
SOUL.md 权限块
我合作过的最可靠的代理在其身份文件中都有一个明确的权限章节:
权限
可以不询问直接做的:
- 读取 /workspace 中的任何文件
- 写入 memory/ 和 logs/
- 向 outbox.json 投递
必须先询问后才能做的:
- 在 /workspace 之外写入
- 发送任何外部消息
- 进行任何具有写入权限的 API 调用
绝不可以做的:
- 发送电子邮件
- 进行金融交易
- 修改 SOUL.md 或配置文件
- 访问指定目录之外的文件
This isn't just documentation — the agent reads this file every turn. The permission boundaries are part of its working context, not a one‑time setup.
这不仅仅是文档——代理每回合都会读取此文件。权限边界是其工作上下文的一部分,而不是一次性设置。
重载规则
权限文档只有在代理实际读取时才有意义。大多数代理在初始化时只加载一次配置,随后随着会话累积上下文而偏离原始配置。
解决方案: 在每个回合开始时重新加载权限块,或至少在每个会话开始时重新加载。如果代理在每次行动前读取其权限边界,就不会漂移到本不该进入的领域。
实际设置
- 今天: 用 10 分钟列出你的代理拥有的所有凭证、API 密钥和文件路径。将其与你在构建时的预期进行对比。
- 本周: 在你的
SOUL.md中添加权限块。明确说明——代理可以做什么,需要批准的操作,以及它绝不应做的事情。 - 每月: 设置日历提醒,重新审计权限。应有计划地添加新访问权限,而不是被动地应对。
权限蔓延是一个缓慢累积的问题,最终会演变成快速危机。那些在生产环境中运行 6 个月以上且未出现事故的代理,几乎总是拥有明确且积极维护的权限边界。
我们使用的有效配置——包括在五个生产代理中通用的权限块模板——都在 Ask Patrick Library 中。