0Pricing
AI Engineering Academy · 课时

为 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 反馈 — 无需本地设置。

此课程中的所有课时

  1. 为 API 定义函数模式
  2. 在应用中处理工具调用
  3. 并行调用函数
  4. 构建自然语言数据库接口
← 返回 AI Engineering Academy