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

在不断演进的人工智能(AI)领域,OpenAI 的 函数调用(现在通过 tools 暴露)已成为真实应用中最重要的积木之一。它可以把 gpt-4.1、gpt-4.1-mini 等强大的大模型,与自己的 API、数据库以及业务逻辑连接起来。
与其让模型“写一段 JSON”然后祈祷它能按照你的格式来,不如直接 用 JSON Schema 描述函数,模型会返回一个 结构化 的函数调用,你就可以在代码中安全执行。
本文中你将学习:
- OpenAI 函数调用是什么、在如今 API 中是如何工作的
- 如何使用 JSON Schema 定义 tools/函数
- 实战示例:安排会议、查询股票、预订旅行
- 如何利用 Structured Outputs 等新特性,让函数调用更可靠
- 设计最佳实践、常见陷阱及常见问题解答
什么是 OpenAI 函数调用(Tools)?
函数调用允许模型返回 机器可读的函数调用,而不是纯文本。在最新的 API 中,这些以 tools 的形式表示:
- 你通过以下字段定义 tools:
type: "function"function.name,function.descriptionfunction.parameters(用 JSON Schema 描述参数)
- 你在请求中随 prompt 一起发送这些 tools。
- 模型会决定是否调用某个 tool,并返回带有函数名和 JSON 参数的 tool call。
- 你的应用将会:
- 解析 tool 调用,
- 在后端执行相应的函数,
- (可选)把执行结果发回给模型,用于生成最终面向用户的回答。
在底层,函数调用被以下接口支持:
- Responses API(
POST /v1/responses)——推荐新应用优先使用。 - 经典的 Chat Completions API(
POST /v1/chat/completions)——目前仍然广泛使用并被支持。
历史上,函数调用是通过 functions 和 function_call 参数实现的。现在这些参数已经 弃用,推荐全部改用 tools 和 tool_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\"}"
}
}然后你可以:
- 调用你自己的股票价格 API;
- 在后续请求中把结果返回给模型;
- 让模型生成一段面向用户的自然语言说明。
示例:使用函数调用进行旅行预订
当用户的自然语言很随意甚至“凌乱”,但你的后端需要 干净、结构化的参数 时,函数调用就能发挥威力。
例如这句话:
“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.”
我们希望模型提取出:
departuredestinationnumber_peopletravel_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_profileget_user_orderscreate_support_ticketschedule_meeting
这会让 Schema 更易维护,也更有利于模型选择正确的 tool。
2. 使用清晰的名称和描述
- 函数名最好是动词短语:
create_invoice、fetch_weather、book_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. 需要时进行工具链式调用
对于复杂工作流(如:先查用户 → 再查订单 → 再总结),你可以:
- 让模型在同一次响应中调用多个 tools(并行 tool 调用),或
- 在后端按步骤编排:把前一步的执行结果重新发给模型,让模型决定下一步调用哪个 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)
工作流可能是这样:
- 模型调用
add_decimal,参数{ "a": 22, "b": 5 }→ 你的代码返回27。 - 你把这个结果和原始问题一起再发给模型。
- 模型再调用
add_hex,参数{ "a": "27", "b": "A" }。 - 你的代码返回
31,模型则对最终结果做解释并返回给用户。
这个模式可以推广到 任何领域:金融、分析、数据可视化、DevOps、BI 仪表盘等等。函数调用 + 你自己的 tools = 一个灵活且具备领域知识的 AI 助手。
想用 ChatGPT 的能力轻松生成各种图表? 试试 VizGPT (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)
-
什么是 OpenAI 的函数调用功能?
函数调用允许你用 JSON Schema 描述函数(tools),从而让模型返回结构化的函数调用,而不是纯文本。模型本身并不会执行任何操作;你的应用负责解析 tool 调用并执行实际函数。
-
哪些模型支持函数调用?
现代的 GPT-4、GPT-4.1、GPT-4o、GPT-4o-mini,以及更新的 GPT-5 / o 系列模型,都通过 Chat Completions 和 Responses API 支持 tools/函数调用。具体支持列表请查阅 OpenAI 最新文档。
-
还应该使用旧的
functions/function_call参数吗?不推荐。那是第一代函数调用接口,现在已被视为旧版。新的代码应使用
tools和tool_choice,它们更灵活,并适配新的模型和 API。 -
这和 JSON Mode 或 Structured Outputs 有什么不同?
- JSON Mode(
response_format: { "type": "json_object" })只保证输出是合法 JSON,但不强制遵守你的 Schema。 - 函数调用 + Structured Outputs(在 tool 定义中使用
strict: true)会强制模型返回的参数符合你提供的 JSON Schema。 - 你也可以将函数调用与 JSON Mode 结合使用,以获得更精细的控制。
- JSON Mode(
-
常见的应用场景有哪些?
- 能调用外部 API 的聊天机器人(天气、CRM、工单系统、内部工具等)
- 自然语言 → API 调用、SQL 查询、搜索过滤条件
- 从非结构化文本中提取结构化记录的数据抽取流水线
- 用于自动化、分析和 BI 的多步骤 “agent” 工作流

