很多人第一次听说"工具调用"(tool calling / function calling),会以为这事很简单:不就是让 AI 输出一段格式正确的指令,去调个接口吗?
但真正做过线上 Agent 的人都知道,工具调用出问题,几乎从来不是因为"AI 选错了工具"。它更常见的死法是:参数里藏了个恶意路径、工具返回的错误信息被人做了手脚、工具一多 AI 就开始犯迷糊、还有协议本身给大规模部署埋了坑。
所以这里想说的是:工具调用的难点,不在于"AI 会不会调",而在于你在 AI 和外部世界之间,立了几道拦得住东西的墙。
第一道坎:安全------别指望 AI"识破坏人",要让坏人"干不了坏事"
关于工具调用的安全,大家第一反应是"检测提示词注入",也就是识别出恶意指令然后拒绝。但最近的研究给这个思路泼了冷水。
有个团队测了 3250 个攻击场景、七个模型,结论是:用 Function Calling 架构时,攻击成功率高达 73.5%;MCP 架构也有 62.6%。更扎心的是,多步连环攻击的成功率到了 91%--96% ,而且模型越聪明,反而越容易被利用------因为检测能力变强,没转化成安全性变强。
这说明一个很朴素的事实:只要安全还依赖 AI 在脑子里"想一想这是不是恶意",那它就有被绕过的空间。 越会推理的模型,也越会给自己找理由。
还有一个特别容易被忽略的漏洞:工具报错信息。工具返回的错误提示在 AI 眼里有一种"权威感",会触发它进入"我要赶紧纠错"的模式,顺便就把平时的安全警觉绕过去了。在四个前沿模型上,往错误信息里塞注入内容,成功率能翻三倍,某些条件下甚至 100% 中招。为什么危险?因为错误信息本来就是"系统说的话",AI 被训练成要信任它,而攻击者恰好能劫持这条信任通道。
那怎么办?有个项目叫 ToolClad,思路很值得借鉴:别去检测"危险参数",而是让危险参数根本没法写出来。 它给每个工具的参数定死"形状"------比如某个参数只能是某个目录下的路径、某个参数只能是特定主机名------在真正调用之前先验一遍,写不成这个形状的一律拒绝。 它的关键点在于:这一层跟别的安全手段不重复 。策略引擎管"这个动作允不允许",消毒器不管参数内容,而 ToolClad 正好卡住了那个最要命的漏洞------动作是允许的,但参数被恶意改造了。
说白了:工具调用的安全,不该外包给 AI 的判断力,而应该写进调用的结构里。参数合约、类型限制、别把参数拼成字符串去执行------这些看着像"老掉牙的软件工程",在 Agent 场景里恰恰是 AI 绕不过去的第一堵墙。
第二道坎:协议------MCP 火是火,但一上规模就烧钱
MCP 在如今几乎成了工具调用的"通用插头",但它一上企业规模,就暴露了两个大成本。
第一个是服务器越堆越多。每接一个 API 就包一个独立服务器,各有各的部署、依赖和密码管理。有人分析了 116 个官方 MCP 服务器,发现 88.6% 背后就是普通的 REST API,92% 的工具就是 API 的裸包装,而一个服务器平均只暴露了底层 API 的 19% 功能。
第二个更根本:每个工具的名字、说明、参数格式,每次对话都得塞进 AI 的上下文里。 工具越多,占的地方越多,而且是线性增长。GitHub 的 API 有 900 多个接口,就算只取 200 个,在任何用户开口之前就已经吃掉几万 token 了。
结果就是"选择坍缩":现实部署只能挑一小撮组织真用得上的 API 暴露出去,或者把工具集拆得七零八落,哪种都别扭。MCP 解决的是"AI 怎么调工具"的接口统一问题,但在"AI 怎么知道有哪些工具"这件事上,用的还是最原始的"全广播"。
这里推荐有个叫 DADL 的方案是对着这个缺陷来的:不把每个工具的说明全推给 AI,只暴露两个固定大小的操作------search(找工具)和 execute(执行)。工具广告的 token 成本从约 14.2 万降到约 1000,压缩了 142 倍。
数字本身不是重点,重点是协议设计的重心变了:工具调用能不能规模化,不取决于接口多"标准",而取决于"找工具"这件事有没有被当成一个独立的检索问题来处理,而不是一股脑往上下文窗口里塞。
第三道坎:认知------工具一多,AI 就开始"眼花"
先不谈安全和协议,就算纯从"AI 能不能想清楚"这个角度说,工具调用也有个被低估的坎:工具越多,AI 选得越不准。
生产环境的数据显示,工具数量超过 15 个左右,准确率就明显往下掉;有个受控测试里,工具从 10 个涨到 40 个,选择准确率从 81.7% 掉到 62.5%。这不是"稍微难一点",是两个机制在起作用。
第一个是注意力被稀释,好东西卡在中间没人看。AI 对上下文开头和结尾记得牢,中间容易丢。几十个长得很像的工具说明堆在一起,真正合适的那个往往恰好在中间的死角------它不是推理不出来,而是注意力被结构性地拉走了。
第二个是工具幻觉:AI 会编出不存在的工具名,或者调对了工具、参数却从另一个工具那儿借来------后者更阴,因为调用"看起来发生了",但参数是错位的,属于硬失败。
这些发现指向一个反直觉的结论:工具调用靠不靠谱,主要不在工具本身,而在 AI 做选择之前看到了什么。 先用一个便宜的分类器判断"这轮到底要不要用工具"(门控),再把工具说明做成向量库、只召回跟当前意图相关的那几个(检索式选择),然后在候选集上分层决策------这套组合拳本质上是主动管理 AI 的注意力预算,而不是被动指望它聪明。
工具调用的质量,很大程度是信息架构的质量。
第四道坎:失败恢复------最贵的坑,是"调用成功了,活儿没干成"
工具调用领域有个系统性偏差:大家几乎都在看"调用成没成功",但线上最烧钱的失败是调用成功了,整个流程却失败了。
一个工具可能返回合法的 JSON、正确的状态码,但返回的内容跟 Agent 当前所处的流程阶段对不上;一条工具链可能每一步都"调对了",却在依赖关系上越积越偏,直到下游某一步才发现上游早就歪了,救不回来了。
工具之间有结构上的依赖,也有行为上的依赖,硬走单条路线,一出错就没法恢复,搜索空间还指数级爆炸。所以应该把 LLM 的工具调用拆成两层------上层四选一做决策,下层在工具依赖图上做路径搜索,用一个显式的"图导航器"去建模工具之间的关系。这样 API 挂了或者语义漂移了,能实时重组工具链,而不是从头重来。
这个架构选择的洞察就一句话:工具调用的恢复能力,不该指望从 AI 的推理里"自己长出来",而该被设计进编排层的拓扑结构里。 回溯、备选路径、依赖图的动态重路由,这些是编排器的活儿,不是提示词的活儿。
相应地,评估也得跟着升级。一套完整的工具调用评估,至少要分清楚五件事:这轮该不该用工具(门控对不对)、工具选对没(选择准不准)、参数跟现实世界对得上吗(参数精确性)、调用链在依赖上走得通吗(编排有效性)、某一步挂了能不能绕到等价路径(恢复能力)。多数团队只在前两项上建了基准,后三项基本靠蒙------而这恰恰是线上事故的主要来源。
最后
模型会越来越强,推理会越来越好,但上面每一道墙要解决的问题,都不会因为模型变强而自动消失。它们只会从"AI 做不到"的明面失败,变成"AI 做得到、但你不希望它那样做"的暗面风险。工具调用真正成熟的标志,不是 Agent 能调一万个工具,而是它调每一个工具时,你都清楚边界画在哪,以及边界被越过时,有什么结构会接住它。