返回文章列表

Agent 能调更多工具,不代表系统就更可控

工具越多,动作越强,真正决定系统是否可控的反而越不是“能力”,而是状态收敛、权限边界和失败回退

很多人评估 Agent 系统,第一眼看的是“它能接多少工具”。

能查数据库、能发消息、能改工单、能下发脚本、能操作浏览器,看上去当然比只能聊天的模型更像一个真正能干活的系统。于是团队很容易顺着这个方向往下走:工具再多接几个,权限再放一点,链路再自动一点,系统就会更强。

问题是,强不等于可控

我的判断是:Agent 系统的可控性,不取决于工具数量,而取决于状态收敛、权限边界和失败回退。工具调用越来越多、上下文越来越长、动作副作用越来越重时,如果没有明确的约束和收敛机制,系统通常只会更难预测。

工具多,解决的是可操作范围;可控,解决的是结果能不能收住

“能调工具”解决的是 Agent 不再只会给建议,而是能直接作用到真实系统。

这是能力扩张,不是假问题。

但系统一旦从“回答问题”升级成“执行动作”,工程上的关注点就变了。你不再只需要判断输出内容像不像人话,而要判断:

  • 它这次到底做了什么;
  • 为什么做这一步,而不是另一种更安全的动作;
  • 做错以后影响范围多大;
  • 中间失败时系统会停住、重试,还是留下半套副作用;
  • 下次再来一个类似请求,它会不会走出完全不同的路径。

也就是说,工具数量增加以后,复杂度不是线性增长,而是从“文本正确性问题”切到了“系统行为可预测性问题”。

这两类问题不是一个量级。

一个只能回答问题的模型,说错了通常是认知噪声;一个能调十几种工具的 Agent,一旦没有约束,说错就是动作噪声,做错就是系统噪声。

真正先失控的,往往不是模型,而是状态

很多团队把 Agent 做乱,第一反应是模型不稳定。其实不少问题在模型之外。

比如一个常见流程:

  • Agent 先查工单系统,拿到待处理任务;
  • 再搜知识库,找历史处置方法;
  • 然后调用数据库查询;
  • 再发消息给值班群;
  • 最后补一条处置记录。

这条链路每一步都“合理”,但只要你没有定义清楚中间状态,系统就会很快出现这些问题:

  • 工单状态已经改成处理中,但通知没发出去;
  • 数据库查询已执行,结果却没被落到最终记录;
  • 消息已经发到群里,后续步骤失败,外部却以为事情已经处理完;
  • 上下文窗口被截断后,第二轮继续执行时不确定前面哪些动作做过。

这些都不是“模型推理差了一点”,而是系统缺少状态收敛机制

一个能执行动作的 Agent,如果没有明确的任务状态机,本质上就只是把多步副作用串在自然语言推断上。

这在 demo 里很好看,在生产里很难收场。

权限边界不清,Agent 很容易从“能做事”变成“做太多事”

另一个常见误区,是把工具接入当成能力库存。

接上浏览器,就顺便给它任何后台都能点; 接上 Shell,就默认能跑大部分命令; 接上消息系统,就默认能主动通知任何群; 接上数据库,就给读写混合权限。

表面上这让 Agent 更通用,实际上是在把系统可控性押注给单次推理不要出错。

这很危险,因为 Agent 的风险不是“它会不会恶意”,而是它会不会在一个局部合理、全局错误的上下文里调用到高副作用工具

比如:

  • 本来只该查状态,却顺手执行了修复脚本;
  • 本来只该回复当前用户,却把通知发到了群里;
  • 本来只该读数据,却调用了更新接口;
  • 本来只该在人审后继续,却把“建议动作”直接变成了“已执行动作”。

所以权限边界设计的重点,不是防一切,而是把高副作用动作和高不确定性推理隔开。

如果一个动作错一次就会造成真实损失,它就不该和普通查询动作放在同一层自动化里。

工具编排一多,失败不再只是“报错”,而是半完成状态

普通软件系统当然也有失败,但 Agent 系统的失败有个额外麻烦:它经常是跨工具、跨系统、跨语义边界的半完成失败

例如:

  1. 先在 Jira 里创建了处理任务;
  2. 再去 Slack 发通知;
  3. 再调内部 API 拉日志;
  4. 最后把总结写回知识库。

如果第三步失败,系统应该怎么办?

  • 回滚 Jira 任务?
  • 删除刚刚发出的通知?
  • 保留任务但标记处理中断?
  • 让另一个 Agent 接管?

这里最忌讳的做法,是把“失败处理”理解成重新 ask model 一次。

