总结
- 模型的能力仅限于"回答",不具备调用本地函数做出额外动作的能力,Function Calling的主要作用是赋予大模型调用本地函数的能力
- 和Agent的关系,Agent 底层通常就是基于 Function Calling 实现的
- 和prompt的区别是:prompt是 让模型"尽量按格式输出" ,cunction calling则是模型被强制输出结构化格式,区别在于稳定些
- 和MCP的区别: Function Calling = 模型调用本地函数,MCP = 标准化"外部工具调用协议"
什么是 Function Calling?
Function Calling(函数调用) 是指:
👉 让大模型在对话过程中,按照你预定义的函数结构,自动生成可执行的函数参数 JSON,由你的程序去真正执行逻辑。
简单说一句话:
模型负责"决定调用什么函数 + 生成参数",
你的程序负责"真正执行函数"。
为什么会有 Function Calling?
原始大模型只能输出文本。
比如你问:
帮我查一下杭州属于哪个省
模型能回答:
杭州属于浙江省
这是他训练的数据里面就有的,所以他能回答
但如果咱们问:
杭州明天天气怎么样
模型只能回答:
不知道/或者编一个答案给你
因为这组数据,他的训练数据里面没有,天气这种数据,一般都是实时产生的,不能作为固定数据提前训练进去。试试天气,一般是一些服务商提供查询api,才能获取到。而大模型本身,并不具备主动调用查询api的能力,或者说,它的能力仅限与"回答"
这就有了一个问题,如果我想问大模型此类问题,有什么办法吗
有!把天气的方法提前写到程序里,然后检测问题,最后让模型去调用这个方法不就行了
所以核心问题就是:怎么让模型主动调用你系统里的真实函数?
这就是 Function Calling 解决的问题。
它的工作流程
假设你在系统里定义了一个函数:
json
{
"name": "getWeather",
"description": "获取某城市的天气",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
}
},
"required": ["city"]
}
}
PS:重点,这个函数是你在你自己的系统里定义的,不是模型里面内置的
用户输入
今天杭州天气怎么样?
模型不会返回文本,而是返回:
假定 你的提示词里面存在这么一句话:
如果检测到输入有提问天气情况的,请按如下xxx格式给他返回,其中function_call.name字段是为字符串:getWeather,function_call.arguments.city为输入中询问的城市名称,如果没有城市,默认返回xxxxx
然后模型检测到你询问天气,则会返回如下:
json
{
"function_call": {
"name": "getWeather",
"arguments": {
"city": "北京"
}
}
}
注意:此时,属于模型的工作就算结束了,他已经回答了问题,剩下的就靠我们自己的先前定义的函数了。
然后我们的后端:
- 识别到 固定格式,识别到name === getWeather(此时你的代码中有那么一段代码 )
ini
if(function_call.name === 'getWeather'){
this.getWeather(function_call.arguments.city)
}
- 真正调用
getWeather("北京")3. 拿到真实天气数据 4. 再把结果喂回模型生成最终回答
代码实例
说半天,如果还是觉得有些迷糊,可以仔细理解下下面的代码实例
js
import OpenAI from "openai";
import dotenv from "dotenv";
dotenv.config();
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
/**
* 你自己系统里的真实函数
* (真实项目里这里会调用天气 API)
*/
async function getWeather(city) {
console.log("🌦 正在调用真实天气接口...");
// 模拟接口返回
return {
city,
temperature: "12°C",
weather: "多云",
};
}
async function run() {
const userInput = "今天杭州天气怎么样?";
// 第一次请求 ------ 让模型决定是否调用函数
const response = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [
{
role: "user",
content: userInput,
},
],
tools: [
{
type: "function",
function: {
name: "getWeather",
description: "获取某城市的天气",
parameters: {
type: "object",
properties: {
city: {
type: "string",
description: "城市名称",
},
},
required: ["city"],
},
},
},
],
});
const message = response.choices[0].message;
// 如果模型决定调用函数
if (message.tool_calls) {
const toolCall = message.tool_calls[0];
const functionName = toolCall.function.name;
const args = JSON.parse(toolCall.function.arguments);
console.log("🤖 模型决定调用函数:", functionName);
console.log("📦 参数:", args);
// 执行真实函数
let result;
if (functionName === "getWeather") {
result = await getWeather(args.city);
}
// 第二次请求 ------ 把函数结果喂回模型
const secondResponse = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [
{ role: "user", content: userInput },
message, // 模型的 function_call 信息
{
role: "tool",
tool_call_id: toolCall.id,
content: JSON.stringify(result),
},
],
});
console.log("\n✅ 最终回答:");
console.log(secondResponse.choices[0].message.content);
} else {
console.log("模型未调用函数:");
console.log(message.content);
}
}
run();
核心本质
Function Calling 本质是:
让模型输出 结构化 JSON,而不是自然语言。
模型不是直接执行函数。
它只是一个"决策器 + 参数生成器"。
和 Agent 的关系
很多人会混淆:
- Function Calling = 能调用一个函数
- Agent = 能根据任务多步调用函数 + 规划步骤
Agent 底层通常就是基于 Function Calling 实现的。
和 MCP 的关系
如果你最近在研究 MCP
简单理解:
- Function Calling = 模型调用本地函数
- MCP = 标准化"外部工具调用协议"
MCP 可以看作:
Function Calling 的协议升级版本 + 工具生态标准化
实际工程中的常见场景
1.查数据
- 查订单
- 查用户余额
- 查数据库
2.执行动作
- 创建任务
- 发邮件
- 发推文(你之前提过 Twitter API 一键发图,这种就很适合)
3.调外部 API
- 天气
- 股票
- 地图
- AI工具链
优势
- 输出稳定(结构化 JSON)
- 参数可控(强类型约束)
- 可自动化执行
- 可组合为 Agent
和 Prompt 工程的区别
Prompt 工程是:
让模型"尽量按格式输出"
Function Calling 是:
模型被强制输出结构化格式
稳定性完全不同。
最后
如果对你有用的话~
