OpenAI函数调用(Function Calling)机制的原理与实践详解
OpenAI函数调用(Function Calling)机制的原理与实践详解
·
OpenAI函数调用(Function Calling)机制的原理与实践详解
1. 概述
OpenAI的函数调用(Function Calling)功能为大语言模型(LLM)提供了与外部代码和服务交互的能力,可以直接通过模型调用自定义函数以实现数据获取或触发实际动作。本文将介绍函数调用的实现原理、函数定义规范、关键参数配置、典型应用场景及完整的Python实现流程。
2. 技术原理
函数调用机制允许开发者通过函数描述(Schema)将自定义代码暴露给模型。模型根据系统提示与用户消息决定是否调用这些函数,开发者再根据返回的调用指令执行相应代码并将结果反馈给模型,模型据此生成最终回复。
函数调用的主要应用方向包括:
- 数据获取:如查询知识库、调用API获取实时数据(如天气、汇率等)。
- 动作执行:如表单提交、接口调用、UI状态变更、发送邮件等。
3. 函数定义与Schema结构
函数通过JSON Schema进行定义,主要包括:
type
:固定为function
name
:函数名称(如get_weather
)description
:函数用途说明parameters
:函数参数JSON Schema定义strict
:是否启用严格模式(true时约束更强)
示例:
# 定义get_weather函数的Schema(示例)
tools = [
{
"type": "function",
"name": "get_weather",
"description": "获取指定地点的当前天气信息。",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "城市和国家,例如:Bogot\u00e1, Colombia"
},
"units": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "返回温度的单位,可选值:celsius或fahrenheit"
}
},
"required": ["location", "units"],
"additionalProperties": False
},
"strict": True
}
]
4. 完整实践流程
4.1 定义业务函数
业务函数可调用外部API获取实际数据,如下为天气信息获取示例:
import requests
def get_weather(latitude, longitude):
"""
获取指定坐标(经纬度)的实时气温
:param latitude: 纬度(float)
:param longitude: 经度(float)
:return: 当前气温(摄氏度)
"""
url = f"https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}¤t=temperature_2m"
response = requests.get(url)
data = response.json()
return data["current"]["temperature_2m"]
注意:此实现要求已将地理位置(如“Paris, France”)转换为对应的经纬度。
4.2 向模型发送函数Schema及用户请求
from openai import OpenAI
import json
client = OpenAI()
tools = [
{
"type": "function",
"name": "get_weather",
"description": "根据经纬度返回当前温度(摄氏度)",
"parameters": {
"type": "object",
"properties": {
"latitude": {"type": "number"},
"longitude": {"type": "number"}
},
"required": ["latitude", "longitude"],
"additionalProperties": False,
},
"strict": True
}
]
input_messages = [
{"role": "user", "content": "What's the weather like in Paris today?"}
]
response = client.responses.create(
model="gpt-4.1",
input=input_messages,
tools=tools
)
4.3 解析模型函数调用并执行
# 假设模型输出如下:
# [
# {"type": "function_call", "id": "fc_12345xyz", "call_id": "call_12345xyz", "name": "get_weather", "arguments": "{\"latitude\":48.8566, \"longitude\":2.3522}"}
# ]
tool_call = response.output[0]
args = json.loads(tool_call["arguments"])
result = get_weather(args["latitude"], args["longitude"])
4.4 返回函数执行结果并获取最终回复
# 将函数调用信息与执行结果加入消息序列,提交给模型生成最终回复
input_messages.append(tool_call)
input_messages.append({
"type": "function_call_output",
"call_id": tool_call["call_id"],
"output": str(result)
})
response_2 = client.responses.create(
model="gpt-4.1",
input=input_messages,
tools=tools
)
print(response_2.output_text)
# 输出示例:The current temperature in Paris is 14°C (57.2°F).
5. 多函数及批量调用场景
模型可能一次性调用多个函数,需遍历response.output批量执行,并用call_id关联返回。
def call_function(name, args):
if name == "get_weather":
return get_weather(**args)
# 可拓展其他函数
for tool_call in response.output:
if tool_call["type"] != "function_call":
continue
name = tool_call["name"]
args = json.loads(tool_call["arguments"])
result = call_function(name, args)
input_messages.append({
"type": "function_call_output",
"call_id": tool_call["call_id"],
"output": str(result)
})
6. 重要参数及附加配置
6.1 工具选择(tool_choice)
auto
(默认):模型自主决定调用零到多个函数。required
:要求必须调用一个或多个函数。- 指定函数:强制仅调用某个具体函数。
none
:不提供任何函数,模拟普通对话。
6.2 并行调用与严格模式
parallel_tool_calls
:为False时每次仅可调用一个函数。strict
:强烈建议开启,保证入参结构与Schema一致。
开启严格模式的Schema示例:
{
"type": "function",
"name": "get_weather",
"description": "检索指定地点当前天气。",
"strict": True,
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "城市+国家"},
"units": {"type": ["string", "null"], "enum": ["celsius", "fahrenheit"], "description": "温度单位"}
},
"required": ["location", "units"],
"additionalProperties": False
}
}
7. 流式响应与进度监听
通过stream=True
可实时获取模型函数调用及参数填充的进度事件,便于展现执行流。
流式监听代码示例:
from openai import OpenAI
client = OpenAI()
tools = [
{
"type": "function",
"name": "get_weather",
"description": "获取指定地点的当前天气。",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "城市和国家"}
},
"required": ["location"],
"additionalProperties": False
}
}
]
stream = client.responses.create(
model="gpt-4.1",
input=[{"role": "user", "content": "What's the weather like in Paris today?"}],
tools=tools,
stream=True
)
for event in stream:
print(event) # 可监听到参数填充与函数触发的过程
8. 函数定义与调用实践建议
- 明确函数名、参数说明和用途,详细描述每个参数的格式与场景。
- 使用合理的枚举与对象结构,避免无效调用。
- 保持函数数量精炼,通常建议不超过20个以保证准确率。
- 如需批量并行调用,需确保输出结构和call_id的唯一性。
9. Token消耗说明
函数定义(Schema)会占用模型上下文的Token额度,请合理控制函数数量和描述长度。如遇Token限制,可尝试优化Schema精简描述。
10. 总结
OpenAI函数调用机制极大拓展了大模型与实际业务系统的融合能力。通过规范的Schema定义与严格的入参约束,配合流程化的调用与结果反馈,能够满足丰富的业务场景需求。开发者可根据实际需求灵活配置参数,实现数据获取、动作执行、自动代理等多样化功能。
更多推荐
所有评论(0)