很多 Function Calling 的示例,看起来都很顺:

用户问天气 → 模型调用函数 → 返回结果

但在真实系统里,最重要的其实不是“能不能调用工具”,而是:
👉 模型什么时候会拒绝调用?什么时候会纠错?什么时候会追问?

我用一个最小天气查询 Demo,从测试视角系统性跑了一组输入,把模型的真实行为拆了一遍。


一、最小 Demo:一个 get_weather 工具

工具定义比较简单,只要求一个必填参数 city

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取当前城市天气信息",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "城市名词,例如:深圳,上海等"
                    }
                },
                "required": ["city"]
            }
        }
    }
]

调用方式使用:

# 调用大模型
response = client.chat.completions.create(
        model="glm-4.5",
        messages=messages,
        tools=tools,
        tool_choice="auto"  # 自动选择是否调用函数
)

也就是说:是否调用工具,完全交给模型自己判断。

打印响应:

# 拿到模型真正返回的内容
answer = response.choices[0].message
print(answer)

print("tool_calls:", answer.tool_calls)
print("arguments:", answer.tool_calls[0].function.arguments)

二、基础场景:信息充分时,模型会稳定调用工具

输入:

深圳天气怎么样?

输出关键点:

  • tool_calls 存在

  • 函数名:get_weather

  • 参数:

{"city": "深圳"}

测试结论:

  • 在信息明确、参数完整的情况下,模型会优先返回 结构化的 tool_calls

  • content 基本为空,自然语言回答会延后到“工具执行结果回填”之后

👉 这也是很多人第一次用 Function Calling 时误以为“模型没回答”的原因。

三、多任务场景:一次响应中生成多个 tool_calls

输入:

深圳和广州的天气对比一下

输出:

同一次响应中,生成 两个 tool_calls

  • index=0 → 深圳

  • index=1 → 广州

测试结论(非常重要)

  • 模型具备 拆分任务 → 多次调用同一工具 的能力

  • 如果代码里只处理 tool_calls[0],就会出现严重逻辑缺陷(只查一个城市就开始对比)

👉 正确做法:必须遍历 tool_calls 执行。

四、跨语言输入:模型会做实体归一,而不是原样透传

输入:weather in Shenzhen

输出:

  • reasoning 是英文

  • 但最终参数被归一为:

  • {"city": "深圳"}

测试结论

  • 模型在 Function Calling 前,存在一层 跨语言实体归一

  • 这会直接影响后端工具的入参兼容性设计(只收中文?还是中英文都行?)

五、错别字场景:先纠错,再调用工具

输入:深证天气怎么样?

输出:

  • 模型明确判断“深证”是“深圳”的错别字

  • tool_calls 中参数被修正为:

{"city": "深圳"}

测试结论

Function Calling 并不是简单的字符串提取,
而是发生在 语义理解和实体纠错之后

六、无效实体:模型会主动放弃工具调用

输入:阿瓦达啃大瓜天气怎么样?

输出:

  • 判断该词不是有效城市

  • 没有触发 tool_calls

  • 转为自然语言追问用户

测试结论(关键)

  • 当模型判断参数 语义无效 时,会拒绝调用工具

  • 能有效避免“参数幻觉”导致的错误调用

七、缺参场景:required 字段会触发追问,而不是调用

输入:天气怎么样?

输出:

  • 识别出缺少 city

  • 未触发 tool_calls

  • 主动询问用户具体城市

测试结论

  • tool schema 中的 required 字段,会真实影响模型决策

  • 不是摆设

八、行为总结表(测试视角)

九、测试视角下的 3 个核心结论

  1. Function Calling 的前提不是“匹配到工具”,而是语义可执行

  2. schema 的 required 字段,会改变模型的交互策略

  3. 真正难测的不是“会不会调用”,而是“什么时候不该调用”

结语

Function Calling 本质上是一个
“语义判断 → 参数构造 → 工具执行” 的决策链。

如果只验证“工具有没有被调用”,其实只测到了最表层。
站在测试视角,更有价值的是:

👉 模型在哪些边界条件下,选择了不调用。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