工具越多越聪明?大模型的 Tool Retrieval 难题
给一个 AI Agent 接上搜索、数据库、邮件、日历、代码执行、CRM、支付、内部知识库……看起来很自然:模型能力不够,就继续加 Tool。
问题是,当工具从 10 个变成 50 个,再从 50 个变成 500 个时,事情并不会简单地变成“模型会做更多事”。
你很可能遇到另一种情况:工具明明已经接好了,模型却选错;该调用 A,却调用了 B;或者光是理解有哪些工具可用,就消耗掉大量 Context。
所以,真正的问题不是“模型最多能接多少个 Tool”,而是:当工具数量不断增加时,如何让模型在当前任务中,只看到真正有用的那几个。
几十个 Tool 时,最先出现的不是容量问题,而是选择问题

假设一个 Agent 有 30 个工具。
其中有 search_web、search_docs、search_email、search_crm,还有 get_customer、get_contact、find_user。
对人来说,这些名字已经有一点相似。对模型来说,它不只要看名字,还要理解每个 Tool 的描述、参数和适用边界,然后判断用户这句话应该对应哪一个。
比如用户说:
“帮我找一下上个月和 Acme 沟通过的人。”
这是查 CRM,还是邮件?找 company、contact,还是 conversation?
Tool 越多,这类语义重叠越频繁。
因此,几十个 Tool 时,一个常见问题是:模型不是不会调用工具,而是不知道应该调用哪个。
这也是为什么 Tool 描述非常重要。一个只有“搜索信息”四个字的 Tool,很容易和其他搜索类 Tool 混淆。好的描述应该告诉模型:它查什么、不查什么、什么时候使用,以及返回什么。
工具数量较少时,这些问题通常还能靠命名、描述和 Prompt Engineering 缓解。
但到了几百个,方法就要变了。
几百个 Tool 时,把全部工具塞进 Context 开始变得昂贵

假设你有 500 个 Tool,每个都有名称、用途说明、参数 Schema。
即使模型的 Context Window 足够大,把它们全部放进去也不代表这是好设计。
原因至少有三个。
第一,工具定义本身会占 Context。
模型每次处理“帮我查一下明天下午有没有会”这种简单请求,都要同时面对支付、代码部署、数据库管理、客服系统等数百个完全无关的工具。
这和你去便利店买瓶水,店员先递给你一本几千页的商品目录没有区别。
第二,候选项越多,选择越困难。
假设只有两个 Tool,一个查日历,一个发邮件,模型的选择空间很小。如果同时存在十几个相似的 calendar、schedule、meeting、availability 工具,歧义自然增加。
第三,长 Context 不只是“装得下”的问题。
模型还需要从这些信息里找到当前任务真正相关的部分。Context 能放 100 万 Token,不等于你应该每次都放 100 万 Token。
Context Window 是容量,不是垃圾桶。
所以,当工具进入几十甚至几百规模后,一个更合理的问题应该是:
“这一轮任务需要哪些 Tool?”
而不是:
“我能不能一次把所有 Tool 都给模型?”
Tool Retrieval,就是先替模型缩小选择范围

Tool Retrieval 可以理解成“给工具做搜索”。
用户输入:
“查一下深圳明天下午天气,然后发邮件告诉团队。”
系统不一定立即把全部 500 个 Tool 交给模型,而是先根据任务检索出最相关的一小组:
weather_forecast
然后把这几个工具连同用户请求一起交给主模型。
于是原本是:
用户问题 → 500 个 Tool → 模型选择
变成:
用户问题 → Tool Retrieval → 5~10 个候选 Tool → 模型选择
这和搜索引擎很像。
互联网上有几十亿网页,搜索引擎不会把所有网页一次性塞给你,让你自己找答案。它先检索一批候选结果,再排序,再展示最值得看的部分。
Tool Retrieval 做的是同一件事,只不过被检索的对象从“网页”变成了“工具”。
工具规模越大,这一层越重要。
动态加载 Tool,关键在于把“发现”和“执行”分开

一种比较实用的 Agent 架构,是把 Tool 分成两层。
第一层不是业务工具,而是“找工具的工具”。
比如系统先理解用户任务属于什么领域:邮件、日历、代码、数据库、销售、客服。
然后从 Tool Registry 中寻找相关工具,再把结果动态加入当前 Context。
假设用户说:
“看看明天下午我有没有空,如果有空就给张三发邮件约半小时。”
系统可能经历这样的过程:
任务识别 → 日历 + 联系人 + 邮件
Tool Retrieval → 找到相关工具
加载 Tool Schema → 主模型规划
调用 Calendar → 查询空闲时间
调用 Contacts → 找到张三
调用 Mail → 生成或发送邮件
注意,这里并不要求模型一开始就知道系统里所有能力的完整参数。
它只需要知道:“我可以寻找需要的工具。”
这有点像程序里的动态加载。
你不会为了调用一个图片处理函数,就在程序启动时加载公司所有服务的 SDK。需要什么,再加载什么。
对于 Agent,同样如此。
Tool Rerank 有没有必要?看你的候选工具有多像

Retrieval 并不一定一次就能找到最好的工具。
例如用户问:
“看看客户最近有没有反馈产品问题。”
Retriever 可能找到:
search_crm_notessearch_support_ticketssearch_emailsearch_slackget_customer_profilesearch_product_feedback
这些 Tool 都“有点相关”。
这时可以增加 Tool Rerank:先粗召回一批候选工具,再使用更精细的判断重新排序,最终只把排名靠前的几个交给主模型。
流程就变成:
Retrieve → Rerank → Load → Execute
但 Rerank 并不是永远必要。
如果系统只有 20 个 Tool,而且边界非常清晰,增加一层 Rerank 可能只是增加延迟和复杂度。
如果你有数百个 Tool,并且存在大量名称相似、功能重叠、不同团队重复建设的接口,那么 Rerank 的价值会明显提高。
判断是否需要它,可以观察一个很简单的现象:
Retriever 经常能找到“差不多对”的工具,却不是“最应该用”的工具吗?
如果答案是经常,那么值得加。
真正值得优化的指标,不是 Tool 数量

设计 Agent 时,人很容易展示一个数字:
“我们的 Agent 已经接入 300 个工具。”
这个数字听起来很强,却未必代表系统真的好用。
更应该关注的是:面对一个真实任务,系统能不能快速把数百个工具缩小成几个正确候选,并且让模型稳定地选中正确的那个。
所以,一个比较健康的演进路径通常是:
工具少时,先把 Tool 名称、描述和边界设计清楚。
工具增加后,引入分类、命名空间或者 Tool Registry。
达到几十到几百规模后,开始使用 Tool Retrieval,避免把所有 Schema 永久塞进 Context。
当候选工具高度相似、Retriever 排名不稳定时,再加入 Rerank。
这时系统的重点已经从“让模型认识所有工具”,变成了“让模型在正确的时间认识正确的工具”。
这两个目标,看起来只差几个字,架构却完全不同。
一个真正可扩展的 Agent,不应该像一个员工被要求背完整家公司的所有 SOP、系统菜单和 API 文档。
更合理的状态是:它知道自己现在要完成什么任务,也知道去哪里找到完成这件事所需要的能力。
当 Tool 从几十个增长到几百、几千个时,模型能力当然重要,但决定系统能否继续扩展的,往往是模型之前那一层:检索、筛选和动态加载。
工具越多,越不应该全部交给模型。
Agent 架构真正成熟的标志,也许不是“我们有多少 Tool”,而是用户提出一句话之后,系统能不能只拿出那几个此刻真正有用的 Tool。
更多推荐


所有评论(0)