Skip to content
OpenAI 函数调用:上手示例大全

OpenAI 函数调用:上手示例大全

Updated on

了解现代 OpenAI 函数调用在 tools、JSON Schema 和 Structured Outputs 下的工作方式。包含 Python 和 JavaScript 的实用示例:安排会议、获取股票价格、预订行程。

在不断演进的人工智能(AI)领域,OpenAI 的 函数调用(现在通过 tools 暴露)已成为真实应用中最重要的积木之一。它可以把 gpt-4.1gpt-4.1-mini 等强大的大模型,与自己的 API、数据库以及业务逻辑连接起来。

与其让模型“写一段 JSON”然后祈祷它能按照你的格式来,不如直接 用 JSON Schema 描述函数,模型会返回一个 结构化 的函数调用,你就可以在代码中安全执行。

本文中你将学习:

  • OpenAI 函数调用是什么、在如今 API 中是如何工作的
  • 如何使用 JSON Schema 定义 tools/函数
  • 实战示例:安排会议、查询股票、预订旅行
  • 如何利用 Structured Outputs 等新特性,让函数调用更可靠
  • 设计最佳实践、常见陷阱及常见问题解答
📚

什么是 OpenAI 函数调用(Tools)?

函数调用允许模型返回 机器可读的函数调用,而不是纯文本。在最新的 API 中,这些以 tools 的形式表示:

  • 你通过以下字段定义 tools:
    • type: "function"
    • function.name, function.description
    • function.parameters(用 JSON Schema 描述参数)
  • 你在请求中随 prompt 一起发送这些 tools。
  • 模型会决定是否调用某个 tool,并返回带有函数名和 JSON 参数的 tool call
  • 你的应用将会:
    1. 解析 tool 调用,
    2. 在后端执行相应的函数,
    3. (可选)把执行结果发回给模型,用于生成最终面向用户的回答。

在底层,函数调用被以下接口支持:

  • Responses APIPOST /v1/responses)——推荐新应用优先使用。
  • 经典的 Chat Completions APIPOST /v1/chat/completions)——目前仍然广泛使用并被支持。

历史上,函数调用是通过 functionsfunction_call 参数实现的。现在这些参数已经 弃用,推荐全部改用 toolstool_choice 的新风格来写新代码。


基础示例:安排会议(Chat Completions API)

先看一个简单例子,使用 Chat Completions API。我们让模型安排一次会议,并让它返回 schedule_meeting 函数所需的结构化参数。

JSON 请求(概念示例)

{
    "model": "gpt-4.1-mini",
    "messages": [
        {
            "role": "user",
            "content": "Schedule a meeting with John Doe next Tuesday at 3 PM."
        }
    ],
    "tools": [
        {
            "type": "function",
            "function": {
                "name": "schedule_meeting",
                "description": "Schedule a meeting in the calendar.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "attendee": {
                            "type": "string",
                            "description": "Name of the attendee for the meeting."
                        },
                        "date": {
                            "type": "string",
                            "description": "Date of the meeting in ISO 8601 format."
                        },
                        "time": {
                            "type": "string",
                            "description": "Time of the meeting, including time zone."
                        }
                    },
                    "required": ["attendee", "date", "time"],
                    "additionalProperties": false
                },
                "strict": true
            }
        }
    ],
    "tool_choice": "auto"
}

模型的回复会包含类似下面这样的内容:

{
    "role": "assistant",
    "tool_calls": [
        {
            "id": "call_123",
            "type": "function",
            "function": {
                "name": "schedule_meeting",
                "arguments": "{\"attendee\":\"John Doe\",\"date\":\"2025-11-18\",\"time\":\"15:00 Europe/Berlin\"}"
            }
        }
    ]
}

你的后端可以解析 arguments,调用真正的 schedule_meeting 函数(比如集成 Google Calendar 或 Outlook),然后(可选)将结果再发给模型,生成一段更友好的确认消息返回给用户。


示例:股票价格查询

