函数调用 (Function Calling)
让模型智能调用你定义的外部函数,实现天气查询、数据库查询、API 调用等能力。
提示: Function Calling 也被称为 Tool Use,两者在 OpenAI 兼容格式中是等价的。WLON API 完整支持该功能。
什么是函数调用
函数调用(Function Calling)允许你向模型描述一组可用的函数(工具),模型会根据用户输入智能判断是否需要调用某个函数,并返回结构化的调用参数。你在本地执行函数后,将结果返回给模型,模型再生成最终回复。
典型应用场景包括:
- 实时数据查询 — 天气、股票、汇率等实时信息
- 数据库操作 — 根据用户意图查询或写入数据库
- 外部 API 调用 — 发送邮件、创建任务、搜索网页
- 计算与转换 — 精确数学计算、单位换算
定义工具 (tools)
在请求中通过 tools 数组定义可用的函数。每个工具使用 JSON Schema 描述其参数:
{
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的当前天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,例如:北京、上海"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位,默认摄氏度"
}
},
"required": ["city"]
}
}
}
]
}
参数说明:
name 为函数名称(仅限字母、数字和下划线);description 帮助模型理解何时该调用此函数;parameters 使用标准 JSON Schema 格式定义参数结构。tool_choice 参数
通过 tool_choice 参数控制模型的函数调用行为:
| 值 | 行为 |
|---|---|
"auto" | 默认值。模型自行决定是否调用函数 |
"none" | 禁止调用任何函数,模型只生成文本回复 |
"required" | 强制模型必须调用至少一个函数 |
{"type": "function", "function": {"name": "get_weather"}} | 强制调用指定函数 |
处理 tool_calls 响应
当模型决定调用函数时,响应中的 finish_reason 为 "tool_calls",并在 message.tool_calls 中包含调用信息:
{
"choices": [
{
"message": {
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\": \"北京\", \"unit\": \"celsius\"}"
}
}
]
},
"finish_reason": "tool_calls"
}
]
}
注意:
arguments 是 JSON 字符串,需要用 json.loads() 解析。模型可能在一次响应中返回多个 tool_calls,需逐一处理。多步调用循环
完整的函数调用流程是一个循环:
- 发送用户消息 + 工具定义给模型
- 模型返回
tool_calls(如果需要调用函数) - 在本地执行对应函数,获取结果
- 将 assistant 消息(含 tool_calls)和 tool 结果消息追加到对话中
- 再次请求模型 — 模型根据函数结果生成最终回复
- 如果模型再次返回
tool_calls,重复步骤 3-5
完整 Python 示例
以下示例展示了一个带有 get_weather 函数的完整调用流程:
import json
from openai import OpenAI
client = OpenAI(
api_key="sk-your-api-key",
base_url="https://api2everything.xyz/v1"
)
# 1. 定义工具
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的当前天气",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
}
},
"required": ["city"]
}
}
}
]
# 2. 模拟本地函数实现
def get_weather(city: str) -> str:
"""模拟天气查询(实际项目中调用真实天气 API)"""
weather_data = {
"北京": "晴,25°C,湿度 40%",
"上海": "多云,22°C,湿度 65%",
"广州": "小雨,28°C,湿度 80%",
}
return weather_data.get(city, f"{city}:暂无天气数据")
# 3. 发起对话
messages = [{"role": "user", "content": "北京和上海今天天气怎么样?"}]
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=tools,
tool_choice="auto"
)
message = response.choices[0].message
# 4. 多步循环处理
while message.tool_calls:
# 将 assistant 消息加入对话
messages.append(message)
# 执行每个函数调用
for tool_call in message.tool_calls:
func_name = tool_call.function.name
func_args = json.loads(tool_call.function.arguments)
# 调用本地函数
if func_name == "get_weather":
result = get_weather(**func_args)
else:
result = f"未知函数:{func_name}"
# 将函数结果加入对话
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result
})
# 再次请求模型
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=tools,
tool_choice="auto"
)
message = response.choices[0].message
# 5. 输出最终回复
print(message.content)
支持的模型
以下模型支持函数调用功能:
| 模型 | 说明 |
|---|---|
gpt-4o / gpt-4o-mini | OpenAI 最新模型,函数调用能力最强 |
gpt-4-turbo | 支持并行函数调用 |
claude-sonnet-4-20250514 | Anthropic Claude,通过兼容层支持 |
gemini-2.5-pro | Google Gemini,支持函数调用 |
deepseek-chat | DeepSeek V3,支持基础函数调用 |
qwen-plus | 通义千问,支持函数调用 |
建议: 对于复杂的多函数调用场景,推荐使用
gpt-4o 或 claude-sonnet-4-20250514,它们在函数选择和参数生成方面表现最佳。