For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
主导航

模型的结构化输出

确保模型的文本响应符合您定义的 JSON 模式。

JSON 是全球应用间数据交换最广泛使用的格式之一。

结构化输出功能可确保模型始终生成符合您提供的 JSON Schema 的响应,因此您无需担心模型遗漏必需的键,或因幻觉生成无效的枚举值。

结构化输出的优势包括:

  1. 可靠的类型安全: 无需验证响应格式,也无需因格式不正确而重试
  2. 明确的拒绝响应: 现在可以通过程序检测模型出于安全原因作出的拒绝响应
  3. 更简单的提示: 无需在提示中反复强调格式要求,即可获得格式一致的响应

除了在 REST API 中支持 JSON Schema 外,OpenAI 的 PythonJavaScript 库还允许您分别使用 pydantic.BaseModelz.object 定义对象模式。下面展示了如何从非结构化文本中提取信息,使结果符合代码中定义的模式。

Ruby SDK 支持使用 Sorbet T::Struct 定义的模式,并返回带有类型信息的解析结果。

获取结构化响应
from openai import OpenAI
from pydantic import BaseModel

client = OpenAI()


class CalendarEvent(BaseModel):
    name: str
    date: str
    participants: list[str]


response = client.responses.parse(
    model="gpt-6-astra",
    input=[
        {"role": "system", "content": "Extract the event information."},
        {
            "role": "user",
            "content": "Alice and Bob are going to a science fair on Friday.",
        },
    ],
    text_format=CalendarEvent,
)

event = response.output_parsed

支持的模型

从 GPT-4o 开始,我们的最新大语言模型均支持结构化输出。对于新项目,请从 gpt-6-astra 开始。gpt-4-turbo 及更早的模型可以改用 JSON 模式

何时通过函数调用使用结构化输出,何时通过 text.format 使用

OpenAI API 提供两种使用结构化输出的方式:

  1. 使用函数调用
  2. 使用 json_schema 响应格式

如果您正在构建需要将模型与应用功能连接起来的应用,函数调用会很有用。

例如,您可以让模型访问查询数据库的函数,从而构建能够帮助用户处理订单的 AI 助手;也可以让模型访问能够与 UI 交互的函数。

相比之下,如果您希望指定模型回复用户时应遵循的结构化模式,而不是模型调用工具时应遵循的模式,那么通过 response_format 使用结构化输出更为合适。

例如,如果您正在构建数学辅导应用,可能希望助手使用特定的 JSON Schema 回复用户,以便生成一个 UI,用不同的方式展示模型输出的各个部分。

在实际使用中:

  • 如果您要将模型连接到系统中的工具、函数、数据等, 则应使用函数调用;如果您希望模型回复用户时 输出结构化内容,则应使用结构化的 text.format

本指南的其余部分将重点介绍 Responses API 中 不涉及函数调用的使用场景。要详细了解如何在函数调用中 使用结构化输出,请参阅

函数调用

指南。

结构化输出与 JSON 模式的比较

结构化输出是 JSON 模式的演进版本。虽然两者都能确保生成有效的 JSON,但只有结构化输出能确保输出符合模式。Responses API、Chat Completions API、Assistants API、Fine-tuning API 和 Batch API 均支持结构化输出和 JSON 模式。

我们建议在条件允许时始终使用结构化输出,而不是 JSON 模式。

不过,通过 response_format: {type: "json_schema", ...} 使用结构化输出仅受 gpt-4o-minigpt-4o-mini-2024-07-18gpt-4o-2024-08-06 及更新的模型快照支持。

结构化输出JSON 模式
输出有效的 JSON
符合模式是(参阅支持的模式
兼容的模型gpt-4o-minigpt-4o-2024-08-06 及更新的模型gpt-3.5-turbogpt-4-*gpt-4o-* 及兼容的 GPT-5 模型
启用方式text: { format: { type: "json_schema", "strict": true, "schema": ... } }text: { format: { type: "json_object" } }

示例

思维链

您可以要求模型以结构化的方式逐步输出答案,引导用户理解解题过程。

在思维链数学辅导中使用结构化输出
from openai import OpenAI
from pydantic import BaseModel

client = OpenAI()


class Step(BaseModel):
    explanation: str
    output: str


class MathReasoning(BaseModel):
    steps: list[Step]
    final_answer: str


response = client.responses.parse(
    model="gpt-6-astra",
    input=[
        {
            "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"},
    ],
    text_format=MathReasoning,
)

math_reasoning = response.output_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"
}

如何通过 text.format 使用结构化输出

结构化输出中的拒绝响应

将结构化输出用于用户生成的输入时,OpenAI 模型偶尔可能出于安全原因拒绝执行请求。由于拒绝响应不一定遵循您在 response_format 中提供的模式,API 响应会包含一个名为 refusal 的新字段,用于指示模型拒绝执行该请求。