下面是一个更“API 风格”的例子:根据自然语言调用 get_stock_price 函数。

get_stock_price tool 的请求

{
    "model": "gpt-4.1-mini",
    "messages": [
        {
            "role": "user",
            "content": "What's the current price of Apple stock?"
        }
    ],
    "tools": [
        {
            "type": "function",
            "function": {
                "name": "get_stock_price",
                "description": "Get the current stock price for a ticker symbol.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "ticker_symbol": {
                            "type": "string",
                            "description": "Ticker symbol of the stock, e.g. AAPL."
                        },
                        "currency": {
                            "type": "string",
                            "enum": ["USD", "EUR", "GBP"],
                            "description": "Currency for the price."
                        }
                    },
                    "required": ["ticker_symbol"],
                    "additionalProperties": false
                },
                "strict": true
            }
        }
    ],
    "tool_choice": "auto"
}

当用户问 “What's the current price of Apple stock?” 时,模型可能会生成类似的 tool 调用:

{
    "type": "function",
    "function": {
        "name": "get_stock_price",
        "arguments": "{\"ticker_symbol\":\"AAPL\",\"currency\":\"USD\"}"
    }
}

然后你可以:

  1. 调用你自己的股票价格 API;
  2. 在后续请求中把结果返回给模型;
  3. 让模型生成一段面向用户的自然语言说明。

示例:使用函数调用进行旅行预订

当用户的自然语言很随意甚至“凌乱”,但你的后端需要 干净、结构化的参数 时,函数调用就能发挥威力。

例如这句话:

“I need to book a trip from Bonn to Amsterdam for my wife, mother, my two sons, my daughter, and me. The airline must fly direct.”

我们希望模型提取出:

  • departure
  • destination
  • number_people
  • travel_mode(例如 plane / train)

book_travel tool 定义

{
    "model": "gpt-4.1-mini",
    "messages": [
        {
            "role": "user",
            "content": "I need to book a trip from Bonn to Amsterdam for my wife, mother, my two sons and daughter, and me. The airline must fly direct."
        }
    ],
    "tools": [
        {
            "type": "function",
            "function": {
                "name": "book_travel",
                "description": "Search or book transportation for a group of travelers.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "departure": {
                            "type": "string",
                            "description": "City or airport you are traveling from."
                        },
                        "destination": {
                            "type": "string",
                            "description": "City or airport you are traveling to."
                        },
                        "number_people": {
                            "type": "integer",
                            "description": "How many people are traveling."
                        },
                        "travel_mode": {
                            "type": "string",
                            "enum": ["plane", "train", "bus", "car"],
                            "description": "Preferred mode of travel."
                        },
                        "non_stop_only": {
                            "type": "boolean",
                            "description": "Whether only non-stop options are allowed."
                        }
                    },
                    "required": ["departure", "destination", "number_people"],
                    "additionalProperties": false
                },
                "strict": true
            }
        }
    ],
    "tool_choice": "auto"
}

模型可能会输出:

{
    "name": "book_travel",
    "arguments": "{\"departure\":\"Bonn\",\"destination\":\"Amsterdam\",\"number_people\":6,\"travel_mode\":\"plane\",\"non_stop_only\":true}"
}

然后你可以把这些参数直接交给机票/行程搜索服务来使用。


使用现代 OpenAI SDK(Python & JavaScript)

通常你不会手写这些原始 JSON,而是使用官方 SDK,并获得更强类型的返回值。

Python 示例(Chat Completions + tools)

from openai import OpenAI
 
client = OpenAI()
 
tools = [
    {
        "type": "function",
        "function": {
            "name": "schedule_meeting",
            "description": "Schedule a meeting in the calendar.",
            "parameters": {
                "type": "object",
                "properties": {
                    "attendee": {"type": "string"},
                    "date": {"type": "string"},
                    "time": {"type": "string"},
                },
                "required": ["attendee", "date", "time"],
                "additionalProperties": False,
            },
            "strict": True,
        },
    }
]
 
