为 API 定义函数模式
为函数编写 JSON Schema 定义,将其传入 tools 参数,并了解模型如何决定何时以及如何调用这些函数。
为 API 定义函数模式 是 CoddyKit 上的免费 AI Engineering Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Engineering Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Engineering Academy 课程共包含 4 节课。
什么是函数调用?
OpenAI 的函数调用(现在称为工具调用)允许您以结构化 JSON Schema 格式向模型描述 Python 函数。当模型判断应调用某个函数时,它不会生成自由文本,而是返回一个包含函数名称和参数的结构化 JSON 对象,然后由您的代码可靠地执行该函数。
tools 参数结构
您需要将函数定义作为对象列表,通过 API 的 tools 参数传入。每个对象的 type 都是 'function',并包含一个 function 键,其中定义了名称、描述和用于定义参数的 JSON Schema。
from openai import OpenAI
client = OpenAI()
tools = [
{
'type': 'function',
'function': {
'name': 'get_current_weather',
'description': 'Get the current weather in a given location.',
'parameters': {
'type': 'object',
'properties': {
'location': {
'type': 'string',
'description': 'City and country, e.g. London, UK'
},
'unit': {
'type': 'string',
'enum': ['celsius', 'fahrenheit'],
'description': 'Temperature unit to use.'
}
},
'required': ['location']
}
}
}
]参数的 JSON Schema
parameters 字段遵循 JSON Schema 规范。使用 type 指定字符串、数字、整数、布尔值、数组或对象。为每个属性使用 description 告诉模型该字段的含义。在 required 数组中列出必填字段,可选字段则无需放入 required。
# A more complex schema with multiple types
create_event_tool = {
'type': 'function',
'function': {
'name': 'create_calendar_event',
'description': 'Create a new calendar event. Use when the user wants to schedule a meeting or appointment.',
'parameters': {
'type': 'object',
'properties': {
'title': {'type': 'string', 'description': 'Event title.'},
'start_time': {'type': 'string', 'description': 'ISO 8601 datetime, e.g. 2024-03-15T14:00:00.'},
'duration_minutes': {'type': 'integer', 'description': 'Duration in minutes.', 'minimum': 5},
'attendees': {
'type': 'array',
'items': {'type': 'string'},
'description': 'List of email addresses of attendees.'
},
'location': {'type': 'string', 'description': 'Physical or virtual meeting location.'}
},
'required': ['title', 'start_time', 'duration_minutes']
}
}
}使用工具发起 API 调用
将 tools 列表直接传递给 chat.completions.create。模型可能返回常规文本消息(如果无需调用函数即可回答),也可能返回指示您执行函数的 tool_calls 对象。请始终检查 finish_reason,以确定当前属于哪种情况。
response = client.chat.completions.create(
model='gpt-4o',
messages=[
{'role': 'user', 'content': 'What is the weather in Tokyo?'}
],
tools=tools
)
print('Finish reason:', response.choices[0].finish_reason)
# 'tool_calls' means the model wants to call a function
# 'stop' means the model gave a regular text response
choice = response.choices[0].message
if response.choices[0].finish_reason == 'tool_calls':
print('Model wants to call:', choice.tool_calls[0].function.name)使用 tool_choice 控制工具选择
tool_choice 参数控制模型是否必须调用函数,还是可以自由选择。将其设置为 'auto' 可让模型自行决定。设置为 'required' 会强制进行工具调用。将其设置为特定的函数名称,则会强制调用该函数——这对于始终需要结构化输出的数据提取任务非常有用。
# Force the model to always call extract_contact
response = client.chat.completions.create(
model='gpt-4o',
messages=[{'role': 'user', 'content': 'Hi, I am John Smith, john@example.com, +1-555-0100.'}],
tools=[extract_contact_tool],
tool_choice={'type': 'function', 'function': {'name': 'extract_contact'}}
)
# With tool_choice forced, finish_reason will always be 'tool_calls'用于限制选项的枚举字段
只要某个参数应限制为一组固定值,就请在 JSON Schema 中使用 enum 字段。这样可以显著提高可靠性:模型能够看到架构中列出的确切允许值,因此不太可能臆造出无效选项。
classify_sentiment_tool = {
'type': 'function',
'function': {
'name': 'classify_sentiment',
'description': 'Classify the sentiment of a customer review.',
'parameters': {
'type': 'object',
'properties': {
'sentiment': {
'type': 'string',
'enum': ['positive', 'negative', 'neutral', 'mixed'],
'description': 'The sentiment classification.'
},
'confidence': {
'type': 'number',
'minimum': 0.0,
'maximum': 1.0,
'description': 'Model confidence from 0 to 1.'
}
},
'required': ['sentiment', 'confidence']
}
}
}嵌套对象架构
JSON Schema 支持嵌套对象。请使用 'type': 'object',并为其定义独立的 properties,以表示复杂的层次化数据结构。这非常适合从电子邮件或文档等非结构化文本中提取结构化数据。
extract_order_tool = {
'type': 'function',
'function': {
'name': 'extract_order',
'description': 'Extract order details from a customer email.',
'parameters': {
'type': 'object',
'properties': {
'customer': {
'type': 'object',
'properties': {
'name': {'type': 'string'},
'email': {'type': 'string', 'format': 'email'}
},
'required': ['name']
},
'items': {
'type': 'array',
'items': {
'type': 'object',
'properties': {
'product_id': {'type': 'string'},
'quantity': {'type': 'integer', 'minimum': 1}
},
'required': ['product_id', 'quantity']
}
}
},
'required': ['customer', 'items']
}
}
}从 Pydantic 模型生成架构
手动编写 JSON Schema 既繁琐又容易出错。您可以改为将数据结构定义为 Pydantic 模型,然后使用 .schema() 自动生成 JSON Schema。将模型响应反序列化时,这还会为您提供 Python 层面的验证。
from pydantic import BaseModel, Field
from typing import Optional, List
class ContactInfo(BaseModel):
name: str = Field(description='Full name of the person.')
email: Optional[str] = Field(None, description='Email address.')
phone: Optional[str] = Field(None, description='Phone number in E.164 format.')
company: Optional[str] = Field(None, description='Company or organization.')
# Auto-generate the JSON Schema
schema = ContactInfo.schema()
# Build the tool definition
extract_contact_tool = {
'type': 'function',
'function': {
'name': 'extract_contact',
'description': 'Extract contact information from text.',
'parameters': schema
}
}编写有效的函数描述
函数描述是模型用来决定何时调用工具的关键信号。优秀的描述会明确说明使用场景,指出何时应调用和不应调用该函数,并说明输出内容。含糊的描述会导致模型调用错误的函数,或错过调用正确函数的机会。
- 含糊:'获取天气数据。'
- 良好:'获取指定城市当前的天气状况。用户明确询问某个指定地点的天气时使用。返回温度、天气状况和湿度。'
确保遵循架构的严格模式
OpenAI 针对结构化输出提供的严格模式可确保模型生成的 JSON 与您的架构完全匹配——不会包含额外字段,也不会缺少必填字段。请在函数定义中设置 'strict': true 来启用该模式。注意:严格模式要求所有架构对象都包含 additionalProperties: false。
strict_tool = {
'type': 'function',
'function': {
'name': 'classify_ticket',
'description': 'Classify a support ticket into category and priority.',
'strict': True, # Enable strict schema adherence
'parameters': {
'type': 'object',
'additionalProperties': False, # Required for strict mode
'properties': {
'category': {
'type': 'string',
'enum': ['billing', 'technical', 'account', 'other']
},
'priority': {
'type': 'string',
'enum': ['low', 'medium', 'high', 'urgent']
}
},
'required': ['category', 'priority']
}
}
}测试函数架构
在部署之前,请使用多样化的输入测试每个函数架构:正常情况、边界情况和对抗性输入。请验证模型是否调用了正确的函数、是否生成了有效的参数类型、是否正确处理可选字段,以及是否遵守枚举约束。您可以先使用 OpenAI Playground 快速迭代,再编写生产代码。
快速检查
测试您对为 OpenAI API 定义函数架构的理解。
课程回顾
在本课中,您学习了:函数架构使用 JSON Schema 定义参数类型、描述和约束;tool_choice 控制模型是否必须调用函数,或允许模型自由选择;以及 Pydantic 模型可以自动生成 JSON Schema,从而减少手动编写架构的工作量。接下来,我们将学习如何在应用程序中检测、执行工具调用并发送回结果。
常见问题解答
「为 API 定义函数模式」课时是免费的吗?
是的 — 「为 API 定义函数模式」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Engineering Academy 课程的其余内容,请升级到 CoddyKit PRO。 AI Engineering Academy 课程共包含 4 节课。
「为 API 定义函数模式」这节课中我会学到什么?
为函数编写 JSON Schema 定义,将其传入 tools 参数,并了解模型如何决定何时以及如何调用这些函数。 你通过在浏览器中直接运行的动手代码来练习 AI Engineering Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 AI Engineering Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 AI Engineering Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「为 API 定义函数模式」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 AI Engineering Academy 课中编写并运行代码吗?
能。每节 AI Engineering Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 为 API 定义函数模式
- 在应用中处理工具调用
- 并行调用函数
- 构建自然语言数据库接口