1.介绍

基本介绍

JSON 是世界上应用最广泛的数据交换格式之一。Structured Outputs 是一个功能,可以确保模型始终生成符合你提供的 JSON Schema 的响应,因此你无需担心模型遗漏必要的键,或生成无效的枚举值。 Structured Outputs 的一些好处包括:

  • 可靠的类型安全性:无需验证或重试格式错误的响应
  • 明确拒绝:基于安全的模型拒绝现在可以程序化检测
  • 简化提示:无需使用强烈措辞的提示即可实现一致的格式化

除了在 REST API 中支持 JSON Schema 之外,OpenAI 的 Python 和 JavaScript SDK 还分别使用 Pydantic 和 Zod 使得定义对象模式变得容易。下面你可以看到如何从符合代码中定义的模式的无结构文本中提取信息。

from openai import OpenAI
from pydantic import BaseModel

MODEL_NAME = "Qwen/Qwen2.5-7B-Instruct"
API_KEY = "您的 APIKEY", # 从https://cloud.siliconflow.cn/account/ak获取
client = OpenAI(api_key=API_KEY, base_url="https://api.siliconflow.cn/v1")
class Step(BaseModel):
    explanation: str
    output: str
class MathReasoning(BaseModel):
    steps: list[Step]
    final_answer: str
json_schema = MathReasoning.model_json_schema()
completion = client.chat.completions.create(
    model=MODEL_NAME,
    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={
        "type": "json_schema",
        "json_schema": {
            "name": "math_response",
            "schema": json_schema
    }
  }
)
math_reasoning = completion.choices[0].message.content
print(math_reasoning)

###2.支持模型列表 目前线上提供的大语言类模型都支持上述参数。

注意:支持的模型情况可能会发生变化,请查阅本文档了解最新支持的模型列表。
你的应用必须检测并处理可能导致模型输出不完整JSON对象的边缘案例。
请合理设置max_tokens,防止JSON字符串被中断。

3.使用场景

在 OpenAI API 中,Structured Outputs 有两种形式:

  • 使用函数调用时
  • 当使用 json_schema 响应格式时

函数调用在构建连接应用程序模型和功能的应用程序时很有用。 例如,你可以给模型访问查询数据库的功能,以便构建一个能帮助用户处理订单的 AI 助手,或者可以与 UI 交互的功能。

相反,通过 response_format 可以更适当地表示结构化输出,当模型响应用户时,你希望表明一个结构化的方案,而不是当模型调用工具时。

例如,如果你正在开发一个数学辅导应用,你可能希望助手使用特定的 JSON Schema 来响应用户,以便你可以生成一个 UI,以不同的方式显示模型输出的各个部分。

简单来说:

  • 如果你将模型连接到系统中的工具、函数、数据等,那么你应该使用函数调用。
  • 如果你希望在模型回应用户时结构化其输出,那么你应该使用一个结构化的 response_format
    本指南的其余部分将专注于 Chat Completions API 中的非函数调用用例。如需了解如何使用结构化输出进行函数调用,请参阅函数调用指南。

4. Structured Outputs vs JSON mode

Structured Outputs 是 JSON 模式的进化。虽然两者都能确保生成有效的 JSON,但只有 Structured Outputs 能确保遵循模式。在语言模型中和语言微调模型中,都支持 Structured Outputs 和 JSON 模式。 我们建议在可能的情况下始终使用结构化输出,而不是 JSON 模式。

示例

如何使用

如何使用response_format输出结构化数据

您可以使用新 SDK 辅助程序中的结构化输出来将模型的输出解析为您所需的格式,或者可以直接指定 JSON 方案。 注意:使用任何模式进行首次请求时,由于我们的 API 需要处理模式,因此会有多余的延迟,但使用相同模式的后续请求将不会有多余的延迟。

提示和最佳实践

####处理用户生成的输入 如果您的应用程序使用用户生成的输入,请确保提示中包含如何处理输入无法生成有效响应的情况的说明。 该模型会始终尝试遵循提供的结构,如果输入与结构完全无关,则可能会产生幻觉。 您可以在提示中加入语言来指定希望模型在检测到输入与任务不兼容时返回空参数,或特定句子。

####处理错误 为了防止您的 JSON Schema 和相应编程语言中的类型出现偏差,我们强烈建议使用原生的 Pydantic/zod SDK 支持。 如果您更喜欢直接指定 JSON 方案,可以添加 CI 规则以标记当 JSON 方案或底层数据对象被编辑时的情况,或者添加一个 CI 步骤来自动生成 JSON 方案(反之亦然)。

避免 JSON 模式偏差

为了防止您的 JSON Schema 和相应编程语言中的类型出现偏差,我们强烈建议使用原生的 Pydantic/zod SDK 支持。 如果您更喜欢直接指定 JSON 方案,可以添加 CI 规则以标记当 JSON 方案或底层数据对象被编辑时的情况,或者添加一个 CI 步骤来自动生成 JSON 方案(反之亦然)。

##流式传输

你可以使用流式处理来处理模型响应或函数调用参数,边生成边解析为结构化数据。 这样,你无需等待整个响应完成就可以处理它。这在你希望逐个显示 JSON 字段或一有可用的函数调用参数就进行处理时特别有用。 我们建议依赖于 SDK 来处理带有结构化输出的流式传输。您可以在函数调用指南中找到如何在不使用 SDK stream 辅助的情况下流式传输函数调用参数的示例。

from openai import OpenAI
from pydantic import BaseModel
from enum import Enum
from typing import Optional
from typing import List

MODEL_NAME = "Qwen/Qwen2.5-7B-Instruct"
API_KEY = "you api_key"
client = OpenAI(api_key=API_KEY, base_url="https://api.siliconflow.cn/v1")
class Step(BaseModel):
    explanation: str
    output: str
class MathReasoning(BaseModel):
    steps: list[Step]
    final_answer: str
json_schema = MathReasoning.model_json_schema()
completion = client.chat.completions.create(
    model=MODEL_NAME,
    stream=True,
    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={
        "type": "json_schema",
        "json_schema": {
            "name": "math_response",
            "schema": json_schema
    }
  }
)
print(completion)
li = ""
for chunk in completion:
    li += chunk.choices[0].delta.content
print(li)

支持的模式

支持的结构化输出类型有: String 字符串 Number 数字 Boolean 布尔 Integer 整数 Object 对象 Array 数组 Enum 枚举 anyOf Root 对象必须不要是 anyOf