completion = client.chat.completions.create(
    model="gpt-4.1-mini",
    messages=[
        {
            "role": "user",
            "content": "Schedule a meeting with John Doe next Tuesday at 3 PM.",
        }
    ],
    tools=tools,
    tool_choice="auto",
)
 
tool_calls = completion.choices[0].message.tool_calls
if tool_calls:
    call = tool_calls[0]
    args = client.responses._client._utils.json.loads(call.function.arguments)
    # Your real implementation:
    # result = schedule_meeting(**args)

JavaScript 示例(Node.js)

import OpenAI from "openai";
 
const client = new OpenAI();
 
const tools = [
    {
        type: "function",
        function: {
            name: "get_stock_price",
            description: "Get the current price for a given ticker symbol.",
            parameters: {
                type: "object",
                properties: {
                    ticker_symbol: {
                        type: "string",
                        description: "Stock ticker symbol, e.g. AAPL",
                    },
                },
                required: ["ticker_symbol"],
                additionalProperties: false,
            },
            strict: true,
        },
    },
];
 
const response = await client.chat.completions.create({
    model: "gpt-4.1-mini",
    messages: [
        { role: "user", content: "What's the current price of Apple stock?" },
    ],
    tools,
    tool_choice: "auto",
});
 
const toolCalls = response.choices[0].message.tool_calls;

Structured Outputs:让函数调用更加可靠

JSON Mode 能保证模型返回的是合法 JSON,但并不保证这个 JSON 一定符合 你的 Schema。Structured Outputs 是一个更新的特性,它在模型调用 tools 时,进一步通过你的 JSON Schema 做约束:

  • 在 tool 的 function 定义中设置 "strict": true
  • 这样模型返回的参数就会被约束为符合你的 Schema(类型、必填字段、不能有多余字段),大幅减少解析和校验错误。

这尤其适用于下面这些场景:

  • 从非结构化文本中抽取复杂的嵌套结构数据
  • 搭建多步工作流,每一步都依赖于精确的结构化数据
  • 为下游系统(SQL、分析流水线、数据可视化等)生成可靠的参数

即使有 Structured Outputs,你仍然应该把这些值当作不可信输入来处理(例如检查数值范围、处理缺失 ID、验证业务规则等)。


设计模式与最佳实践

1. 让 tools 保持小而专注

不要写一个巨大的 do_everything 函数,而是定义 小而可组合的 tools,例如:

  • get_user_profile
  • get_user_orders
  • create_support_ticket
  • schedule_meeting

这会让 Schema 更易维护,也更有利于模型选择正确的 tool。

2. 使用清晰的名称和描述

  • 函数名最好是动词短语:create_invoicefetch_weatherbook_travel
  • 描述中要体现 在什么情况下 使用该函数,而不仅仅是它做什么。

不佳示例:

“Get data from the system.”

更好示例:

“Use this function whenever the user asks about their recent orders or order history.”

3. 使用严格的 Schema

  • required 指定必填字段,并设置 additionalProperties: false
  • 对有限集合的选项使用 enum("enum": ["plane", "train"])。
  • 适当地添加简单限制(字符串格式、整数最小值等)。

4. 校验并记录一切

  • 在执行任何函数之前,务必在服务端验证 tool 参数。
  • 记录 tool 调用和自然语言 prompt 以便调试。
  • 当校验失败时,可以考虑重试(配合简短的系统提示,纠正模型)。

5. 需要时进行工具链式调用

对于复杂工作流(如:先查用户 → 再查订单 → 再总结),你可以:

  1. 让模型在同一次响应中调用多个 tools(并行 tool 调用),或
  2. 在后端按步骤编排:把前一步的执行结果重新发给模型,让模型决定下一步调用哪个 tool。

具体多步示例:混合进制的数学问题

再看一个经典例子,说明函数调用为何不只是“玩具”功能。

“What’s the result of 22 plus 5 in decimal added to the hexadecimal number A?”

