过去一年,大语言模型从「会写代码的聊天框」变成「会自己动手干的智能体」。它们能调 API、能跑 shell、能查数据库、能写邮件。但凡用过的人都会撞上同一种卡顿:一旦工具清单从十几个涨到几十、上百个,智能体就开始挑错工具、走错顺序、把同一个调用重复两遍。
这件事常被归咎于模型不够聪明,但真正的问题在更底层:当一个智能体面对 N 个工具、需要为当前任务规划一条 K 步的执行路径时,候选路径的总量是 N 的 K 次方。在 K = 5、N = 50 的常见设置里,候选空间已经接近三亿条。任何语言模型——无论上下文多长、推理多慢——都无法在动手之前把这三亿条路径都过一遍。
一、工具调用不是「写代码」,是「选下一步」
很多人把智能体的工具调用理解成「写一段程序」,于是期待模型像编译器一样把伪代码翻译成系统调用。但智能体的真实工作模式更接近「每做一步决策一次」:读完任务、挑一个工具、看返回结果、再挑下一个。这种 ReAct 风格(Reason + Act)天然把规划问题拆成了多次独立的单步选择。
单步选择看似简单,但每一步的错误都会传染。如果第一步挑错了工具,后续所有推理都建立在错误前提之上;如果某一步选了「看起来合理但语义不对」的工具,智能体可能要在错误的方向上再花两到三步才发现不对劲。这就是为什么简单统计「调用成功率」会严重高估真实可用性:衡量智能体表现的关键指标是「整条路径都对」,而不是「每一步都凑合」。
二、组合爆炸:N=50、K=5 的真实代价
把这个问题放到数学上:N 个工具、K 步规划,所有合法路径的数量级在 N 的 K 次方。N = 50、K = 5 这个设置在企业级智能体里非常普遍——一个客服智能体可能要查询订单、改地址、查物流、退款、查优惠券、解绑银行卡、发邮件、调知识库——加起来远不止 50 个工具。
三亿条候选路径并不都需要评估,但模型仍需要某种形式的剪枝:它会基于工具描述的相似度、过去调用过哪些工具、当前任务的关键动词,把候选范围压到几十个。这一步就是最容易出错的地方——剪枝过头会把正确答案切掉,剪枝不够又会让模型陷入「在太多候选之间反复纠结」的延迟。研究里常看到的「工具一多准确率就掉」的现象,主要就出在剪枝这一关。
三、为什么「少即是多」反而更稳
业界逐渐摸索出一个反直觉的工程经验:与其一次性挂上全部工具,不如让智能体自己先规划「这一步到底需要哪几类工具」,再从工具池里挑出 5-10 个相关的喂给模型。
这种「工具分层 + 动态召回」的策略本质上是把组合爆炸从「全局」压到「局部」。第一步不直接挑工具,而是先挑工具类别;第二步才在类别内挑具体工具。两个阶段各自的搜索空间都被砍掉一个量级,剪枝的精度要求也随之下降。代价是多了一层调用延迟,但换来的是准确率从 60% 多跳到 80% 出头——对生产环境来说,这种交换几乎总是划算的。
四、更进一步的解法:从工具描述开始重写
另一条路从工具本身的「说明书」下手。许多工具描述是工程师写给人类看的,里面塞满了参数、返回值、示例,模型读到这种描述时反而容易抓不住重点。把工具描述重写成「一段任务动词 + 一段输入输出格式 + 一段边界条件」的三段式结构,准确率能再涨 5 到 10 个百分点。
这件事值得单独说:模型读工具描述和读 API 文档完全不是同一件事。人类看 API 文档会扫示例、看参数表、查错误码;模型则更依赖动词、对象、修饰词这些语义锚点。把描述写得「对人友好」往往牺牲「对模型友好」,反之亦然。一个成熟的智能体框架,应该允许两种描述并存:一份给工程师、一份给模型,模型只读到它能用的那一版。
五、回到智能体设计的几个常识
把上面这些观察拼到一起,能得到几个朴素的工程常识:工具多不一定好,超过某个阈值之后边际收益会迅速转负;规划阶段比执行阶段更值得花心思优化,因为规划的失败会传染;工具描述是被严重低估的杠杆,重写一份描述的回报常常高于升级一次模型。
智能体这一波浪潮刚走完「能跑起来」的阶段,下一阶段的关键不再是「能不能调工具」,而是「会不会挑工具」。把组合爆炸的代价控制住、把工具描述打磨好、把规划拆得足够细——这三件事做扎实,智能体从「演示能用」走向「生产可靠」才真正有了底气。
