工具选择难题:当智能体拥有数十个工具时,如何选择调用哪一个
大多数 Agent 演示仅使用 5 个工具,而生产系统通常拥有 50 个。这两个数字之间的差距,正是大多数 Agent 架构分崩离析的地方。
当你给一个 LLM 4 个工具和一个明确的任务时,它通常能选对。但当你给它 50 个工具时,更有趣的事情发生了:准确率大幅下降,Token 成本激增,且失败模式通常表现为模型幻觉出一个工具调用,而不是承认它不知道该用哪一个。来自 Berkeley Function Calling Leaderboard 的研究发现,在跨多个领域的日历调度任务中,当工具数量从 4 个扩展到 51 个时,准确率从 43% 骤降至仅 2%。这绝不是一个平滑的性能退化曲线。
工具选择问题处于检索、上下文管理和模型推理的交汇点 —— 而构建真实 Agent 系统的实践者通常是在产品上线后,才通过这种痛苦的方式意识到这一点。
为什么将所有工具都塞进上下文会失败
这种天真的方法也是最显而易见的方法:在系统提示词(System Prompt)中定义所有工具,让模型自己去理解。这在工具数量达到 10-15 个之前是有效的,具体取决于模型和每个工具描述的精确度。超过这个数量,两个问题会同时爆发。
Token 爆炸。 Anthropic 的内部测试发现,58 个工具定义大约会消耗 55,000 个 Token。按照生产环境的推理成本计算,这意味着 Agent 的每一次轮转都会带有等同于总结一部短篇小说的基础开销 —— 甚至在用户的查询进入之前就是如此。对于高吞吐量系统来说,这是一个隐藏的预算项目,它使单位经济效益变得难以维系。
选择准确率下降。 更多的工具不仅仅增加了 Token 消耗 —— 它们还会降低模型的选择能力。这种失败模式非常隐蔽:模型很少会说“我不知道该用哪个工具”。相反,它会选择一个听起来合理但错误的工具,或者错误地组合多个工具,或者尝试使用符合另一个工具架构(Schema)的参数来调用某个工具。这些错误很难被检测到,因为响应格式通常仍然是有效的 —— 只是在语义上是错误的。
还有第三种常被忽视的失败原因:文档质量差异。在一组 50 个工具中,有些工具会有精确、范围明确的描述,而另一些则会有由不同团队在不同时期编写的模糊、重叠的描述。一个名为 send_notification 的工具和另一个名为 push_alert 且描述相似的工具,肯定会让模型感到困惑,特别是当正确的选择取决于描述文本中并未明确说明的微妙行为差异时。
静态检索:聊胜于无,但还远远不够
大多数团队采取的第一种修复方案是基于 RAG 的工具选择:对所有工具描述进行向量化(Embedding),对用户查询进行向量化,找到前 k 个最相似的工具,并只将这些工具传递给模型。这比静态包含要好得多 —— 它减少了 Token 使用并缩小了选择空间。
但纯向量嵌入检索也有其自身的失败模式,实践者很快就会学到这一点。
查询与描述之间的词汇不匹配。 一个请求“重新安排会议”的用户,其查询与描述为 calendar_event_update 的工具之间可能没有很高的余弦相似度,特别是如果嵌入模型没有针对 API 文档进行过训练的话。用户的语言和工具的文档语言通常处于嵌入空间的不同部分。
动态工作流中的静态检索。 多步任务中第 2 步所需的正确工具通常取决于第 1 步的输出。如果你仅根据原始用户查询来检索工具,你将系统性地遗漏那些在执行过程中变得相关的工具。条件检索(Conditioned retrieval)—— 即工具选择同时结合了原始意图和不断演变的执行上下文 —— 在多步基准测试中的表现始终优于仅基于查询的检索。
Top-k 截断消除了次优选择。 当两个工具的相关性几乎相同时,嵌入相似度排名可能会将正确的工具放在第 k+1 个位置,恰好在窗口之外。模型永远看不到正确的选项,并从它能看到的选项中做出错误的抉择。
语义覆盖攻击(这主要是一个可靠性问题,而不仅仅是安全问题)。 如果几个工具具有重叠 的、通用的描述,它们将占用所有的 Top-k 插槽,而不管其实际相关性如何。即使在正常的设置下,缺乏区分度的工具描述也会不断导致这个问题 —— 检索到的前 5 个结果最终只是同一大类能力的五个变体,而不是一组多样化、互补的工具。
真正有效的方法:分层路由
能够可靠处理大量工具库存的生产系统,往往使用分层路由(Layered Routing)而不是单一的检索过程。其结构大致如下:
层级 1:意图分类。 通过一个轻量级分类器(或一个小型的 LLM 调用)将传入的请求映射到某个领域或工具类别。这不需要语义搜索 —— 这是一个结构化的分发步骤。类别可以是粗颗粒度的:calendar_operations、document_management、data_queries、user_management。其目标是在进行任何相似度计算之前,剔除 80% 的工具库存。
层级 2:类别内的混合检索。 在相关类别中,同时使用稠密(向量嵌入)和稀疏(BM25/关键词)检索,然后合并排名列表。混合检索在工具选择方面的表现始终优于纯语义搜索,因为 API 文档包含精确的术语 —— 方法名称、参数名称、特定领域的专业术语 —— 关键词匹配处理这些术语的效果比嵌入向量更好。
层级 3:基于上下文的重排序。 对于多步工作流,根据当前的执行状态(而不仅仅是原始查询)对候选工具进行重排序。一个能够看到已经调用了哪些工具及其输出结果的重排序器,其筛选出的选项系统性地优于仅根据初始请求工作的重排序器。
结果是:模型每次调用看到的只是 5-8 个工具,而不是 50 个,且所有工具都与当前步骤相关。选择准确率攀升,Token 成本下降。失败分析变得可行,因为你可以记录并审计检索了哪些工具以及原因。
多智能体系统中的工具到智能体检索 (Tool-to-Agent Retrieval)
当工具库分散在多个专门的智能体中时——例如一个智能体负责日历,一个负责文档,一个负责 CRM——路由就变成了一个两级问题:应该调用哪个智能体,以及该智能体中的哪个工具。
一种诱人的捷径是仅进行智能体级别的路由:分类意图,路由到正确的智能体,让智能体内部处理工具选择。这会在两个方面出现问题。首先,它将细粒度的工具功能隐藏在粗粒度的智能体描述之后,迫使路由决策在缺乏必要信息的情况下做出。其次,某些任务确实跨越多个智能体,需要协调的工具束——纯粹的智能体优先方法无法推理这些跨智能体的依赖关系。
将工具和智能体都嵌入到共享的向量空间中,并通过元数据关系进行关联,能更好地处理这个问题。检索可以根据查询相似性模式,针对精确任务匹配单个工具功能,或者针对协调的多步骤工作流匹配智能体束。在拥有 70+ 个 MCP 服务器和 527+ 个工具的基准测试中,这种方法在检索质量指标上比仅智能体或仅工具的路由提升了约 17-18%。
执行上下文问题
有一种失效模式是仅靠检索改进无法解决的:模型选择了正确的工具,但由于缺乏对世界模型的认知而调用错误。
在有状态系统中,工具调用具有副作用,会改变后续调用应执行的操作。一个删除记录的智能体并不理解这会改变下一次 SELECT 的结果。一个发送电子邮件的智能体不会建模重试发送会导致邮件重复。工具选择层可以找到正确的工具,但执行的正确性取决于模型对其行为所产生的状态后果的理解。
实际的缓解措施是执行前规划:让智能体在执行任何步骤之前勾勒出完整的调用序列,识别依赖关系和不可逆性约束。在行动前进行规划的模型比逐个选择并执行工具的模型产生不可逆错误的概率显著降低。NESTFUL 基准测试发现,即使是 GPT-4o 在处理依赖 API 调用的完整序列时,准确率也仅为 28%——这有力地提醒我们,工具选择只是问题的一部分。
编写用于检索的工具描述
工具本身就是一种检索产物,而不仅仅是 API 文档。为人类读者编写的描述往往无法作为理想的检索目标。
对智能体系统有用的工具描述包括:
- 典型用例:何时调用此工具的具体示例,而不只是它做什么
- 反面示例:明确说明何时应改用相关工具
- 前置条件和后置条件:调用此工具前必须满足什么条件,调用后会有什么变化
- 失败模式:当输入超出范围、底层服务不可用或操作部分成功时,工具会返回什么
将这些字段添加到工具元数据中,并与主要描述一起建立索引,可以显著提高检索质量。关于工具检索文档扩展的研究发现,添加如 when_to_use、tags 和 limitations 等结构化字段所带来的检索指标提升最大——甚至超过了改进基础描述本身。
路由架构决策
何时添加路由层,何时简化工具库,这是一个取决于你实际数据的判断。一个合理的启发式方法是:
- 少于 15 个工具:静态包含,转而投资于描述质量
- 15-40 个工具:带混合评分的单次语义检索
- 40 个以上工具:分层路由,包含意图分类、混合检索和上下文感知的重排序 (context-conditioned re-ranking)
- 跨多个智能体的 200 个以上工具:共享嵌入空间中的工具到智能体检索
从业者常犯的错误是在穷尽描述质量改进之前就追求路由的复杂性。一组区分度高、描述精准的 30 个工具,其表现将优于构建在 30 个描述糟糕的工具之上的检索系统。检索无法解决混乱——它只是缩小了模型看到的混乱选项的范围。
衡量是否奏效
智能体 工具选择是最难评估的组件之一,因为失败往往是无声的。模型调用了一个工具,工具返回了结果,智能体继续运行。是否调用了正确的工具,只有在工具调用级别进行日志记录和审计时才可见,而不仅仅是看最终响应。
值得跟踪的有用信号:
- 每个意图类别的工具选择准确率:随着工具库的增长,哪些类别的准确率出现了下降?
- 检索召回率@k (Recall@k):对于给定的查询,正确的工具出现在前 k 个检索结果中的频率是多少?
- 工具调用重试率:你模型调用工具、获得意外结果、然后调用另一个工具的情况有多频繁?高重试率表明上游选择存在错误。
- 每轮平均工具数:随时间增加则表明检索未能有效地缩小选择空间。
构建专门覆盖检索层的评估 (evals),而不只是端到端的任务完成度。当任务完成度评估出现退化时,检索问题通常已经存在很久了——你只是之前看不见它。
工具选择问题本质上是一个伪装成模型问题的检索问题。将此视为“模型不够聪明”的工程师会寻求更大、更昂贵的模型。而将此视为“检索层没有给模型提供正确信息”的工程师,则能构建出在拥有 500 个工具时仍能保持与 5 个工具时相同准确率的系统。
- https://dev.to/terzioglub/why-llm-agents-break-when-you-give-them-tools-and-what-to-do-about-it-f5
- https://arxiv.org/html/2511.01854v1
- https://www.useparagon.com/learn/rag-best-practices-optimizing-tool-calling/
- https://rewire.it/blog/dynamic-tool-allocation-for-ai-agents-the-rats-pattern/index.html
- https://gorilla.cs.berkeley.edu/leaderboard.html
- https://next.redhat.com/2025/11/26/tool-rag-the-next-breakthrough-in-scalable-ai-agents/
- https://openinnovation.ai/how-to-build-ai-agents-with-dynamic-tool-routing/
