函数调用
函数调用(Function Calling / Tool Use)允许模型在生成回复时识别需要调用外部工具的场景,并返回结构化的函数调用参数。你的程序执行函数后,再将结果返回给模型,由模型生成最终回复。
工作流程
用户提问 → 模型判断需要调用函数 → 返回函数名和参数
→ 你的程序执行函数 → 将结果发回模型 → 模型生成最终回复模型本身不执行函数,它只负责决定”调用哪个函数”以及”传什么参数”。实际执行由你的代码完成。
适用场景
- 查询实时数据(天气、股价、数据库)
- 执行操作(发送邮件、创建工单、调用第三方 API)
- 构建 AI Agent(多步骤推理 + 工具调用)
- 与业务系统集成
基本示例
Python
from openai import OpenAI
import json
client = OpenAI(
api_key="<ACCELE_AI_API_KEY>",
base_url="https://api.acceleai.cn/v1"
)
# 第一步:定义工具
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"]
}
}
}
]
# 第二步:发送请求,让模型决定是否调用工具
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "user", "content": "北京今天天气怎么样?"}
],
tools=tools,
tool_choice="auto"
)
message = response.choices[0].message
# 第三步:检查模型是否要求调用函数
if message.tool_calls:
tool_call = message.tool_calls[0]
function_name = tool_call.function.name
arguments = json.loads(tool_call.function.arguments)
print(f"模型请求调用: {function_name}({arguments})")
# 输出: 模型请求调用: get_weather({"city": "北京"})
# 第四步:执行函数(这里用模拟数据)
weather_result = json.dumps({
"city": "北京",
"temperature": 22,
"condition": "晴",
"humidity": 45
}, ensure_ascii=False)
# 第五步:将函数结果发回模型
final_response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "user", "content": "北京今天天气怎么样?"},
message, # 包含 tool_calls 的助手消息
{
"role": "tool",
"tool_call_id": tool_call.id,
"content": weather_result
}
],
tools=tools
)
print(final_response.choices[0].message.content)
# 输出: 北京今天天气晴朗,气温22°C,湿度45%,适合外出活动。cURL
curl https://api.acceleai.cn/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <ACCELE_AI_API_KEY>" \
-d '{
"model": "gpt-4o",
"messages": [
{"role": "user", "content": "北京今天天气怎么样?"}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的当前天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名称"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["city"]
}
}
}
],
"tool_choice": "auto"
}'多函数定义
你可以同时定义多个函数,模型会根据上下文选择合适的函数调用,也可能一次调用多个函数(并行调用)。
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的当前天气",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string"}
},
"required": ["city"]
}
}
},
{
"type": "function",
"function": {
"name": "search_restaurants",
"description": "搜索指定城市的餐厅",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string"},
"cuisine": {"type": "string", "description": "菜系,如:中餐、日料、西餐"}
},
"required": ["city"]
}
}
}
]
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "user", "content": "北京天气怎么样?顺便推荐几家好吃的日料店。"}
],
tools=tools,
tool_choice="auto"
)
# 模型可能同时调用 get_weather 和 search_restaurants
for tool_call in response.choices[0].message.tool_calls:
print(f"调用: {tool_call.function.name}({tool_call.function.arguments})")tool_choice 参数
tool_choice 控制模型如何选择工具:
| 值 | 说明 |
|---|---|
"auto" | 模型自行决定是否调用工具(默认) |
"none" | 禁止调用任何工具,强制直接回复 |
"required" | 强制模型必须调用至少一个工具 |
{"type": "function", "function": {"name": "xxx"}} | 强制调用指定的函数 |
流式输出中的函数调用
函数调用同样支持流式输出。工具调用信息会通过 delta.tool_calls 逐步返回:
stream = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "北京天气如何?"}],
tools=tools,
tool_choice="auto",
stream=True
)
tool_calls_data = {}
for chunk in stream:
delta = chunk.choices[0].delta
if delta.tool_calls:
for tc in delta.tool_calls:
idx = tc.index
if idx not in tool_calls_data:
tool_calls_data[idx] = {"id": tc.id, "name": tc.function.name, "arguments": ""}
if tc.function.arguments:
tool_calls_data[idx]["arguments"] += tc.function.arguments
for idx, tc in tool_calls_data.items():
print(f"函数: {tc['name']}, 参数: {tc['arguments']}")支持的模型
| 模型 | 函数调用 | 并行调用 |
|---|---|---|
| GPT-4o / GPT-4o-mini | ✅ | ✅ |
| GPT-5 | ✅ | ✅ |
| Claude Sonnet 4 / Opus 4 | ✅ | ✅ |
| Gemini 2.5 Pro / Flash | ✅ | ✅ |
| DeepSeek V3 | ✅ | ✅ |
| Qwen 3 | ✅ | ✅ |
最佳实践
- 清晰的函数描述:
description字段要准确描述函数用途,模型依赖它来判断何时调用 - 参数描述要具体:每个参数都加上
description,并使用enum限制可选值 - 处理不调用的情况:模型可能判断不需要调用任何函数而直接回答,确保你的代码能处理这种情况
- 错误处理:函数执行失败时,将错误信息作为
tool角色的content返回,让模型据此生成友好提示 - 控制工具数量:定义过多工具会增加输入 Token 消耗并可能降低选择准确性,建议控制在 10 个以内