一次 Function Calling 的测试思考,为什么“火星天气”会调用工具,而“阿瓦达啃大瓜”不会?
在测试 Function Calling 的过程中,我遇到一个挺有意思的现象。
同样是非真实城市的输入,模型的行为却完全不同:
-
问 “火星天气怎么样?”,模型有时会尝试调用工具
-
问 “阿瓦达啃大瓜天气怎么样?”,模型却会直接拒绝调用
这让我开始思考一个问题:
模型到底是如何判断「这次工具调用值不值得执行」的?
Case A:火星天气怎么样?
这是一个非常典型的边界输入。
在一次测试中,模型响应中的 reasoning 是这样的:
用户询问火星的天气情况。我需要使用 get_weather 函数来获取天气信息。
这个函数需要一个 city 参数,用户提到了“火星”,我应该用“火星”作为城市名称来调用函数。
于是,模型直接构造了参数:
{"city": "火星"}
并触发了 tool_call。
但有意思的是,在另一次测试中,模型却给出了完全不同的判断:
工具的描述中提到的是“城市名词,例如:深圳、上海等”,
这表明该工具是用于获取地球上的城市天气,而不是火星的天气。
于是,这一次它没有调用工具,而是选择了拒绝执行。
这说明什么?
对“火星天气”这种输入,模型的行为是不稳定的:
-
有时会觉得:虽然不标准,但可以“先试试”
-
有时会觉得:语义不匹配,不值得调用
从测试视角看,这其实非常重要。
这类 case 本身就是语义边界问题,
不应该指望模型给出 100% 确定的行为。
如果这是一个真实系统,通常会有两种处理方式:
-
自动化多次跑,用统计结果判断调用倾向
-
或者通过修改 tools 的描述 / system prompt,明确约束:
如果不是清晰的城市名词,就不要触发 tool_call
至于选哪一种,其实取决于具体公司的业务取舍。
Case B:阿瓦达啃大瓜天气怎么样?
相比之下,这个 case 的行为就非常稳定。
模型的 reasoning 很明确:
“阿瓦达啃大瓜”不是一个真实的城市名称,看起来更像是一个玩笑或者测试性问题。
根据工具定义,get_weather 需要一个城市名词,因此不应该调用该函数。
于是:
-
没有触发 tool_call
-
而是直接告诉用户:这不是有效的城市,并引导用户重新输入
这一点,反而让我对模型更放心了一点。

至少在明显不可执行的情况下,它不会“硬凑参数”去调用工具。
一个容易被忽略的点:这两次其实都调用了模型
这里顺便澄清一个容易混淆的地方。
无论是:
-
没有触发 tool_call 的“阿瓦达啃大瓜”
-
还是没有触发 tool_call 的那一次“火星天气”
模型本身都已经被调用过了,也都消耗了 token。
区别是:
-
模型是否返回了
tool_calls -
系统是否进入“执行工具”这一步
也就是说:
Function Calling 决定的是“系统下一步做什么”,
而不是“这一轮模型有没有被调用”。
总结:我从这两个 case 得到的认知
把“火星”和“阿瓦达啃大瓜”这两个 case 放在一起,我得到一个很明确的结论:
在 Function Calling 之前,模型会先做一次「语义可执行性判断」,
而不是看到参数长得像就直接调用工具。
-
对于 明显无效 的输入(阿瓦达啃大瓜),模型会稳定拒绝调用
-
对于 边缘但可理解 的输入(火星),模型可能会出现策略摇摆
这也意味着,在测试 Function Calling 时,
真正值得关注的不是“会不会调用”,而是:
在什么情况下,模型应该拒绝调用工具。
这,才是我觉得 Function Calling 最值得测试的地方。
更多推荐


所有评论(0)