OpenAI Function Calling
Function Calling(函数调用)让 AI 能够调用你定义的函数,是构建 AI Agent 和智能应用的核心能力。推荐使用 Responses API 的 tools 机制,Chat Completions 仍可兼容。
可以把它看成“AI 拿到你的工具箱并学会按规则借工具”。
模型负责决定“该用哪个工具”,你负责执行工具并把结果回传。
什么是 Function Calling?
Function Calling 让 GPT 模型能够:
- 理解用户意图
- 决定调用哪个函数
- 提取函数参数
- 返回结构化调用请求
用户: "北京今天天气怎么样?"
↓
GPT: 需要调用 get_weather(city="北京")
↓
你的代码: 调用天气 API
↓
GPT: "北京今天晴,气温 25°C"
读者导向:什么时候该用?
- 需要调用外部系统(天气、订单、库存、CRM)的场景
- 需要结构化参数抽取,而不是纯文本闲聊
- 需要可审计、可复现的执行链路
不建议用在:
- 只需单轮文案生成、无需外部数据交互的简单场景
基础用法
定义函数
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"]
}
}
}
]
调用 API
from openai import OpenAI
import json
client = OpenAI()
response = client.chat.completions.create(
model="gpt-5.2",
messages=[
{"role": "user", "content": "北京天气怎么样?"}
],
tools=tools
)
# 检查是否有函数调用
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}")
print(f"参数: {arguments}")
# 输出: 函数: get_weather, 参数: {"city": "北京"}
执行函数并返回结果
def get_weather(city: str, unit: str = "celsius") -> str:
"""模拟天气 API"""
# 实际应用中调用真实的天气 API
return f"{city}今天晴,气温 25°C"
# 1. 第一次调用 - 获取函数调用请求
response = client.chat.completions.create(
model="gpt-5.2",
messages=[{"role": "user", "content": "北京天气怎么样?"}],
tools=tools
)
message = response.choices[0].message
messages = [{"role": "user", "content": "北京天气怎么样?"}]
if message.tool_calls:
# 2. 执行函数
tool_call = message.tool_calls[0]
args = json.loads(tool_call.function.arguments)
result = get_weather(**args)
# 3. 将结果返回给 GPT
messages.append(message) # 助手的消息(包含 tool_calls)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result
})
# 4. 获取最终回复
final_response = client.chat.completions.create(
model="gpt-5.2",
messages=messages,
tools=tools
)
print(final_response.choices[0].message.content)
# 输出: 北京今天天气晴朗,气温为 25°C,适合户外活动。
多函数定义
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市"}
},
"required": ["city"]
}
}
},
{
"type": "function",
"function": {
"name": "search_restaurants",
"description": "搜索餐厅",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "位置"},
"cuisine": {"type": "string", "description": "菜系"},
"price_range": {
"type": "string",
"enum": ["cheap", "moderate", "expensive"]
}
},
"required": ["location"]
}
}
},
{
"type": "function",
"function": {
"name": "book_restaurant",
"description": "预订餐厅",
"parameters": {
"type": "object",
"properties": {
"restaurant_id": {"type": "string"},
"date": {"type": "string", "description": "日期 YYYY-MM-DD"},
"time": {"type": "string", "description": "时间 HH:MM"},
"party_size": {"type": "integer", "description": "人数"}
},
"required": ["restaurant_id", "date", "time", "party_size"]
}
}
}
]
并行函数调用
GPT 可以同时调用多个函数:
response = client.chat.completions.create(
model="gpt-5.2",
messages=[
{"role": "user", "content": "北京和上海的天气分别怎么样?"}
],
tools=tools
)
message = response.choices[0].message
# 可能返回多个 tool_calls
for tool_call in message.tool_calls:
print(f"调用: {tool_call.function.name}")
print(f"参数: {tool_call.function.arguments}")
# 输出:
# 调用: get_weather, 参数: {"city": "北京"}
# 调用: get_weather, 参数: {"city": "上海"}
处理并行调用
def process_tool_calls(message, available_functions):
"""处理所有函数调用"""
results = []
for tool_call in message.tool_calls:
func_name = tool_call.function.name
func_args = json.loads(tool_call.function.arguments)
# 调用对应函数
if func_name in available_functions:
result = available_functions[func_name](**func_args)
results.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": str(result)
})
return results
# 定义可用函数
available_functions = {
"get_weather": get_weather,
"search_restaurants": search_restaurants,
"book_restaurant": book_restaurant
}
# 处理调用
tool_results = process_tool_calls(message, available_functions)
强制函数调用
# 自动决定(默认)
tool_choice = "auto"
# 强制调用特定函数
tool_choice = {"type": "function", "function": {"name": "get_weather"}}
# 禁止函数调用
tool_choice = "none"
# 必须调用某个函数(任意一个)
tool_choice = "required"
response = client.chat.completions.create(
model="gpt-5.2",
messages=[...],
tools=tools,
tool_choice=tool_choice
)
常见误区
- 函数 schema 定义太松,导致模型给出不可执行参数
- 工具执行失败后不回传错误上下文,模型无法自我修正
- 忽略幂等和权限校验,线上容易出现重复调用或越权操作
一句轻松提醒:
Function Calling 像“让 AI 当调度员”,不是“把系统控制权全部交出去”。
完整示例:AI 助手
from openai import OpenAI
import json
client = OpenAI()
# 模拟函数实现
def get_weather(city: str) -> str:
weather_data = {
"北京": "晴,25°C",
"上海": "多云,28°C",
"深圳": "阵雨,30°C"
}
return weather_data.get(city, f"{city}天气数据暂不可用")
def search_web(query: str) -> str:
return f"搜索结果: 关于'{query}'的相关信息..."
def calculate(expression: str) -> str:
try:
result = eval(expression) # 注意:生产环境需要安全处理
return str(result)
except:
return "计算错误"
# 工具定义
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取城市天气",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "城市名"}
},
"required": ["city"]
}
}
},
{
"type": "function",
"function": {
"name": "search_web",
"description": "搜索网络信息",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "搜索关键词"}
},
"required": ["query"]
}
}
},
{
"type": "function",
"function": {
"name": "calculate",
"description": "数学计算",
"parameters": {
"type": "object",
"properties": {
"expression": {"type": "string", "description": "数学表达式"}
},
"required": ["expression"]
}
}
}
]
available_functions = {
"get_weather": get_weather,
"search_web": search_web,
"calculate": calculate
}
def chat(user_message: str):
messages = [{"role": "user", "content": user_message}]
while True:
response = client.chat.completions.create(
model="gpt-5.2",
messages=messages,
tools=tools
)
message = response.choices[0].message
# 如果没有函数调用,返回结果
if not message.tool_calls:
return message.content
# 处理函数调用
messages.append(message)
for tool_call in message.tool_calls:
func_name = tool_call.function.name
func_args = json.loads(tool_call.function.arguments)
print(f"[调用函数] {func_name}({func_args})")
result = available_functions[func_name](**func_args)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result
})
# 测试
print(chat("北京天气怎么样?"))
print(chat("123 * 456 等于多少?"))
print(chat("帮我搜索一下 Python 最新版本"))
最佳实践
1. 清晰的函数描述
# ❌ 不够清晰
"description": "获取数据"
# ✅ 清晰明确
"description": "获取指定城市的实时天气信息,包括温度、湿度和天气状况"
2. 完整的参数说明
"parameters": {
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "日期,格式为 YYYY-MM-DD,如 2024-01-15"
}
}
}
3. 使用枚举限制选项
"status": {
"type": "string",
"enum": ["pending", "approved", "rejected"],
"description": "状态"
}
4. 安全处理用户输入
def safe_calculate(expression: str) -> str:
"""安全的计算函数"""
# 只允许数字和基本运算符
allowed = set('0123456789+-*/(). ')
if not all(c in allowed for c in expression):
return "不支持的表达式"
try:
return str(eval(expression))
except:
return "计算错误"
下一步
- Embeddings - 文本向量化
- Vision - 图像理解
- Assistants API - 构建 AI 助手
提示:Function Calling 是构建 AI Agent 的基础,掌握它可以让 AI 与外部世界交互。