读:当 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:
- 直接注入 :用户输入里夹带恶意指令
- 间接注入 :恶意指令藏在邮件、网页、RAG 文档或工具返回值里,agent 正常干活时碰上的
- 记忆投毒 :往 agent 的记忆里灌恶意内容
- 思维链后门 (Plan-of-Thought Backdoor):攻击者在系统提示里预先埋好触发条件,agent 平时看起来正常,但一碰到特定输入就会按预设的攻击路线走
除了攻击之外。LLM调用超时、返回格式不对、模型升级后行为变了、同一数据被并发操作、LLM返回结果模糊导致 agent 死循环,这些问题听起来平平无奇,但上线生产经常可能碰上。
速查表
上面聊了这么多,最后整理一张表,方便对照检查:
| 检查项 | 该问的问题 | 跟普通服务有什么不同 |
|---|---|---|
| 职责边界 | 不能干什么? | 能干什么列白名单,不碰的不留口子 |
| 身份 | 谁在行动、代表谁? | 三个身份(用户 agent 工具)各自独立 |
| 授权粒度 | 每个操作的权限? | 粒度要到单个操作,不能只到服务级 |
| 工具白名单 | 描述和版本都查了吗? | 信任在描述层,每次调用都要验 |
| 审计日志 | 能还原决策过程吗? | 别信 agent 自己的说法,独立记日志 |
| 限流 | 限制放在 agent 管不着的地方了吗? | agent 只能通过收到 429 才知道超限 |
| 兜底 | 模型搞砸了怎么办? | 底线是写死的代码,不是模型 |
| 部署回滚 | 代码、提示、工具目录、模型一起管了吗? | 只回滚代码会留下一堆对不上的东西 |
| 测试 | 四个攻击面都测了吗? | 间接注入是 2026 年最该防的 |
小结
Agent 上生产本质上是运维问题,只不过每一层都多了新坑。从身份分离到操作级授权,从工具描述验签到写死的兜底规则,每道锁的思路都一样:把"有权限"和"用权限"中间那一步加回去,用自己写的代码拦在外面,不让 agent 自己管自己。