PAYATHON 2026

OpenAI Responses API 如何使用 Structured Outputs?

技术老齐

在 client.responses.create() 中,将 JSON Schema 放在 text.format.schema,并在同一个 format 对象中设置 type="json_schema"、name 和 strict=True。只提供 { "type": "json_schema" } 并不完整。官方参数说明

client.responses.parse() 是 SDK 提供的辅助方法,用于提交结构定义并解析结果。REST API 文档中没有单独的 /responses/parse 接口,不能据此认为 SDK 没有这个方法。

使用 create 直接传入 JSON Schema

以下示例提取活动名称、日期描述和参与者,使用问题中的模型标识。运行前,请确认模型仍可用、账户有访问权限,并已设置 OPENAI_API_KEY。

import json
from openai import OpenAI

client = OpenAI()

messages = [
    {"role": "system", "content": "Extract the event information."},
    {
        "role": "user",
        "content": "Alice and Bob are going to a science fair on Friday.",
    },
]

event_schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "date": {"type": "string"},
        "participants": {
            "type": "array",
            "items": {"type": "string"},
        },
    },
    "required": ["name", "date", "participants"],
    "additionalProperties": False,
}

response = client.responses.create(
    model="gpt-4o-2024-08-06",
    input=messages,
    text={
        "format": {
            "type": "json_schema",
            "name": "calendar_event",
            "strict": True,
            "schema": event_schema,
        }
    },
)

if response.status != "completed":
    raise RuntimeError(
        f"Response not completed: {response.status}; "
        f"details={response.incomplete_details}"
    )

for item in response.output:
    if item.type == "message":
        for part in item.content:
            if part.type == "refusal":
                raise RuntimeError(part.refusal)

if not response.output_text:
    raise RuntimeError("No JSON output returned")

event = json.loads(response.output_text)
print(event)

参数的层级关系是:

text
└── format
    ├── type: "json_schema"
    ├── name: "calendar_event"
    ├── strict: true
    └── schema: {...}

直接发送 HTTP 请求时,同样要将这个 text 对象放在 POST /v1/responses 的 JSON 请求体中,布尔值使用 JSON 的 true。不要将其他端点的 response_format 参数结构直接用于 Responses API。

parse 与 create 有什么区别?

在支持该方法的 OpenAI Python SDK 中,responses.parse() 可以接收 Pydantic 模型。SDK 会根据模型生成 JSON Schema,将返回结果解析为对应的对象,再通过 response.output_parsed 提供给调用方。官方 Structured Outputs 指南

复用上面定义的 client 和 messages:

from pydantic import BaseModel

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

response = client.responses.parse(
    model="gpt-4o-2024-08-06",
    input=messages,
    text_format=CalendarEvent,
)

if response.status != "completed" or response.output_parsed is None:
    raise RuntimeError("No parsed event returned; inspect response.output")

event = response.output_parsed
print(event.name)

需要手动控制 JSON Schema 时,可以用 create();如果已经用 Pydantic 定义了数据结构,parse() 更方便。text_format=CalendarEvent 是 Python SDK 辅助方法的参数,不是 REST 请求体字段。

如果遇到提示没有 responses.parse 的 AttributeError,请检查安装的 openai SDK 版本和实际导入来源,确认使用的是支持该方法的官方 SDK。也可以使用前面的 create() 写法。

使用时需要注意什么?

  • strict=True 只支持 JSON Schema 的一个子集。对象应设置 additionalProperties: false,定义的属性都要列入 required;业务上允许缺失的值可用包含 null 的类型表示。
  • json_object 只约束输出为合法 JSON,不能替代指定 Schema 的 Structured Outputs。
  • 遇到拒绝回答或生成被截断时,不应直接假定输出可解析。请先检查响应状态和 refusal,再读取结构化结果。

这些限制和异常处理方式可参阅官方指南。Schema 约束的是数据结构,仍需检查业务含义。例如,输入只有 Friday、没有具体日期依据时,不应擅自换算成年月日。

备注:内容仅供参考。