🦾 AI Agent 🟡 进阶 ⏱ 9 分钟

📞 Function Calling:模型「说」,代码「做」

两轮对话 + 中间执行,模型只出 JSON 意图。顺便讲清 Function Calling 和 Tool Calling 到底啥关系。

1

Function Calling 在解决什么问题

🗣️ 没有它之前:靠猜

想让模型调工具,只能解析自然语言:模型说「我需要查一下北京的天气」,开发者写 if/else 判断它「说」的是要查天气,再手动调 API。

这做法极其脆弱——模型换个说法,if/else 就失配了,无法标准化。

🎯 有了它之后:出 JSON

Function Calling 把这件事固定下来:模型不「说」要调工具,而是直接输出一段结构化的 JSON,开发者按格式解析就行。

准确率大幅提升,也有统一标准对接。

OpenAI 2023 年推出,Claude/Gemini/Qwen 都支持

2

三个角色:一场任务委托

👔 开发者 = HR

给每个工具写「职位说明书」(JSON schema),告诉模型:我们有哪些工具、每个能做什么、需要哪些参数。

🧠 模型 = 经理

读完说明书,决定「这个任务需要调哪个工具、参数填什么」,然后把指令下达出来。

它全程只是「下指令」,不亲自执行任何代码。

🧑‍💻 你的代码 = 员工

真正去跑函数、访问网络、查数据库,把结果汇报回来。

关键:模型没有执行权限,也没有直接访问网络的权限。

一句话焊死:模型只负责决策(选什么工具、填什么参数),执行由宿主代码完成。这是整个机制的核心设计,也是面试最容易踩的误区。

3

工具定义:JSON schema

📋 schema = 工具说明书

一份结构化 JSON,告诉模型工具叫什么、能做什么、需要哪些参数。

核心字段:name(名字)、description(描述)、parameters(参数类型/必填/enum/说明)。

🎯 命门:description

模型判断要不要调、参数怎么填的唯一依据就是 description。

❌ 写「获取天气」→ 模型瞎猜
✅ 写「查询指定城市的实时天气,含气温、天气状况、风向风速,仅支持中国大陆城市」→ 选得准

参数 description 同理:格式要求、示例值、限制条件都要写进去。写得越清晰,模型的选择越准确。

例如 city 参数要写「城市名称,如北京/上海,不要带省份前缀」;unit 用 enum: ["celsius", "fahrenheit"] 限定取值。

4

运行时:两轮对话 + 中间执行

① 传问题+工具messages + tools 发给模型
➜
② 模型出 tool_callsfinish_reason=tool_calls
➜
③ 代码执行解析 JSON 跑函数
➜
④ 结果塞回role=tool 挂回对话
➜
⑤ 模型给答案自然语言最终回答
🔁 模型没准备好答案,先输出 tool_calls 信号 → 你执行 → 再喂回去 → 才给最终答案
🎬 查天气的完整两轮对话
User
北京今天天气怎么样?
模型·第一轮
判断需要工具,finish_reason=tool_calls,输出 tool_calls:[{"function": "get_weather", "arguments": {"city": "北京"}}]
你的代码
解析 JSON,调真实天气 API → 得到「北京今天晴,15°C,东北风 3 级」
模型·第二轮
读到 tool 结果后回答:「北京今天天气晴朗,气温 15°C,适合外出。」
5

并行工具调用

⚡ 一次出多个 tool_calls

tool_calls 是个列表。问「北京和上海的天气」,模型一次返回两个调用请求,代码可同时执行(asyncio.gather / 线程),拿齐结果一次性塞回。

避免串行跑两轮的延迟。

🔗 前提:无依赖

并行调用要求几个工具之间没有依赖关系。

✅ 查北京天气 + 查上海天气 → 可并行
❌ 先查订单号、再查物流 → 第二个依赖第一个,只能串行

6

那 Function Calling 和 Tool Calling 呢?

官方口径:OpenAI 文档第一句就写 Function calling, also known as tool calling——在模型侧两者是同一个东西,模型都只「说想法」。

差异在概念范围,不在执行能力:

🧠 Function Calling🛠️ Tool Calling
定位早期/狭义:模型输出「调哪个函数+JSON参数」现代/广义:在工具箱选工具 + Agent 循环
范围函数是工具的一种函数、搜索、代码执行、MCP 都是工具
执行模型侧不执行模型侧也不执行,是应用/框架/平台跑
演进functions/function_call(老 API)tools/tool_calls(新 API,支持并行+多类型)
🔑
准确版本

两者在模型侧都不执行代码。执行代码的是你的应用、框架或服务商 server tool。

🧩
别被框架骗到

LangChain 的 @tool 装饰器把 schema、parser、executor 全包了,看似「模型会执行」,其实是框架帮你写了 if tool_calls 的循环。

☁️
server tool 是特例

Anthropic 的 web_search/code_execution 是服务端执行,但那是官方白名单能力,不是 Claude 本体跑你业务代码。

一句话总结

Function Calling 是让模型「说」结构化 JSON 意图(调哪个函数、参数是啥)、由宿主代码「做」的机制,运行时是两轮对话 + 中间执行。它和 Tool Calling 在模型侧是同一件事,差异只在概念范围——FC 是早期狭义说法(函数),Tool Calling 是现代广义说法(工具+Agent 循环),两者模型侧都不执行代码。

🎤 面试问答 · 口语化回答
Function Calling 是 AI 工程面试必考,这几问常被深挖:
面试官讲讲 Function Calling 的原理?
你

我用一句话概括:模型不输出自然语言,而是输出结构化的 JSON 告诉我们它要调哪个函数、参数是什么,我们拿到 JSON 去真正执行,再把结果塞回对话,模型基于结果生成最终答案。运行时是两轮对话加中间执行:第一轮把工具列表和问题一起给模型,模型判断需要调工具就输出 tool_calls;我们执行;第二轮把 tool 结果挂回对话再问一次模型,它才给最终答案。

💡 加分点:强调核心设计很加分:模型只负责决策,执行由宿主代码完成,模型没有执行权限也没有网络权限。
面试官工具 schema 怎么定义?哪个字段最重要?
你

用 JSON schema 定义,包含 name、description、parameters。其中 description 最重要,因为模型判断要不要调这个工具、参数怎么填,唯一依赖的就是这段描述。如果只写「获取天气」,模型就会瞎猜;要写清楚使用场景、限制条件,比如「查询指定城市的实时天气,仅支持中国大陆城市」。参数的 description 也一样,格式要求、示例值、枚举都要写进去。

💡 加分点:能说出「description 是模型唯一依赖的依据」说明你写过工具定义、踩过模型选不准工具的坑,很有实战感。
面试官Function Calling 和 Tool Calling 有什么区别?
你

在模型侧它俩其实是同一个东西,OpenAI 文档直接写 Function calling also known as tool calling,模型都只输出意图不执行。区别在概念范围:Function Calling 是早期狭义的说法,指模型输出调哪个函数加 JSON 参数;Tool Calling 是现代广义的说法,指模型在工具箱里选工具再加 Agent 循环。函数是工具的一种,工具还可以是搜索、代码执行、MCP。两者模型侧都不执行代码,真正执行的是我们的应用或框架。

💡 加分点:能主动纠正「Tool Calling 里模型会执行代码」这个误区非常加分,说明你真的理解三层执行主体(模型/你的代码/平台)。
📝 读完打卡 · 写下你的收获 读完了?来打卡吧
用一句话写下你从这篇学到的最大收获,检验自己是否真的懂了 👇
⏱ 00:00 🔥0分