当输出对象中出现 refusal 属性时,您可以在 UI 中显示拒绝响应,也可以在使用该响应的代码中加入条件逻辑,以处理请求被拒绝的情况。

class Step(BaseModel):
    explanation: str
    output: str


class MathReasoning(BaseModel):
    steps: list[Step]
    final_answer: str


response = client.responses.parse(
    model="gpt-6-astra",
    input=[
        {
            "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"},
    ],
    text_format=MathReasoning,
)

for output in response.output:
    if output.type != "message":
        continue

    for item in output.content:
        if item.type == "refusal":
            # If the model refuses to respond, you will get a refusal message
            print(item.refusal)
            continue

        if not item.parsed:
            raise Exception("Could not parse response")

        print(item.parsed)

请求被拒绝时,API 响应大致如下:

{
  "id": "resp_1234567890",
  "object": "response",
  "created_at": 1721596428,
  "status": "completed",
  "completed_at": 1721596429,
  "error": null,
  "incomplete_details": null,
  "input": [],
  "instructions": null,
  "max_output_tokens": null,
  "model": "gpt-4o-2024-08-06",
  "output": [{
    "id": "msg_1234567890",
    "type": "message",
    "role": "assistant",
    "content": [
      {
        "type": "refusal",
        "refusal": "I'm sorry, I cannot assist with that request."
      }
    ]
  }],
  "usage": {
    "input_tokens": 81,
    "output_tokens": 11,
    "total_tokens": 92,
    "output_tokens_details": {
      "reasoning_tokens": 0,
    }
  },
}

技巧与最佳实践

处理用户生成的输入

如果您的应用使用用户生成的输入,请务必在提示中说明,当输入无法产生有效响应时应如何处理。

模型始终会尝试遵循所提供的模式,因此,如果输入与模式完全无关,就可能产生幻觉。

您可以在提示中明确说明,如果模型检测到输入与任务不兼容,应返回空参数或某个特定句子。

处理错误

结构化输出仍可能包含错误。如果您发现错误,可以尝试调整指令、在系统指令中提供示例,或将任务拆分为更简单的子任务。有关如何调整输入的更多指导,请参阅提示工程指南

避免 JSON 模式与类型不一致

为防止您的 JSON Schema 与所用编程语言中的对应类型出现不一致,如果 SDK 提供了原生的模式辅助工具,我们强烈建议您使用这些工具。

如果您更倾向于直接指定 JSON 模式,可以添加 CI 规则,在 JSON 模式或底层数据对象被修改时发出提示;也可以添加一个 CI 步骤,根据类型定义自动生成 JSON Schema(或反向生成类型定义)。

流式传输

您可以使用流式传输,在模型响应或函数调用参数生成的过程中处理它们,并将其解析为结构化数据。

这样,您就不必等到整个响应生成完毕后再进行处理。 如果您希望逐个显示 JSON 字段,或在函数调用参数可用时立即处理它们,这种方式尤其有用。

我们建议使用 SDK 来处理结构化输出的流式传输。

from openai import OpenAI
from pydantic import BaseModel


class EntitiesModel(BaseModel):
    attributes: list[str]
    colors: list[str]
    animals: list[str]


client = OpenAI()

with client.responses.stream(
    model="gpt-6-astra",
    input=[
        {"role": "system", "content": "Extract entities from the input text"},
        {
            "role": "user",
            "content": "The quick brown fox jumps over the lazy dog with piercing blue eyes",
        },
    ],
    text_format=EntitiesModel,
) as stream:
    for event in stream:
        if event.type == "response.refusal.delta":
            print(event.delta, end="")
        elif event.type == "response.output_text.delta":
            print(event.delta, end="")
        elif event.type == "response.error":
            print(event.error, end="")
        elif event.type == "response.completed":
            print("Completed")  # print(event.response.output)

    final_response = stream.get_final_response()
    print(final_response)

支持的模式

结构化输出支持 JSON Schema 语言的一个子集。

支持的类型

结构化输出支持以下类型:

  • 字符串
  • 数值
  • 布尔值
  • 整数
  • 对象
  • 数组
  • 枚举
  • anyOf

支持的属性

除了指定属性的类型,您还可以指定一些额外的约束:

string 支持的属性:

  • pattern:字符串必须匹配的正则表达式。
  • format:字符串的预定义格式。目前支持:
    • date-time
    • time
    • date
    • duration
    • email
    • hostname
    • ipv4
    • ipv6
    • uuid

number 支持的属性:

  • multipleOf:数值必须是该值的倍数。
  • maximum:数值必须小于或等于该值。
  • exclusiveMaximum:数值必须小于该值。
  • minimum:数值必须大于或等于该值。
  • exclusiveMinimum:数值必须大于该值。

