大模型Function Calling:解锁AI智能工具箱
一、用一句更直白的话定义 Function Calling
在大语言模型(比如 GPT、Claude 等)里,Function Calling(函数调用)就是:让模型在回答问题时,不是直接给你“结果”,而是先给你一份“调用你写好的函数的说明书(函数名 + 参数)”,由你的程序去真正执行这个函数,再把结果喂回模型,最终输出自然语言答案。
你可以把它理解成:
用户 →(自然语言)→ 模型 →(结构化函数调用)→ 你的代码 / 外部系统 →(真实结果)→ 模型 →(自然语言总结)→ 用户
二、为什么需要 Function Calling?
大模型本身有几类“天生短板”:
不会真正“动手”
它能“说”,但不能直接:
发邮件、拉群
查数据库
下单、订票
操作企业内部系统
没有实时数据
训练完成后,参数里的知识是“冻结”的:
不知道最新汇率、股价、天气
不知道今天的新闻
不知道你公司刚刚新增的订单
不擅长精确计算 / 严格规则
复杂税务、工程计算容易出错
对“必须是结构化输出”的场景不稳(如严格 JSON)
Function Calling 的目的,就是:给模型配备一套“可靠工具箱”,让它在需要时主动调用这些工具(函数),用真实世界的数据和能力来弥补自身的不足。
三、完整工作流程
用一个具体例子来拆解:
用户说:「帮我查一下上海今天的天气,顺便建议我穿什么。」
步骤 1:你把“工具说明书”给模型
你在请求里告诉模型:
有一个函数叫 get_weather
它的作用:查实时天气
它接收哪些参数、类型是什么(用 JSON Schema 定义)
示例(概念性):
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的实时天气",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市名称,例如 \"Shanghai\" 或 \"上海\""
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位"
}
},
"required": ["location", "unit"],
"additionalProperties": false
}
}
}
你把这些函数定义放到 tools(或类似字段)里一起发给模型。
步骤 2:用户发自然语言请求
例如:
用户:“帮我查一下上海今天的天气,顺便建议我穿什么。”
步骤 3:模型决定要不要用工具、用哪个工具
模型读完用户问题,结合你提供的函数列表,判断:
这个问题需要实时天气
自己脑子里没有今天的实时数据
你恰好提供了 get_weather 这个函数
于是它决定:调用 get_weather。
步骤 4:模型生成“函数调用请求”(结构化 JSON)
而不是直接用中文回答,模型给你一段“指令”,大致是:
{
"name": "get_weather",
"arguments": {
"location": "Shanghai",
"unit": "celsius"
}
}
这段内容不是给用户的,而是给你的后端程序看的——告诉你应该执行哪个函数、传什么参数。
步骤 5:你的程序真正去执行函数
对应代码大致这样(伪代码):
def get_weather(location, unit):
# 这里调用真实的天气 API 或内部服务
# 返回结构化结果
return {
"location": location,
"temperature": 18,
"unit": unit,
"description": "小雨"
}
# 从模型的输出里取出函数名和参数
call = {
"name": "get_weather",
"arguments": {"location": "Shanghai", "unit": "celsius"}
}
result = get_weather(**call["arguments"])
得到的 result 是真实数据,例如:
{
"location": "Shanghai",
"temperature": 18,
"unit": "celsius",
"description": "小雨"
}
步骤 6:你把执行结果再喂回给模型
你会再发起一次请求,用类似这样的内容(概念):
把这次工具调用的“结果”作为一条特殊的“tool 消息”
同时把原始用户问题也带上
模型收到后,看到:
用户问了什么
它之前调用了哪个函数
这个函数返回了什么结果
步骤 7:模型基于工具结果生成自然语言回答
模型会用自然语言组织最终答案,比如:
“上海今天小雨,气温大约 18℃,建议你穿一件带帽的外套,出门记得带伞。”
到这一步,用户才看到最终回答。
小结:
**第一次请求:主要是“我要解决什么问题 + 这些是你可以用的工具”
中间过程:模型只返回“函数调用指令”,不给用户看
你执行完函数后:再把结果回给模型
最后一次回复:才是面向用户的人类可读答案
四、函数定义里的 JSON Schema 是干嘛的?
你在告诉模型“有一个函数可以用”的时候,要把参数结构讲清楚,否则模型不知道怎么“组装参数”。
4.1 常见字段
type: 必须是 "function"(表示这是一个函数工具)
name: 函数名(如 get_weather)
description: 用人话说明该函数用来干什么
parameters: 用 JSON Schema 定义参数
type: 一般是 "object"
properties: 参数列表及类型
required: 哪些参数是必填
additionalProperties: 是否允许多余字段
strict: 是否启用严格模式(让模型必须**遵守 schema)
4.2 参数类型和约束
在 properties 里,你可以定义:
string, number, integer, boolean, object, array 等
enum:枚举值限制,比如 ["celsius", "fahrenheit"]
description:解释这个字段的含义,模型依靠它理解怎么用
示例(更完整一点):
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市名称,如 \"Shanghai\" 或 \"上海\""
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位"
},
"lang": {
"type": "string",
"enum": ["zh", "en"],
"description": "返回内容的语言"
}
},
"required": ["location", "unit"],
"additionalProperties": false
}
好处:
模型知道该传哪些字段、用什么值,错误率明显降低
你可以对不合法的入参做校验,提升系统健壮性
五、和“普通 API 调用”有什么本质不同?