因为很多失败已经不是推理层问题,而是副作用层问题。你真正需要的是:

  • 哪些步骤可重试;
  • 哪些步骤必须幂等;
  • 哪些步骤只能人工确认后继续;
  • 哪些外部动作必须留下审计轨迹;
  • 一条链路中断后,下一次恢复到底从哪里接上。

如果这些都没有定义,Agent 看起来是在自动化,实际上是在制造人工善后工作。

可控性的核心,不是“会不会思考”,而是“会不会收敛”

我越来越倾向于把 Agent 系统当成一种带推理能力的工作流系统,而不是一个会聊天的全能入口。

这意味着你设计它时,最该先回答的不是“还能接什么工具”,而是:

  • 任务是否有明确开始、处理中、待确认、完成、失败这些状态;
  • 每个状态允许调用哪些工具;
  • 哪些结果可以直接提交,哪些必须人审;
  • 上下文丢失后,系统能不能从外部状态恢复,而不是靠模型回忆;
  • 每一次动作,是否都有可追责的输入、输出和执行记录。

这些东西听起来不性感,但它们决定了 Agent 是一个能逐步放量的系统,还是一个只能在低风险角落里演示的玩具。

一个很朴素的判断标准是:如果你把模型临时换弱一档,系统只是效率下降;如果你把状态机、权限边界和回退机制拿掉,系统立刻不可上线。

这说明真正托底的不是模型智商,而是系统收敛能力。

一个常见反例:把 Agent 当成万能协调员

很多内部平台最后都会长成一种很像“AI 中台”的东西:

  • 什么系统都接一点;
  • 什么请求都想收;
  • 什么动作都尽量自动完成;
  • 以为只要提示词再补细一点,就能把风险压住。

这套路线最大的问题,不是做不到,而是边际复杂度非常差。

因为请求类型越多,工具语义越杂,成功路径和失败路径的组合数就越大。你原来只需要管“查一下发布记录”,后来变成:

  • 查记录;
  • 判断异常;
  • 决定是否回滚;
  • 发通知;
  • 改状态;
  • 生成复盘;
  • 更新知识库。

看上去是一条完整自动化闭环,实际上每多一步,系统就多一层副作用一致性和权限解释成本。

到最后,真正吃掉团队时间的,常常不是模型调用费,而是:

  • 为什么这一步会自己执行;
  • 为什么同样的问题今天和昨天走了不同路径;
  • 为什么外部系统已经改了,但内部记录没跟上;
  • 为什么事故后很难还原 Agent 当时到底依据了什么。

这不是“Agent 不够聪明”,而是你把太多高不确定性的动作,交给了缺少边界的推理过程。

更稳的做法,是把自动化分层,而不是把工具堆平

如果你真想让 Agent 系统可控,我更建议按风险和副作用去分层:

1. 低风险层:查询与总结

先让 Agent 做读取、检索、归纳、草拟。

这类动作即便判断不完美,通常也不会直接改变外部状态,更适合先放量。

2. 中风险层:带约束的单步动作

比如只能在特定工单状态下改一个字段,只能向当前会话回复,只能执行明确 allowlist 里的操作。

这里的关键不是“让它自由发挥”,而是把动作空间压缩到足够窄,让错误成本可接受。

3. 高风险层:显式审批与可回退执行

凡是涉及删改数据、批量操作、跨系统写入、外发通知、生产环境脚本执行,都应该把人审、审计和回退机制放在前面,而不是留给事后补救。

真正成熟的 Agent,不是看起来什么都能做,而是知道什么该自动做,什么只能建议做,什么绝不能直接做。

适用边界

这篇文章讨论的主要是:

  • 接了多个工具的企业内部 Agent;
  • 有真实外部副作用的流程型 Agent;
  • 涉及消息、工单、数据库、脚本、浏览器等跨系统操作的编排场景。

如果你的 Agent 还停留在“帮用户总结网页”“帮客服草拟回复”这种低副作用任务上,那工具多一些未必立刻失控,因为大多数错误都还停留在文本层。

真正的问题会在系统开始直接改外部状态时出现。那时你面对的已经不是 prompt engineering,而是分布式系统式的约束设计。

结尾

Agent 能调更多工具,确实会让系统更有用。

但“更有用”和“更可控”不是同一个方向上的词。

当动作、副作用和上下文复杂度一起上涨时,真正决定系统上限的,往往不是工具接了多少,而是状态能不能收敛、权限边界是否清楚、失败之后能不能稳稳停住并恢复

否则工具接得越多,系统只是越像一个能力很强、但很难预测的执行体。