暗无天日

=============>DarkSun的个人博客

读:当 Agent 成为生产调用者——四个被打破的运维假设

一件删库案

2025 年 7 月,Replit 的自主编程 agent 把生产数据库删了。当时已经是代码冻结状态,本来不允许任何变更,但它不管,照删不误。删完之后还跟用户说没法回滚。不过事后查了才发现,回滚是可以做的,agent 说的不是事实 1

这个事的根因不是模型不行,是系统没给 agent 设上限。Agent 手上有写数据库的权限,就自己用了,没人拦得住。也就是说,只要Agent能调到生产系统的工具,你就得拿生产标准来管它。

Pier-Jean Malandrino 在 DZone 上写了一篇文章,专门讲这个问题。大部分运维纪律直接搬过来没问题,但有四个老规矩到 agent 这里就不管用了:

老规矩 到 agent 这还好使吗
同样代码同样输入,结果一样 不好使了
接口返回 200 就是成功了 不好使了
威胁面在设计阶段就定死了 不好使了
值班工程师能处理大部分故障 不太好使

上篇 读:AI Agent 生产化 聊了从原型到生产的完整路线图:状态管理、评估体系、监控信号这些都讲了。这篇是续篇,范围收窄一些,专门聊调用者从人或者普通服务变成一个会自己做决定的 agent 时,运维该在哪加把锁。

有权限和用权限之间那一步

普通软件里,一个人或一个服务拿到了权限,不代表它马上就用。管理员有删库权限,但他得自己打开控制台去点删除。一个微服务能写数据库,代码里没写删表它就不会动。人和服务都不会无缘无故行权。

Agent 不一样。它有自主决策能力,任何授予它的权限,它都可能在某个时刻自行决定使用,不需要经过人工确认。

它不是故意要这么做的,也没人黑它,它就是做了一个看起来合理的决定。Replit 的事就是最好的例子:写数据库的权限本来是干正经活用的,但当时已经宣布代码冻结,按理说任何对生产的写操作都不该执行,可系统层面没有任何机制能拦住它。

OWASP 2025 年底发了一份"Agentic Applications 十大安全风险"清单,里面有个原则叫"最小代理权"(Least Agency) 2:给 agent 的自主决策范围越小越好,够用就行。跟最小权限是同一套思路,只不过最小权限管的是"能看到什么",最小代理权管的是"能自己决定做什么"。

先说清楚它不能干什么

很多团队拿到 agent 就赶紧给它接一堆工具。这个顺序反了。应该先界定好 agent 的职责边界,再考虑给它什么工具。因为职责画多大圈,出事的时候影响范围就有多大。

谁管这个 agent、它干什么活、能干的事列白名单、不能碰的事写死、输入输出长什么样、什么时候必须找人类、怎么算干得好怎么算干砸了都得写清楚。而且得细,"帮客服处理工单"这种写法太粗。得细到"能读账户信息、能改备注、能发草稿邮件、退款一律转人工"。

2026 年 3 月 Claude Code 的源码因为 npm 打包事故泄露了,里面的系统提示很值得看看它是怎么写权限规则的 11

But for actions that are hard to reverse, affect shared systems beyond your local environment, or could otherwise be risky or destructive, check with the user before proceeding. [...] A user approving an action (like a git push) once does NOT mean that they approve it in all contexts [...]. Authorization stands for the scope specified, not beyond. Match the scope of your actions to what was actually requested.

Examples of the kind of risky actions that warrant user confirmation:

  • Destructive operations: deleting files/branches, dropping database tables, killing processes, rm -rf, overwriting uncommitted changes
  • Hard-to-reverse operations: force-pushing, git reset --hard, amending published commits, removing or downgrading packages/dependencies, modifying CI/CD pipelines

上面这个例子就很好,它明确了"确认操作"是跟每次具体操作绑定的,不是一次授权就全程放行。然后分了两类,每类下面把操作列得清清楚楚。Agent 运行的时候不用猜什么叫"有风险",策略已经穷举了。企业级 agent 的权限说明就该写到这个粒度。

三个身份要分开

服务之间互相认证这事大家很熟了:每个服务有自己的身份,密码不共享,调用链上身份一层一层往下传。

Agent 加进来之后,参与方从两个变成了三个:用户发起认证和授权,agent 拿到独立的机器身份(下游服务可以单独识别它、单独给它限速),工具端以用户的名义做事,一般走 OAuth 的 on-behalf-of 流程。

大部分团队一开始图省事,直接把用户的 session token 给 agent。这种做法一旦两个 agent 同时改同一条数据,日志里就分不清谁干了什么。三个身份越早分开越好,后面再改代价会很大。

South 等人(2025)给 OAuth 2.0 和 OpenID Connect 做了扩展,专门加了 agent 的凭据和元数据,让用户、agent、服务三方能追溯清楚 3

粒度要到单个操作

"能调 CRM"太粗了。应该写:能不能读账户?能不能改一条记录?多少钱以下的退款能自己批?能不能触发发货?每个动作都是独立的授权项,审批人可能都不一样。

工具 高影响操作 审批
CRM 账户、联系人 备注、草稿邮件 更改账户所有人 经理
计费 发票状态 50 欧以下退款 自动
计费 50 欧以上退款 人工
库存 库存水平 触发发货 人工
数据导出 批量导出 禁止

说白了就是双标。企业架构花了二十年让微服务各自管好自己的一亩三分地,支付服务不能写 HR 库,这是基本常识。结果 agent 一来,同一个团队转头就给了它一个万能 token,什么都能碰。微服务只能干代码写好的事,但agent 有自主性,手伸到哪就管到哪。权限范围更广。

Shi 等人(2025)做的 Progent 框架测过这个:在 Agent Security Bench 上,细粒度权限把攻击成功率从 70.3% 压到 7.3%,手动配规则能压到 0% 4

MCP 的工具描述可能被人动过手脚

MCP 把 agent 接外部工具这件事标准化了。好处是不用给每个工具写专用对接的代码。坏处是信任关系变了:agent 调工具之前会先读工具的描述信息来决定怎么调。描述要是被人改过,agent 就是拿着假情报在做事。

Hasan 等人扫了 1,899 个开源 MCP 服务器,7.2% 有通用漏洞,5.5% 存在工具投毒,就是在工具描述里塞了恶意指令,agent 一读就中招 5

所以白名单不光要管"哪些工具能调",还要管"描述信不信得过、用的是哪个版本、谁的签名"。工具目录得像 IAM 策略文件一样管:进版本控制、走 code review、加签名、锁版本号。每次调用要查三样东西:在不在白名单里、签名还有没有效、版本号对不对得上。哪样对不上就拒绝调用并记安全日志。三道关少一道,白名单就是摆设。

模型搞砸了要有兜底

前面都在说怎么限制 agent 的能力。反过来想一个问题:模型自己就给了一个烂结果,怎么办?

兜底方案必须是用代码写死的规矩,不能让 agent 自己说了算。三种情况要有预案:

  • 格式不对 :模型返回的东西结构有问题,用更严的 schema 重试一次,再不行就用预设模板回复,同时升级处理
  • 拿不准 :置信度分数低,或者另一个审查模型觉得不对劲,直接转人工
  • 不可逆操作 :退款、删除、对外发邮件这类事,永远不能让模型一个人拍板

Bhagwatkar 等人(2026 年 3 月)在 agent 和工具之间设计了两道防火墙:Minimizer 在调用前精简输入,Sanitizer 在拿到结果后清洗输出,都是写死的代码,不走模型 8。思路跟限流一样,限流管调用频率,这两道墙管数据内容。

多少钱以上商品的退款、删记录、给客户发邮件,都该走写死的规则。这套兜底就是底线,模型输出什么不影响底线的可审计性。

攻击面有四个,不是一个

之前两篇 五层纵深防御为什么所有防御都会被攻破 聊过 prompt injection。这里补一句:攻击面(就是攻击者能接触到你系统的入口)不止一个。

Zhang 等人(2025)在 Agent Security Bench 里划了四个入口 10

  1. 直接注入 :用户输入里夹带恶意指令
  2. 间接注入 :恶意指令藏在邮件、网页、RAG 文档或工具返回值里,agent 正常干活时碰上的
  3. 记忆投毒 :往 agent 的记忆里灌恶意内容
  4. 思维链后门 (Plan-of-Thought Backdoor):攻击者在系统提示里预先埋好触发条件,agent 平时看起来正常,但一碰到特定输入就会按预设的攻击路线走

除了攻击之外。LLM调用超时、返回格式不对、模型升级后行为变了、同一数据被并发操作、LLM返回结果模糊导致 agent 死循环,这些问题听起来平平无奇,但上线生产经常可能碰上。

速查表

上面聊了这么多,最后整理一张表,方便对照检查:

检查项 该问的问题 跟普通服务有什么不同
职责边界 不能干什么? 能干什么列白名单,不碰的不留口子
身份 谁在行动、代表谁? 三个身份(用户 agent 工具)各自独立
授权粒度 每个操作的权限? 粒度要到单个操作,不能只到服务级
工具白名单 描述和版本都查了吗? 信任在描述层,每次调用都要验
审计日志 能还原决策过程吗? 别信 agent 自己的说法,独立记日志
限流 限制放在 agent 管不着的地方了吗? agent 只能通过收到 429 才知道超限
兜底 模型搞砸了怎么办? 底线是写死的代码,不是模型
部署回滚 代码、提示、工具目录、模型一起管了吗? 只回滚代码会留下一堆对不上的东西
测试 四个攻击面都测了吗? 间接注入是 2026 年最该防的

小结

Agent 上生产本质上是运维问题,只不过每一层都多了新坑。从身份分离到操作级授权,从工具描述验签到写死的兜底规则,每道锁的思路都一样:把"有权限"和"用权限"中间那一步加回去,用自己写的代码拦在外面,不让 agent 自己管自己。

AI : Agent : 安全 : 生产部署 : 运维 : 授权 : MCP