一句话概括:
传统方式:“开发者说了算”(逻辑都写死在代码里)
Function Calling:“模型说了算”(模型理解需求 → 自动选择工具)
六、常见落地场景(更细一点)
智能客服 / 智能助理**
函数:query_order_status, cancel_order, create_ticket
效果:用户直接问「帮我查一下 123456 这个订单的物流」,模型会自动:
从话里抽出订单号
调用 query_order_status
整理查询结果、解释给用户听
企业内部知识 / 数据查询
函数:query_crm, get_project_status, search_docs
模型变成“公司内部信息入口”:
「我们和 XX 客户上一次签的合同金额是多少?」
→ 调 CRM API → 查合同表 → 模型总结回答。
个人助手
函数:create_calendar_event, add_todo, send_email
用户说:「帮我下周三下午 3 点和张三开会,拉个日历事件,提醒我提前半小时准备。」
→ 模型调用日历 API → 创建日程 → 再用自然语言确认。
数据分析 / 报表生成
函数:run_sql_query, generate_chart
模型先通过 run_sql_query 拉出原始数据,再生成文字分析和可视化建议。
复杂多步骤任务
比如“帮我规划一个上海周末两日游的行程并预订酒店”:
步骤1:search_spots 搜景点
步骤2:plan_route 规划路线
步骤3:search_hotels 找酒店
步骤4:book_hotel 预订
整个链路中,可以有多次函数调用 + 中间自然语言解释。
七、对开发者来说,具体要做哪几件事?
可以理解为“三件核心工作 + 一点工程实践”。
7.1 核心三件事
设计并描述你的函数(工具)
把业务能力拆成一个个函数:get_weather、query_db、send_email …
给每个函数写清楚:
函数名(name)
功能说明(description)
参数结构(parameters JSON schema)
这一步更像写“API 文档”,但对象是**大模型。
在后端真正实现这些函数**
根据你的技术栈实现:
Python/Java/Go 等
内部服务调用、外部 API 调用、数据库、第三方平台
写一个“中间层”去调度
接收模型返回的 function call(JSON)
根据 name 跳转到对应实现
执行后把结果再打包成“tool 输出”喂回模型
处理错误(比如 API 挂了、参数不合法)
7.2 工程实践建议
对每个函数:
做参数校验(长度、格式、枚举值)
做错误兜底(请求外部 API 失败要有 fallback)
对整体系统:
记录每次函数调用的日志(方便排查问题)
控制调用频率和并发(防止接口被打爆)
监控成本(过多的函数定义会增加 Token 消耗)
八、Function Calling 的优势与局限
8.1 明显优势
大大简化“自然语言 → API 调用”这一步
以前要写一堆 NLP / 规则解析,现在交给模型自动做。
提高系统灵活性和可扩展性
新功能 = 新增/修改一个函数定义和实现。
可以和检索(RAG)、多模态等能力组合
例如:先用检索拿到文档,再调用函数做计算。
8.2 需要注意的局限
**不是万能的:
模型有时会给出不合适的参数或调用不合适的函数,因此需要:
严格的 JSON Schema
后端的参数验证和错误处理
增加了系统复杂度:
相比“纯聊天”,你要多维护一层“工具层”和“调度逻辑”。
延迟和成本:
每一次函数调用通常意味着:
一次额外的模型请求(把结果喂回模型)
一次外部 API 请求
需要在体验和准确性之间平衡
更多推荐

所有评论(0)