Back to Blog

OpenAI Function Calling 实战指南:API 调用、参数校验与常见坑

2026/9/62 min read

OpenAI Function Calling 实战指南:API 调用、参数校验与常见坑

OpenAI 的 Function Calling 让模型能输出结构化 JSON,调用外部工具。你得先告诉它有哪些函数可用,它会返回 tool_calls,你来解析、执行、再把结果喂回去。比纯 prompt 稳定,调试也方便,现在做 Agent 基本都绕不开。

什么是 Function Calling

它不光说人话,还会“点菜”——选函数、填参数。我把它当个带脑子的中转站:用户一问,它判断该找谁干活,再把单子递过去。

常见用法有三类:

  • 从聊天里抠出订单号、日期这种硬信息
  • 真去查数据库、发邮件、调 API
  • 把一个大任务拆成几步,让它自己排顺序

如何定义函数 Schema

工具描述必须写进请求里,格式是 JSON Schema。别怕麻烦,参数写模糊了,模型就容易乱传。比如字符串就标 string,枚举值列清楚,可选字段一定加 "optional": true(虽然 schema 本身没这字段,但得靠 description 或 required 字段体现)。

下面是个天气查询的例子:

import openai

client = openai.OpenAI()

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取指定城市的当前天气情况",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市名称,例如:北京、上海"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "温度单位"
                    }
                },
                "required": ["location"]
            }
        }
    }
]

messages = [{"role": "user", "content": "北京今天天气怎么样?"}]

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=messages,
    tools=tools,
    tool_choice="auto"
)

解析 tool_calls 并执行函数

模型回的 message 里如果有 tool_calls,就说明它想调函数。你得手动取出来,解析参数,跑逻辑,再把结果塞进新消息里,角色设为 tool

# 模拟执行函数
import json

def execute_tool(name, arguments):
    if name == "get_weather":
        # 这里替换为真实的 API 调用
        return {"temperature": 25, "condition": "晴朗"}
    return None

# 处理模型响应
if response.choices[0].message.tool_calls:
    for tool_call in response.choices[0].message.tool_calls:
        args = json.loads(tool_call.function.arguments)
        result = execute_tool(tool_call.function.name, args)
        
        messages.append(response.choices[0].message)  # 添加助手的消息(包含 tool_calls)
        messages.append({
            "role": "tool",
            "tool_call_id": tool_call.id,
            "content": json.dumps(result)
        })

# 再次请求模型生成最终回答
final_response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=messages,
    tools=tools
)
print(final_response.choices[0].message.content)

常见错误与避坑指南

踩过几次坑,记下来提醒自己:

  • 参数类型对不上。模型爱把数字吐成字符串,比如 "temperature": "25"。我一般接完立刻 int()float() 强转,或者加一层校验。
  • 函数名大小写或下划线错一位,getWeatherget_weather 就是两个世界。执行前先 in 一下字典键。
  • 工具挂了,返回空或格式错,模型可能原地重试。我加了个计数器,超过两轮直接切到 fallback 流程。
  • 对话越聊越长,tool 类型消息堆一堆,token 快爆了。现在默认截掉最早的三条历史,留着最近的就行。

进阶:并行函数调用

模型真能一次点好几个菜。tool_calls 是个 list,你遍历执行,攒齐所有结果,再一起喂回去。不用等一个跑完再跑下一个,省时间。

下一步建议

tool_choice 的几个选项值得试试:"none" 强制不调用,"required" 必须调一个,还能直接写死 "get_weather"。另外官方文档里那个多轮天气+航班组合查询的 demo,跑一遍就懂怎么串链路了。

相关阅读

原文出处

本文首发于 OpenAI Function Calling 实战指南:API 调用、参数校验与常见坑https://lyxq.com.cn/en/blog/openai-function-calling-guide

转载或引用请注明出处,商业使用请联系作者获得授权。