array 支持的属性:

  • minItems:数组的元素数量必须至少达到该值。
  • maxItems:数组的元素数量不得超过该值。

以下示例展示了如何使用这些类型约束:

{
    "name": "user_data",
    "strict": true,
    "schema": {
        "type": "object",
        "properties": {
            "name": {
                "type": "string",
                "description": "The name of the user"
            },
            "username": {
                "type": "string",
                "description": "The username of the user. Must start with @",
                "pattern": "^@[a-zA-Z0-9_]+$"
            },
            "email": {
                "type": "string",
                "description": "The email of the user",
                "format": "email"
            }
        },
        "additionalProperties": false,
        "required": [
            "name", "username", "email"
        ]
    }
}

根节点必须是对象,不能使用 anyOf

请注意,模式的根节点必须是对象,且不能使用 anyOf。例如,Zod 中的一种用法是使用可辨识联合类型,这会在顶层生成 anyOf。因此,以下这样的代码无法正常工作:

import { z } from "zod";
import { zodResponseFormat } from "openai/helpers/zod";

const BaseResponseSchema = z.object({
  /* ... */
});
const UnsuccessfulResponseSchema = z.object({
  /* ... */
});

const finalSchema = z.discriminatedUnion("status", [
  BaseResponseSchema,
  UnsuccessfulResponseSchema,
]);

// Invalid JSON Schema for Structured Outputs
const json = zodResponseFormat(finalSchema, "final_schema");

所有字段都必须设为 required

要使用结构化输出,必须将所有字段或函数参数指定为 required

{
    "name": "get_weather",
    "description": "Fetches the weather in the given location",
    "strict": true,
    "parameters": {
        "type": "object",
        "properties": {
            "location": {
                "type": "string",
                "description": "The location to get the weather for"
            },
            "unit": {
                "type": "string",
                "description": "The unit to return the temperature in",
                "enum": ["F", "C"]
            }
        },
        "additionalProperties": false,
        "required": ["location", "unit"]
    }
}

虽然所有字段都必须为必填项(模型会为每个参数返回一个值),但可以使用包含 null 的联合类型来模拟可选参数。

{
    "name": "get_weather",
    "description": "Fetches the weather in the given location",
    "strict": true,
    "parameters": {
        "type": "object",
        "properties": {
            "location": {
                "type": "string",
                "description": "The location to get the weather for"
            },
            "unit": {
                "type": ["string", "null"],
                "description": "The unit to return the temperature in",
                "enum": ["F", "C"]
            }
        },
        "additionalProperties": false,
        "required": [
            "location", "unit"
        ]
    }
}

对象的嵌套深度和大小有限制

一个模式最多可以包含 5000 个对象属性,嵌套深度最多为 10 层。

字符串总长度限制

在一个模式中,所有属性名、定义名、枚举值和 const 值的字符串总长度不得超过 120,000 个字符。

枚举大小限制

一个模式中所有枚举属性的枚举值总数最多为 1000 个。

对于值为字符串的单个枚举属性,当枚举值超过 250 个时,所有枚举值的字符串总长度不得超过 15,000 个字符。

对象中必须始终设置 additionalProperties: false

additionalProperties 控制是否允许对象包含 JSON Schema 中未定义的额外键值对。

结构化输出仅支持生成指定的键值对,因此我们要求开发者设置 additionalProperties: false 以启用结构化输出。

{
    "name": "get_weather",
    "description": "Fetches the weather in the given location",
    "strict": true,
    "schema": {
        "type": "object",
        "properties": {
            "location": {
                "type": "string",
                "description": "The location to get the weather for"
            },
            "unit": {
                "type": "string",
                "description": "The unit to return the temperature in",
                "enum": ["F", "C"]
            }
        },
        "additionalProperties": false,
        "required": [
            "location", "unit"
        ]
    }
}

键的顺序

使用结构化输出时,输出中键的顺序将与模式中键的顺序一致。

某些特定类型的关键字尚不受支持

  • 组合: allOfnotdependentRequireddependentSchemasifthenelse

对于微调模型,我们还不支持以下内容:

  • 字符串: minLengthmaxLengthpatternformat
  • 数字: minimummaximummultipleOf
  • 对象: patternProperties
  • 数组: minItemsmaxItems

如果您通过传入 strict: true 启用结构化输出,并使用不受支持的 JSON Schema 调用 API,则会收到错误。

对于 anyOf,每个嵌套模式都必须是符合此子集要求的有效 JSON Schema

以下是受支持的 anyOf 模式示例:

{
    "type": "object",
    "properties": {
        "item": {
            "anyOf": [
                {
                    "type": "object",
                    "description": "The user object to insert into the database",
                    "properties": {
                        "name": {
                            "type": "string",
                            "description": "The name of the user"
                        },
                        "age": {
                            "type": "number",
                            "description": "The age of the user"
                        }
                    },
                    "additionalProperties": false,
                    "required": [
                        "name",
                        "age"
                    ]
                },
                {
                    "type": "object",
                    "description": "The address object to insert into the database",
                    "properties": {
                        "number": {
                            "type": "string",
                            "description": "The number of the address. Eg. for 123 main st, this would be 123"
                        },
                        "street": {
                            "type": "string",
                            "description": "The street name. Eg. for 123 main st, this would be main st"
                        },
                        "city": {
                            "type": "string",
                            "description": "The city of the address"
                        }
                    },
                    "additionalProperties": false,
                    "required": [
                        "number",
                        "street",
                        "city"
                    ]
                }
            ]
        }
    },
    "additionalProperties": false,
    "required": [
        "item"
    ]
}

支持定义

您可以使用定义来创建子模式,并在整个模式中引用这些子模式。以下是一个简单示例。

{
    "type": "object",
    "properties": {
        "steps": {
            "type": "array",
            "items": {
                "$ref": "#/$defs/step"
            }
        },
        "final_answer": {
            "type": "string"
        }
    },
    "$defs": {
        "step": {
            "type": "object",
            "properties": {
                "explanation": {
                    "type": "string"
                },
                "output": {
                    "type": "string"
                }
            },
            "required": [
                "explanation",
                "output"
            ],
            "additionalProperties": false
        }
    },
    "required": [
        "steps",
        "final_answer"
    ],
    "additionalProperties": false
}

支持递归模式

以下递归模式示例使用 # 表示对根模式的递归引用。

{
    "name": "ui",
    "description": "Dynamically generated UI",
    "strict": true,
    "schema": {
        "type": "object",
        "properties": {
            "type": {
                "type": "string",
                "description": "The type of the UI component",
                "enum": ["div", "button", "header", "section", "field", "form"]
            },
            "label": {
                "type": "string",
                "description": "The label of the UI component, used for buttons or form fields"
            },
            "children": {
                "type": "array",
                "description": "Nested UI components",
                "items": {
                    "$ref": "#"
                }
            },
            "attributes": {
                "type": "array",
                "description": "Arbitrary attributes for the UI component, suitable for any element",
                "items": {
                    "type": "object",
                    "properties": {
                        "name": {
                            "type": "string",
                            "description": "The name of the attribute, for example onClick or className"
                        },
                        "value": {
                            "type": "string",
                            "description": "The value of the attribute"
                        }
                    },
                    "additionalProperties": false,
                    "required": ["name", "value"]
                }
            }
        },
        "required": ["type", "label", "children", "attributes"],
        "additionalProperties": false
    }
}

使用显式递归的递归模式示例:

{
    "type": "object",
    "properties": {
        "linked_list": {
            "$ref": "#/$defs/linked_list_node"
        }
    },
    "$defs": {
        "linked_list_node": {
            "type": "object",
            "properties": {
                "value": {
                    "type": "number"
                },
                "next": {
                    "anyOf": [
                        {
                            "$ref": "#/$defs/linked_list_node"
                        },
                        {
                            "type": "null"
                        }
                    ]
                }
            },
            "additionalProperties": false,
            "required": [
                "next",
                "value"
            ]
        }
    },
    "additionalProperties": false,
    "required": [
        "linked_list"
    ]
}

JSON 模式

JSON 模式是结构化输出功能的基础版本。JSON 模式可确保模型输出为有效的 JSON,而结构化输出能可靠地使模型输出符合您指定的模式。如果您的使用场景支持结构化输出,我们建议您使用它。

启用 JSON 模式后,模型输出可确保为有效的 JSON,但某些边界情况除外,您应检测这些情况并妥善处理。

要在 Responses API 中启用 JSON 模式,您可以将 text.format 设置为 { "type": "json_object" }。如果您使用函数调用,JSON 模式始终处于启用状态。

重要说明:

  • 使用 JSON 模式时,您必须始终通过对话中的某条消息(例如系统消息)指示模型生成 JSON。如果未明确指示模型生成 JSON,模型可能会不断生成空白字符,请求也可能持续运行,直到达到 Token 上限。为帮助您避免遗漏这一要求,如果上下文中没有出现字符串“JSON”,API 将抛出错误。
  • JSON 模式不保证输出符合任何特定模式,只保证输出是有效的 JSON,且解析时不会出错。您应使用结构化输出来确保输出符合您的模式;如果无法使用,则应使用验证库,并可能需要重试,以确保输出符合所需模式。
  • 您的应用必须检测并处理可能导致模型输出不是完整 JSON 对象的边界情况(见下文)。

资源

要进一步了解结构化输出,我们建议您浏览以下资源: