30秒快速回答: Function Calling 是大模型的一项核心能力——它能在对话中识别「什么时候该调用外部工具」,然后生成符合工具要求的参数。模型本身不执行函数,它只是「发号施令」——告诉系统「请调用这个函数,参数是这些」。你(开发者)负责执行函数并把结果返回给模型,模型再基于结果生成最终回答。
Function Calling 的工作流程
用户: 「北京今天天气怎么样?」
↓
┌─────────────┐
│ 大模型判断 │ 「我需要调用 get_weather 函数」
│ (决策层) │ 「参数: city='Beijing'」
└──────┬──────┘
↓ 返回 function_call 请求
┌─────────────┐
│ 你的代码 │ 执行 get_weather("Beijing")
│ (执行层) │ → 结果: {"temp": 25, "condition": "晴"}
└──────┬──────┘
↓ 将结果返回给模型
┌─────────────┐
│ 大模型回答 │ 「北京今天晴,气温 25°C。」
└─────────────┘
关键理解: 模型不执行任何代码。它只是”请求”你执行,你执行完后把结果告诉它,它再生成人类可读的回答。
代码实战:OpenAI Function Calling
from openai import OpenAI
import json
client = OpenAI()
# 1. 定义工具(函数声明)
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的实时天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如 Beijing, Shanghai"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位"
}
},
"required": ["city"]
}
}
},
{
"type": "function",
"function": {
"name": "send_email",
"description": "发送邮件",
"parameters": {
"type": "object",
"properties": {
"to": {"type": "string", "description": "收件人邮箱"},
"subject": {"type": "string", "description": "邮件主题"},
"body": {"type": "string", "description": "邮件正文"}
},
"required": ["to", "subject", "body"]
}
}
}
]
# 2. 模拟天气查询函数
def get_weather(city: str, unit: str = "celsius") -> dict:
# 实际项目中调天气 API
weather_data = {
"beijing": {"temp": 25, "condition": "晴", "humidity": 45},
"shanghai": {"temp": 28, "condition": "多云", "humidity": 70}
}
return weather_data.get(city.lower(), {"temp": 20, "condition": "未知"})
# 3. 对话循环
messages = [{"role": "user", "content": "北京今天热吗?帮我查一下天气"}]
while True:
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=tools,
tool_choice="auto" # 模型自动判断是否调用工具
)
msg = response.choices[0].message
# 如果模型不需要调工具,直接输出答案
if not msg.tool_calls:
print("AI:", msg.content)
break
# 如果模型要调工具,执行工具调用
messages.append(msg)
for tool_call in msg.tool_calls:
func_name = tool_call.function.name
func_args = json.loads(tool_call.function.arguments)
print(f"[调用工具] {func_name}({func_args})")
# 执行函数
if func_name == "get_weather":
result = get_weather(**func_args)
elif func_name == "send_email":
result = {"status": "sent", "message": f"邮件已发送至 {func_args['to']}"}
else:
result = {"error": f"未知工具: {func_name}"}
# 将工具结果返回给模型
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result, ensure_ascii=False)
})
输出:
[调用工具] get_weather({'city': 'Beijing'})
AI: 北京今天晴,气温 25°C,湿度 45%。不热,天气很舒适。
DeepSeek Function Calling(兼容 OpenAI 格式)
from openai import OpenAI
client = OpenAI(
api_key="你的key",
base_url="https://api.deepseek.com"
)
# 完全兼容 OpenAI 的 tools 参数格式
response = client.chat.completions.create(
model="deepseek-chat",
messages=[
{"role": "user", "content": "搜索2026年AI最新趋势"}
],
tools=[{
"type": "function",
"function": {
"name": "web_search",
"description": "搜索互联网信息",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "搜索关键词"}
},
"required": ["query"]
}
}
}]
)
Function Calling 的进阶技巧
1. 并行调用
模型可以在一次响应中请求调用多个独立函数:
# 用户: "比较北京和上海的天气"
# 模型一次返回两个 tool_calls:
# tool_call 1: get_weather(city="Beijing")
# tool_call 2: get_weather(city="Shanghai")
2. 强制调用
设置 tool_choice 确保模型一定调用某个函数:
# 强制调用特定函数
tool_choice = {"type": "function", "function": {"name": "get_weather"}}
# 或强制必须调用(任意一个已注册的函数)
tool_choice = "required"
3. 结构化输出
利用 Function Calling 强制模型输出结构化 JSON:
tools = [{
"type": "function",
"function": {
"name": "extract_person_info",
"description": "从文本中提取人物信息",
"parameters": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"occupation": {"type": "string"},
"skills": {"type": "array", "items": {"type": "string"}}
},
"required": ["name", "age", "occupation"]
}
}
}]
# 模型会强制按这个 JSON Schema 输出
Function Calling vs MCP vs Agent
| 维度 | Function Calling | MCP | Agent |
|---|---|---|---|
| 定位 | 模型内部的工具调用机制 | 外部工具的发现和连接协议 | 自主规划+执行的任务系统 |
| 谁负责调度 | 你的代码 | MCP 客户端 | Agent 自身 |
| 复杂度 | 低(手写调用逻辑) | 中(统一接口) | 高(自主决策) |
| 适用场景 | 1-3 个工具的简单调用 | 多工具标准化接入 | 复杂多步骤任务 |
关系: Agent 通常使用 Function Calling 作为底层机制来调用工具,而 MCP 协议可以为这些工具提供统一的发现和接入标准。三者是不同层次的互补关系。
常见问题
Q: Function Calling 需要额外付费吗?
不需要。Function Calling 是模型的内置能力,按正常的 Token 计费。但工具定义(tools 参数)和调用结果都会消耗 Token。
Q: 模型不调用我注册的函数怎么办?
确保函数命名清晰、description 描述准确。模型基于函数名和描述决定是否调用。如果描述是”获取天气”但用户问”外卖”,模型就不会触发。
Q: 函数调用失败了怎么处理?
在你的代码中捕获异常,将错误信息作为 tool result 返回给模型,模型会尝试用其他方式回答或告知用户无法完成。
Q: 支持多少个工具同时注册?
GPT-4o 支持最多 128 个工具。但工具越多,模型选择越容易出错。建议按需注册——当前对话可能用到的工具不超过 5-10 个。
下一步建议: 把本文的代码复制到 Colab 或本地运行,放一个真实的 REST API(如和风天气 API)替代 mock 数据,体验让 AI 真正调用外部世界的感觉。