我们可以定义两个工具来解决:

  • add_decimal(a: number, b: number)
  • add_hex(a: string, b: string)

工作流可能是这样:

  1. 模型调用 add_decimal,参数 { "a": 22, "b": 5 } → 你的代码返回 27
  2. 你把这个结果和原始问题一起再发给模型。
  3. 模型再调用 add_hex,参数 { "a": "27", "b": "A" }
  4. 你的代码返回 31,模型则对最终结果做解释并返回给用户。

这个模式可以推广到 任何领域:金融、分析、数据可视化、DevOps、BI 仪表盘等等。函数调用 + 你自己的 tools = 一个灵活且具备领域知识的 AI 助手。


想用 ChatGPT 的能力轻松生成各种图表? 试试 VizGPT (opens in a new tab) ——用自然语言描述数据和图表需求,即可零代码生成精美可视化。

How to Create Charts with VizGPT (opens in a new tab)

VizGPT: Create Charts with the Power of ChatGPT (opens in a new tab)


相关 OpenAI 更新概览

围绕函数调用与 tools,OpenAI 持续在以下方面迭代:

  • 现代模型的 更大上下文窗口,更方便处理长对话、长文档以及复杂 Schema。
  • Structured Outputs,无论用于 tools 还是 response format,都能确保输出遵循你的 JSON Schema。
  • 更丰富的 Responses API 与 tools 生态(web search、file search、code execution 等),使得构建完整的 agentic 工作流更加容易,同时保留统一的函数调用概念。

关于价格和最新模型列表,请以 OpenAI 官方文档和定价页面为准。


总结

函数调用是让大模型真正成为 可落地、可集成的基础设施 的关键方式之一:

  • 你用 JSON Schema 声明函数能做什么;
  • 模型决定 何时 调用、以及 如何 填写参数;
  • 你的后端执行这些调用,并和模型一起,为用户构建丰富的交互体验。

无论是安排会议、查询股票、预订行程,还是用 PyGWalker、VizGPT 等 tools 搭建完整 BI 仪表盘,函数调用都是衔接自然语言与真实操作之间的“胶水”。

可以先从一个简单函数开始,做好验证与日志记录,然后随着应用成熟,逐步演进到多步骤的 agentic 工作流。


常见问题(FAQ)

  1. 什么是 OpenAI 的函数调用功能?

    函数调用允许你用 JSON Schema 描述函数(tools),从而让模型返回结构化的函数调用,而不是纯文本。模型本身并不会执行任何操作;你的应用负责解析 tool 调用并执行实际函数。

  2. 哪些模型支持函数调用?

    现代的 GPT-4、GPT-4.1、GPT-4o、GPT-4o-mini,以及更新的 GPT-5 / o 系列模型,都通过 Chat Completions 和 Responses API 支持 tools/函数调用。具体支持列表请查阅 OpenAI 最新文档。

  3. 还应该使用旧的 functions / function_call 参数吗?

    不推荐。那是第一代函数调用接口,现在已被视为旧版。新的代码应使用 toolstool_choice,它们更灵活,并适配新的模型和 API。

  4. 这和 JSON Mode 或 Structured Outputs 有什么不同?

    • JSON Moderesponse_format: { "type": "json_object" })只保证输出是合法 JSON,但不强制遵守你的 Schema。
    • 函数调用 + Structured Outputs(在 tool 定义中使用 strict: true)会强制模型返回的参数符合你提供的 JSON Schema。
    • 你也可以将函数调用与 JSON Mode 结合使用,以获得更精细的控制。
  5. 常见的应用场景有哪些?

    • 能调用外部 API 的聊天机器人(天气、CRM、工单系统、内部工具等)
    • 自然语言 → API 调用、SQL 查询、搜索过滤条件
    • 从非结构化文本中提取结构化记录的数据抽取流水线
    • 用于自动化、分析和 BI 的多步骤 “agent” 工作流
📚