Tool Calling 是什么?大模型如何调用工具?
Tool Calling 是什么?大模型如何调用工具?
一句话核心:Tool Calling(Function Calling)是通过特殊训练让大模型输出结构化JSON来调用外部API的技术,解决"LLM只生成文本、无法执行操作"的核心痛点,是聊天机器人进化为智能体的关键一步。
核心概念(术语表)
- Tool Calling / Function Calling:让大模型调用外部工具的技术,最早由OpenAI于2023年6月13日提出,本质是通过结构化JSON而不是自然文本来传递调用指令
- SFT(Supervised Fine-Tuning):监督微调,给模型喂大量「工具调用示范对话」,教会模型"会不会调"
- RLHF(Reinforcement Learning from Human Feedback):人类反馈强化学习,用打分器调整模型参数,教会模型"该不该调"
- 奖励模型(Reward Model):RLHF中单独训练的小模型,负责判断"哪个回答人类更喜欢",本质是把人类偏好蒸馏进裁判
- 工具 Schema / JSON Schema:工具的说明书,描述函数名、参数类型、功能描述,模型靠它"认识"有哪些工具可用
- 特殊标记符(Special Tokens):如
<|tool▁calls▁begin|>、<|User|>,没有文本含义但能规范模型在不同任务模式间切换输出 - 指令微调(Instruction Tuning):在预训练基础上用带标签的文本数据训练,让模型学会各种问题的回答方式
- 意图识别(Intent Recognition):模型判断用户问题是否需要调用工具的关键能力,决定了"调还是不调"
- MCP(Model Context Protocol):模型上下文协议,Function Calling的升级版,解决多工具管理的生态问题
- RLAIF(RL from AI Feedback):用AI代替人类打分的RLHF变体,成本更低、速度更快,效果与人工反馈相近
历史背景 / 来源
Function Calling 由 OpenAI 于 2023年6月13日 正式提出(来源:OpenAI官方公告)。当时GPT-4刚发布不久,OpenAI意识到大模型虽然能生成流畅文本,但无法真正"干活"——查不了天气、执行不了操作、控制不了机器人。为了让LLM从"只会说"进化到"能做",OpenAI设计了这套机制:用外部函数作为中介传递调用请求,模型负责决策,代码负责执行。这一设计成为后续所有Agent开发框架和MCP协议的基础。现在主流Agent开发框架(如Agents-SDK)和MCP技术,本质都是对Function Calling流程的效率优化。
工作原理 / 核心机制
整体思路
Function Calling的核心是"模型决策 + 代码执行"的分工模式:大模型通过特殊标记符学会在普通对话和工具调用两种模式间切换,当判断需要工具时输出结构化JSON,外部函数接收JSON后真正调用API,最后把结果塞回对话让模型给出最终回答。
训练阶段
第一步:SFT 教"套路"
构造训练数据:System消息放工具说明书(函数名、参数、功能)→ User消息放用户提问 → Assistant输出结构化JSON调用请求(如 {"tool_calls":[{"name":"get_weather","arguments":{"city":"北京"}}]})→ Tool消息模拟工具返回 → Assistant给出最终回答。数据来源:人工标注(质量高但贵)+ GPT-4自动生成(成本低、量大,业界主流)。训练规模:几十万到上百万条样本。
第二步:RLHF 教"边界感"
- 对同一问题生成多种回答(调工具/不调/参数填错),覆盖各种情况
- 人类标注员判断哪种回答更合理
- 用打分数据训练奖励模型(Reward Model),相当于"会打分的裁判"
- 用奖励模型的分数强化学习调整主模型参数,让它倾向产出高分回答
关键点:奖励模型的打分能力从人类偏好中学出来,如果人类标注员水平不稳定,奖励模型会学到歪的标准。
推理阶段
- 应用代码把工具Schema(JSON格式说明书)连同用户问题一起发给模型
- 模型判断是否需要工具:无关问题直接回答,相关问题输出
tool_callsJSON - 外部函数接收JSON,自动带入参数运行API
- 把结果封装为
function response message加入消息列表 - 模型拿到结果,给出最终自然语言回答
关键知识点
- LLM预训练只学文本生成:模型从出生到成年只生活在文字世界,见过海量书籍却从没接触过工具,根本不知道"API调用"是什么
- 工具调用不是涌现能力:参数量大只能让模型理解力和推理能力变强,输出可解析的JSON格式是预训练语料里根本不存在的模式,必须后天训练
- SFT只解决"会不会"不解决"该不该":训练样本里"该调场景"占绝大多数,模型会过拟合"积极调用"倾向,看过「1+1」也要去查计算器
- RLHF解决"边界感":经过人类反馈,模型学会能直接回答就回答、需要实时数据才调用,这是SFT给不了的
- 模型只负责决策不负责执行:整个过程模型只是在"下指令",真正执行工具的是你的代码
- 意图识别是最大难点:三个问题都提到"北京"但意图完全不同——电影推荐(不调)、穿衣建议(查北京)、旅游规划(查北京+杭州)
- 特殊标记符是模式切换的关键:DeepSeek-V3的
<|begin▁of▁sentence|>、<|User|>等标记没有文本含义,但能规范模型在不同响应模式间切换 - Function Calling是JSON而非自然语言:JSON格式固定、机器好解析,代码才能准确读到"调哪个工具、参数是什么"
- DeepSeek R1放弃Function Calling:为优先保障推理能力(R1核心定位),选择不训练工具调用,这是模型设计的权衡取舍
- 没有原生Function Calling的模型也能用工具:通过提示词工程引导,虽然不如原生支持的效果好,但技术上可行
- MCP是Function Calling的生态升级:解决多工具管理问题,让开发者无缝接入海量外部工具生态,像搭积木一样开发Agent
- 训练数据用特殊标记分隔输入输出:指令微调数据中,
<|tool▁calls▁begin|>和<|tool▁calls▁end|>标记告诉模型这里要输出结构化调用 - RLAIF已接近人工反馈效果:用AI打分代替人类标注,成本更低、速度更快,业界现在很常用
- 工具Schema本质是"名片":描述函数的输入输出,让模型知道这个工具是干什么的、怎么用
应用场景
- DeepSeek Mini Manus:用6个外部工具实现复杂任务自动化,用户描述目标后Agent自动规划调用哪几个工具完成任务
- Claude Code / Cursor:AI编程助手,通过Function Calling调用文件系统API、bash命令API,执行代码、读写文件
- OpenWeather + 聊天机器人:用户问"北京天气",Agent自动调用天气API获取实时数据再回答,而非让用户自己去查
- 企业知识库问答:结合RAG技术,Agent判断需要查哪个知识库文档,调用搜索API获取最新信息再综合回答
- 电商智能客服:同时调用库存API(查有没有货)、物流API(查发货时间)、价格API(查优惠),一次性回答用户多个问题
常见误区 / 踩坑
❌ 误区1:认为Function Calling是LLM直接执行代码
✅ 正解:模型只输出JSON调用请求,真正执行的是你的代码。模型是"决策者"不是"执行者"❌ 误区2:以为工具调用能力是大模型涌现出来的
✅ 正解:涌现能力是"量变引起质变",指参数量大后理解力变强,但输出结构化JSON是预训练语料里根本不存在的模式,必须后天专门训练❌ 误区3:认为SFT训练完模型就知道"什么时候该调工具"
✅ 正解:SFT只教"套路",模型会过拟合积极调用倾向,必须再通过RLHF建立边界感❌ 误区4:以为所有大模型都支持Function Calling
✅ 正解:DeepSeek R1等推理模型为优先保障推理能力,选择放弃Function Calling训练。没有原生支持的模型需要用提示词工程补救❌ 误区5:认为Function Calling和MCP是竞争关系
✅ 正解:MCP是Function Calling的生态升级,解决多工具管理问题,两者协同而非替代
性能 / 复杂度
- 意图识别准确率:直接影响Function Calling成功率,差的模型可能"该调不调、不该调乱调"
- 工具匹配复杂度:当工具数量从3个增加到30个,意图识别的难度指数上升(n个工具 → n种意图组合)
- 延迟:多轮调用工具时,每次API请求增加200-500ms延迟,多步任务可能累积到数秒
与替代方案对比:
- 方案A:纯提示词工程引导(无原生Function Calling),速度无额外开销,但准确率低30-40%
- 方案B:原生Function Calling,准确率高,但需要额外训练成本
- 临界点:简单单轮任务用提示词勉强可行,复杂多工具任务必须用原生支持
与相关概念的区别
- vs API调用:API调用是代码直接调代码,Function Calling是AI决策后调代码。Function Calling多了"意图识别"环节,知道什么时候该调
- vs MCP协议:Function Calling是一对一工具调用,MCP是标准化多工具管理。Function Calling是"单兵作战",MCP是"集团军作战"
- vs Agent:Function Calling是Agent的能力之一,Agent = 大模型 + 工具调用 + 记忆 + 规划。Function Calling是Agent的"手"
进阶 / 面试加分项
- 最新进展:MCP协议(2024年由Anthropic提出)正在成为工具调用的事实标准,解决Function Calling无法统一管理多工具的痛点,A2A协议进一步解决多Agent协作问题
- 业界争议:推理模型(如DeepSeek R1)是否应该保留Function Calling能力——保障推理深度 vs 保持工具调用的广度,模型设计必须做权衡
- 一句话送给候选人:Function Calling训练的本质是"教模型说机器能听懂的话",SFT给词汇表,RLHF给语法规则,缺一不可
面试如何回答
🟢 什么是 Function Calling?它和普通的 API 调用有什么区别?
回答要点:
Function Calling(也叫 Tool Calling)是一种让大模型调用外部工具的技术,核心是模型输出结构化 JSON 来传递调用指令,而不是像普通 API 调用那样由代码直接触发。关键区别在于:普通 API 调用是规则驱动的(写 if-else 判断什么时候调), Function Calling 是意图驱动的(AI 自己判断要不要调)。举例:用户问"北京天气怎么样",Function Calling 让 AI 自动识别需要查天气,然后输出 {"tool_calls":[{"name":"get_weather","arguments":{"city":"北京"}}]},外部函数拿到这个 JSON 才真正调用天气 API。这个设计最早由 OpenAI 在 2023 年 6 月提出,解决了 LLM "只会说、不会做" 的核心痛点。
🟡 为什么大模型不会天生调用工具?工具调用能力是怎么训练出来的?
回答要点:
大模型预训练阶段只学文本生成,见过海量书籍却从未接触过工具,所以遇到"查天气"只会说"我需要调用天气 API",而不会输出可解析的 JSON 调用请求。工具调用能力靠两个阶段后天训练:第一阶段是 SFT(监督微调),给模型喂大量「工具调用示范对话」,让它学会看到工具描述 → 判断要不要调 → 输出结构化 JSON 这整套流程;第二阶段是 RLHF(人类反馈强化学习),让模型生成多种回答(调/不调/参数错),人类标注员打分,训练奖励模型,再用强化学习调整参数,让模型学会"什么时候不该调"。简单说:SFT 教"套路",RLHF 教"边界感",缺一不可。
🟡 SFT 和 RLHF 在工具调用训练中各自解决什么问题?为什么 RLHF 不可省略?
回答要点:
SFT 只解决了"会不会调",RLHF 解决"该不该调"。举个例子:经过 SFT 训练的模型,遇到"1+1 等于几"也可能去调计算器工具,这明显画蛇添足。为什么会这样?因为 SFT 训练样本里"该调的场景"占绝大多数,模型在模仿中会过拟合"积极调用"的倾向,没有看过足够多的"不该调"反例,所以边界感天然就弱。RLHF 通过人类反馈建立边界感:让模型生成多样回答,人类判断哪种更合理,训练奖励模型打分,再用强化学习优化主模型,让它学会"能直接回答的就直接回答、需要实时数据的才调用"。这个边界感是 SFT 给不了的,必须靠反馈信号来塑造。
🟡 Function Calling 的运行时流程是怎样的?请详细描述每个步骤
回答要点:
运行时流程分三步走:第一步,应用代码把工具 Schema(JSON 格式的工具说明书,包含函数名、参数、功能描述)连同用户问题一起发给模型;第二步,模型进行意图识别——如果判断问题与工具无关(如"你好"),直接生成自然语言回答;如果判断需要工具(如"北京天气"),输出包含 tool_calls 字段的结构化 JSON;第三步,外部函数接收这个 JSON,自动带入参数调用真正的 API(如 OpenWeather),把返回结果(如"晴,15°C")封装为 function response message 加入消息列表,模型拿到结果再给出最终自然语言回答("北京今天天气晴朗,气温15°C")。整个过程模型只是"决策者",真正"执行者"是你的代码。
🔴 为什么有些推理模型(如 DeepSeek R1)不支持 Function Calling?模型是如何学会在不同响应模式间切换的?
回答要点:
模型设计必须做权衡:Function Calling 训练和推理能力训练在资源分配上有冲突。DeepSeek R1 为了优先保障推理深度,选择主动放弃 Function Calling 训练,这是产品定位的取舍而非技术缺陷。关于模式切换:大模型靠特殊标记符(Special Tokens)实现不同响应模式。拿 DeepSeek-V3 来说,输入文本中包含 <|User|>、<|Assistant|>、<|tool▁calls▁begin|> 等隐藏标记,这些标记没有文本含义但能规范模型行为。训练时,带工具的样本在 output 中包含 <|tool▁calls▁begin|>get_weather<|tool▁calls▁end|> 这样的结构,让模型学会"遇到这类标记就输出 JSON"。本质上,Function Calling 就是用特殊标记符规范的一种特殊响应模式。
🟡 Function Calling 和 MCP 协议有什么区别?什么场景用哪个?
回答要点:
Function Calling 是一对一工具调用(一个模型调一个工具),MCP(Model Context Protocol)是标准化多工具管理(一个模型管多个工具)。打个比方:Function Calling 像"单兵作战",每个工具单独对接;MCP 像"集团军作战",通过统一协议管理所有工具。Function Calling 的痛点是:当系统有 30 个工具时,每个工具都要单独写接口,管理和维护成本极高。MCP 解决了这个问题,让开发者可以无缝接入海量外部工具生态,像搭积木一样开发 Agent。实际选择:简单场景(2-3 个工具)用 Function Calling 足够;复杂场景(10+ 工具、多 Agent 协作)用 MCP 更合适。现在 Claude Code、Agents-SDK 等主流框架都支持 MCP。
🟡 如果模型没有原生 Function Calling 能力,有什么补救方案?效果如何?
回答要点:
可以用提示词工程(Prompt Engineering)引导模型输出结构化信息,但效果不如原生支持。核心技巧是:在 System Prompt 里明确告诉模型"你有哪些工具可用,当用户问 XX 时,你应该输出 JSON 格式 {"tool":"xxx","params":{}}",并给出几个示例。这种方案相当于"用自然语言教模型规则",优点是零训练成本、任何模型都能用;缺点是模型可能不遵守格式、意图识别准确率低 30-40%、复杂多工具场景下几乎不可用。更进阶的方案是用微调数据在小模型上蒸馏 Function Calling 能力。实际建议:简单单轮任务可以尝试提示词工程,复杂多工具任务必须用原生支持或换模型。
🔴 训练 Function Calling 时的数据是怎么构造的?有没有什么坑?
回答要点:
训练数据构造有两种来源:人工标注(成本高但质量好,一般用于构造核心种子数据)和用 GPT-4 自动批量生成(成本低、量大,业界主流做法,需人工抽查)。数据格式是关键:一条完整样本包含 System 消息(工具说明书)、User 消息(用户提问)、Assistant 调用请求(结构化 JSON,不是自然语言!)、Tool 消息(模拟工具返回)、Assistant 最终回答。特别要注意的是,RLHF 阶段如果人类标注员水平不稳定、标准不一致,奖励模型会学到歪的打分标准,导致主模型优化方向偏离。另外,训练数据中"该调"和"不该调"的样本比例要平衡,否则模型会过拟合"积极调用"倾向——这些都是容易踩的坑。
