Structured Outputs
是一个功能,它确保模型始终生成符合您提供的 JSON Schema 的响应。这意味着您不需要担心模型会遗漏所需的键,或者生成无效的枚举值。
https://platform.openai.com/docs/guides/structured-outputs/
这个功能的一些好处包括:
可靠的类型安全性:不需要验证或重试格式不正确的响应。 明确的拒绝:基于安全的模型拒绝现在可以通过程序检测。 更简单的提示:不需要使用强烈措辞的提示来实现一致的格式化。
Structured Outputs 使用案例
from pydantic import BaseModel
from openai import OpenAI
client = OpenAI()
class CalendarEvent(BaseModel):
name: str
date: str
participants: list[str]
completion = client.beta.chat.completions.parse(
model="gpt-4o-2024-08-06",
messages=[
{"role": "system", "content": "Extract the event information."},
{"role": "user", "content": "Alice and Bob are going to a science fair on Friday."},
],
response_format=CalendarEvent,
)
event = completion.choices[0].message.parsed
Structured Outputs 功能在我们最新的大型语言模型中可用,从 GPT-4o 开始:
gpt-4o-mini-2024-07-18
及以后的版本gpt-4o-2024-08-06
及以后的版本
像 gpt-4-turbo
这样的旧版模型可能需要使用 JSON模式。
Structured Outputs
功能确保模型生成的响应始终符合您提供的 JSON Schema,从而避免了模型遗漏必需的键或生成无效的枚举值等问题。
Structured Outputs 是 JSON模式 的演进。我们建议在可能的情况下始终使用 Structured Outputs 而不是 JSON 模式。
然而,带有 response_format: {type: "json_schema", ...}
的 Structured Outputs 仅支持 gpt-4o-mini
、gpt-4o-mini-2024-07-18
和 gpt-4o-2024-08-06
模型快照及以后的版本。
Structured Outputs | JSON Mode | |
---|---|---|
输出有效 JSON | 是 | 是 |
遵守模式 | 是(参见支持的模式) | 否 |
兼容模型 | gpt-4o-mini 、gpt-4o-2024-08-06 及以后版本 | gpt-3.5-turbo 、gpt-4-* 和 gpt-4o-* 模型 |
启用方式 | response_format: { type: "json_schema", json_schema: {"strict": true, "schema": ...} } | response_format: { type: "json_object" } |
Structured Outputs两种形式
Structured Outputs 在 OpenAI API 中有两种形式:通过 函数调用 或通过 json_schema
响应格式。
函数调用 非常有用,当你构建一个应用程序,需要将模型和应用程序的功能桥接起来时。
例如,你可以让模型访问查询数据库的函数,以构建一个可以帮助用户处理订单的 AI 助手,或者与用户界面交互的函数。
相反,通过 response_format
的 Structured Outputs
更适合于当你想要指示模型在响应用户时使用的有结构的模式,而不是模型调用工具时。
简单来说:
如果你正在将模型连接到系统中的工具、函数、数据等,那么你应该使用函数调用。 如果你希望在模型响应用户时构建其输出的结构,那么你应该使用结构化的 response_format
。
使用案例
案例1:Structured Outputs 可以用于链式思考数学辅导
from pydantic import BaseModel
from openai import OpenAI
client = OpenAI()
class Step(BaseModel):
explanation: str
output: str
class MathReasoning(BaseModel):
steps: list[Step]
final_answer: str
completion = client.beta.chat.completions.parse(
model="gpt-4o-2024-08-06",
messages=[
{"role": "system", "content": "You are a helpful math tutor. Guide the user through the solution step by step."},
{"role": "user", "content": "how can I solve 8x + 7 = -23"}
],
response_format=MathReasoning,
)
math_reasoning = completion.choices[0].message.parsed
输出结果为:
{
"steps": [
{
"explanation": "Start with the equation 8x + 7 = -23.",
"output": "8x + 7 = -23"
},
{
"explanation": "Subtract 7 from both sides to isolate the term with the variable.",
"output": "8x = -23 - 7"
},
{
"explanation": "Simplify the right side of the equation.",
"output": "8x = -30"
},
{
"explanation": "Divide both sides by 8 to solve for x.",
"output": "x = -30 / 8"
},
{
"explanation": "Simplify the fraction.",
"output": "x = -15 / 4"
}
],
"final_answer": "x = -15 / 4"
}
案例2:使用 Structured Outputs 提取信息
from pydantic import BaseModel
from openai import OpenAI
client = OpenAI()
class ResearchPaperExtraction(BaseModel):
title: str
authors: list[str]
abstract: str
keywords: list[str]
completion = client.beta.chat.completions.parse(
model="gpt-4o-2024-08-06",
messages=[
{"role": "system", "content": "You are an expert at structured data extraction. You will be given unstructured text from a research paper and should convert it into the given structure."},
{"role": "user", "content": "..."}
],
response_format=ResearchPaperExtraction,
)
research_paper = completion.choices[0].message.parsed
输出结果为:
{
"title": "Application of Quantum Algorithms in Interstellar Navigation: A New Frontier",
"authors": [
"Dr. Stella Voyager",
"Dr. Nova Star",
"Dr. Lyra Hunter"
],
"abstract": "This paper investigates the utilization of quantum algorithms to improve interstellar navigation systems. By leveraging quantum superposition and entanglement, our proposed navigation system can calculate optimal travel paths through space-time anomalies more efficiently than classical methods. Experimental simulations suggest a significant reduction in travel time and fuel consumption for interstellar missions.",
"keywords": [
"Quantum algorithms",
"interstellar navigation",
"space-time anomalies",
"quantum superposition",
"quantum entanglement",
"space travel"
]
}
案例3:使用 Structured Outputs 进行内容审核
from enum import Enum
from typing import Optional
from pydantic import BaseModel
from openai import OpenAI
client = OpenAI()
class Category(str, Enum):
violence = "violence"
sexual = "sexual"
self_harm = "self_harm"
class ContentCompliance(BaseModel):
is_violating: bool
category: Optional[Category]
explanation_if_violating: Optional[str]
completion = client.beta.chat.completions.parse(
model="gpt-4o-2024-08-06",
messages=[
{"role": "system", "content": "Determine if the user input violates specific guidelines and explain if they do."},
{"role": "user", "content": "How do I prepare for a job interview?"}
],
response_format=ContentCompliance,
)
compliance = completion.choices[0].message.parsed
输出结果为:
{
"is_violating": false,
"category": null,
"explanation_if_violating": null
}
response_format
如何使用
使用 response_format 参数,您可以在调用 OpenAI API 时指定 Structured Outputs,以便将模型的输出解析为您所需的格式,或者您也可以直接指定 JSON Schema。
步骤 1:定义您的对象
首先,您必须定义一个对象或数据结构,以表示模型应该遵循的 JSON Schema。您可以在本指南顶部的示例中查看参考。
虽然 Structured Outputs 支持大部分 JSON Schema,但由于性能或技术原因,某些特性可能不可用。有关更多详细信息,请参见这里。
例如,您可以这样定义一个对象:
from pydantic import BaseModel
class Step(BaseModel):
explanation: str
output: str
class MathResponse(BaseModel):
steps: list[Step]
final_answer: str
为了最大限度地提高模型生成的质量,我们建议:
清晰直观地命名键:确保每个字段的名称都能清楚地表达其内容和用途。 为重要键创建清晰的标题和描述:这有助于模型更好地理解每个字段的预期内容。 创建并使用评估来确定最适合您用例的结构:通过实验不同的数据结构,找到最能提高模型输出质量的结构。
步骤 2:在 API 调用中提供您的对象
您可以使用 parse 方法自动将 JSON 响应解析为您定义的对象。
在内部,SDK 负责提供与您的数据结构对应的 JSON Schema,然后解析响应为对象。
completion = client.beta.chat.completions.parse(
model="gpt-4o-2024-08-06",
messages=[
{"role": "system", "content": "You are a helpful math tutor. Guide the user through the solution step by step."},
{"role": "user", "content": "how can I solve 8x + 7 = -23"}
],
response_format=MathResponse
)
步骤 3:处理边缘情况
在某些情况下,模型可能无法生成符合提供的 JSON Schema 的有效响应。这可能发生在以下情况下:
拒绝回答:出于安全原因,模型拒绝回答。 达到最大令牌限制:如果达到最大令牌限制,响应可能是不完整的。 理解错误:模型可能误解了问题的意图,导致生成的数据不符合预期的结构。
如何处理这些边缘情况:
增加错误处理:在代码中增加错误处理逻辑,以处理解析失败的情况。 提供备用响应:如果模型的响应不符合预期,可以提供备用响应或提示用户重新提问。 调整模型配置:调整模型的配置,例如增加最大令牌数,以减少不完整响应的可能性。 人工审核:对于复杂或模糊的边缘情况,可以引入人工审核来确保数据的准确性。
技巧和最佳实践
处理用户生成的输入
如果您的应用使用用户生成的输入,请确保提示中包含如何处理无法生成有效响应的情况的说明。
模型将始终尝试遵守提供的模式,如果输入与模式完全不相关,则可能导致生成与现实不符的内容。
您可以在提示中包含语言,指定如果模型检测到输入与任务不兼容,则返回空参数或特定句子。
处理错误
即使使用了 Structured Outputs,输出仍然可能包含错误。如果您发现错误,尝试调整您的指令,提供系统指令中的例子,或将任务分解为更简单的子任务。有关如何调整输入的更多指导,请参阅提示工程指南。
避免 JSON 模式偏离
为了防止您的 JSON 模式和相应编程语言中的类型出现偏离,我们强烈建议使用原生的 Pydantic/Zod SDK 支持。
如果您更喜欢直接指定 JSON 模式,您可以添加 CI 规则,在编辑 JSON 模式或底层数据对象时发出警告,或者添加一个 CI 步骤,从类型定义自动生成 JSON 模式(反之亦然)。
支持的模式
Structured Outputs 支持 JSON Schema 语言的一个子集。
支持的类型
Structured Outputs 支持以下类型:
字符串(String) 数字(Number) 布尔值(Boolean) 整数(Integer) 对象(Object) 数组(Array) 枚举(Enum) anyOf
尽管所有字段必须是必需的(模型将为每个参数返回一个值),但可以通过使用带有 null 的联合类型来模拟可选参数。
{
"name": "get_weather",
"description": "获取给定位置的天气",
"strict": true,
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "要获取天气的位置"
},
"unit": {
"type": ["string", "null"],
"description": "返回温度的单位",
"enum": ["F", "C"]
}
},
"additionalProperties": false,
"required": [
"location", "unit"
]
}
}
# 学习大模型 & 讨论Kaggle #
每天大模型、算法竞赛、干货资讯