大家好,我是吴师兄。
在真实 Agent 开发里,调用工具不稳、选错函数、参数瞎填,是最常见、也最折磨工程师的问题。
但很多同学不知道,一个最根本的原因其实不是模型不行,而是 工具给太多,给太早,给得太乱。
我们把这类 badcase 积累多了之后,就会发现一条铁律:
只要不给 Agent 做动态函数路由(Dynamic Function Routing),Function Call 稳定性永远上不去。
今天这篇文章就来拆透:
-
为什么动态路由是必要条件
-
什么时候必须用
-
真实案例如何把错误率从 20% 拉到 1%
-
面试官听你讲这个,会直接对你另眼相看
为什么工具越多,模型越容易“选错工具”?
很多团队在构建 Agent 时会犯一个常见误区: 把所有工具一股脑塞给模型。
比如你的系统能查机票、订酒店、查天气、查用户信息,只要用户一问话,LLM 就直接看到六七个工具的 JSON Schema。
模型会怎么做? 它会在“不确定的意图”下拟合出一个“看似合理”的工具。
结果就是:
用户问: “明天北京天气怎么样?”
模型却调用:
search_flights(origin="北京", destination="明天")
这种荒诞的 badcase 在训练营实践里出现过太多了。
原因很简单:
当候选工具越多,模型的决策空间越大,错误概率呈指数级增长。
动态函数路由的核心目标:减少歧义、减少搜索空间
动态函数路由的本质是:
提前一步判断用户的意图,让模型只看到它“可能”需要的那一小部分工具。
举例:
用户问天气,工具列表缩小为 [get_weather]
用户问酒店,工具列表缩小为 [search_hotels, book_hotel]
用户问航班,工具列表只给 [search_flights, book_flight]
当工具列表从 6 个缩小到 1~2 个之后,模型的错误率会暴跌。
为什么有效?
因为 LLM 的行为规律很简单:
-
工具越少,越容易选择正确
-
Schema 越短,注意力越集中
-
Token 压力越小,截断风险越低
-
上下文越干净,歧义越少
这就是“给模型做减法”的威力。
真实项目案例:错误率从 22% → 1.3%
这是训练营里旅行助手 Agent 的一个真实数据。
初始版本(无动态路由):
-
工具数量:6 个
-
请求数量:500 条测试集
-
Function Call 错误率:22%
错误集中在:
-
用户查天气 → 模型调用查机票
-
用户查机票 → 模型用酒店工具
-
参数缺失、错误字段、字符串乱填
之后我们加了动态路由:
-
用轻量意图分类(关键词 + 小模型分类器)
-
对每个场景给固定工具子集
优化后:
-
工具数量:动态选择,常见只给 1~2 个
-
错误率:1.3%
几乎所有错误都来自 API 本身的边界情况,而不是意图误判。
这就是为什么我在 Agent 系列文章里面一直强调:
动态路由不是“增强策略”,而是 Function Call 能否落地的基础设施。
动态函数路由是怎么做的?不是一句“if else”那么简单
我们总结了三种常见策略:
策略 1:轻量规则(最常用、最快上线)
适用于简单场景:
-
关键词匹配
-
简单的正则
-
模板识别
例子:
如果包含“天气”,就给 get_weather 如果包含“订机票”,就给 book_flight 如果包含“查酒店”,就给 search_hotels
优点: 简单、快速、足够稳定
缺点: 无法覆盖长尾复杂意图
策略 2:意图分类器(小模型 + 文本分类)
适用于中大型项目:
-
一个 10 类意图分类模型即可
-
精度可以从 80% → 92%
-
强化学习可以继续提升
这一步成本低,却效果显著,是训练营 Agent 项目里常规操作。
策略 3:LLM 先解释意图,再执行工具
让 LLM 自己输出:
用户意图:查询天气 应使用工具:get_weather
再进入下一次 Function Call 对话。
效果非常稳定,尤其适合复杂多轮场景。
但是有一点必须注意: 让 LLM 做意图理解时,不能同时暴露所有工具,否则它又会乱选。
所以我们一般是两阶段结构:
1)先用小模型或规则缩小候选集合
2)再让 LLM 在小集合里决策
工程味更强,也更通用。
面试官最爱问的一句话:什么时候一定要用动态路由?
标准答案很明确: 当工具数量超过 3 个、场景包含自然语言意图时,动态路由是必选项,而不是可选项。
理由是:
-
自然语言本身有歧义
-
模型无法自动识别哪些工具不相关
-
工具越多,错误概率呈指数级上升
-
截断风险会让模型忽略关键字段
-
Schema 越长,模型越难理解参数含义
如果你只说:
“动态路由可以提升准确度。”
这是泛泛之谈。
但如果你能讲出:
“动态路由可以减少工具选择空间,从概率上降低错误率,是 Function Calling 稳定的底层逻辑。”
那就是做过实战的人才讲得出来。
总结:Function Call 的稳定性,本质上是“让模型少犯错”
核心逻辑只有一句话:
模型越自由,错误越多;模型越被“框住”,效果越稳。
动态函数路由就是在给模型“收自由度”。
-
工具少 → 决策简单
-
Schema 短 → 注意力集中
-
Token 压力小 → 截断更少
-
意图确定 → 乱选概率低
当这套体系成熟了,一个 Agent 才算具备真正落地的基础。
没有动态路由,就没有稳定的 Function Call。
