OpenAI推出基于JSON Schema的结构化输出以解决这一问题。结构化输出确保模型响应遵循严格的格式,减少错误,并使将大语言模型集成到需要一致的、机器可读数据的应用程序中变得更加容易,对于一致性和准确性至关重要的任务其输出更为可靠。

什么是基于JSON Schema的结构化输出
大语言模型通常会生成无特定结构的自由格式文本,在能够有效使用之前需要进行大量的后期处理。这种不可预测性会导致错误、浪费时间并增加成本。

OpenAI推出基于JSON Schema的结构化输出以解决这一问题。结构化输出确保模型响应遵循严格的格式,减少错误,并使将大语言模型集成到需要一致的、机器可读数据的应用程序中变得更加容易,对于一致性和准确性至关重要的任务其输出更为可靠。

通常情况下,大语言模型基于概率预测逐个生成文本标记。不过,如果需要以特定格式生成文本,这种方法就不太适用了。结构化输出通过预定义的规则或模式来引导这一过程,使每个标记都符合所需的结构。

如何使用基于JSON Schema的结构化输出
并非所有的模型都支持基于JSON Schema的结构化输出。经测试,文心一言支持结构化输出。通义千问、豆包、deepseek还不支持。

下面以输出方程求解过程的结构化输出为例,阐述OpenAI Python SDK使用结构化输出的两种方法。

先准备好开发环境,以windows开发环境为例:

设置Python开发环境
安装uv。uv是一个用Rust编写的极其快速的Python包和项目管理器。

复制
powershell -ExecutionPolicy ByPass -c “irm https://astral.sh/uv/install.ps1 | iex”
1.
创建python虚拟环境(假设项目目录为structured-output)

复制
# Create a new directory for our project
uv init structured-output
cd structured-output

# Create virtual environment and activate it
uv venv
.venv\Scripts\activate

# Install dependencies
uv add openai python-dotenv
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
设置环境变量
创建.env,.env内容如下(注意修改OPENAI_API_KEY为您的key)

复制
OPENAI_API_KEY=your_api_key_here
OPENAI_BASE_URL=https://qianfan.baidubce.com/v2
MODEL_NAME=ernie-3.5-128k
1.
2.
3.
把.env添加到.gitignore

结构化输出方法1:手工定义Schema
通过设置chat completion的response_format打开结构化输出。response_format的格式为:

复制
{
type: “json_schema”,
json_schema: {
“strict”: true,
“schema”: …
}
}
1.
2.
3.
4.
5.
6.
7.
完整例子如下:

复制
import os
from openai import OpenAI
from dotenv import load_dotenv

load_dotenv() # load environment variables from .env

client = OpenAI()
chat_completion = client.chat.completions.create(
messages=[
{
“role”: “system”,
“content”: “你是一位数学老师。一步步引导用户完成解题过程”
},
{
“role”: “user”,
“content”: “我该如何解7x + 6 = 41这个方程”
}
],
model=os.getenv(“MODEL_NAME”),
response_format={
“type”: “json_schema”,
“json_schema”: {
“name”: “math_response”,
“schema”: {
“type”: “object”,
“properties”: {
“steps”: {
“type”: “array”,
“items”: {
“type”: “object”,
“properties”: {
“explanation”: {“type”: “string”},
“output”: {“type”: “string”}
},
“required”: [“explanation”, “output”],
“additionalProperties”: False
}
},
“final_answer”: {“type”: “string”}
},
“required”: [“steps”, “final_answer”],
“additionalProperties”: False
},
“strict”: True
}
},
)
content = chat_completion.choices[0].message.content
print(content)
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
输出结果如下:

复制
{
“final_answer”:”x = 5″,
“steps”:[
{
“explanation”:”首先,我们需要将方程中的常数项移至等式的另一边,使方程左侧只剩下未知数x的系数和x本身。”,
“output”:”7x = 41 – 6″
},
{
“explanation”:”进行减法运算,简化方程。”,
“output”:”7x = 35″
},
{
“explanation”:”接下来,我们需要将x的系数化为1,以求解x的值。为此,我们将方程两边同时除以7。”,
“output”:”x = 35 ÷ 7″
},
{
“explanation”:”进行除法运算,得出x的值。”,
“output”:”x = 5″
}
]
}
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
结构化输出方法2:使用自定义的pydantic模型
通过设置chat completion的response_format为自定义的pydantic模型MathReasoning

完整例子如下:

复制
import os
from openai import OpenAI
from dotenv import load_dotenv
from pydantic import BaseModel

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

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

load_dotenv() # load environment variables from .env

client = OpenAI()
chat_completion = client.beta.chat.completions.parse(
messages=[
{
“role”: “system”,
“content”: “你是一位乐于助人的数学老师。一步步引导用户完成解题过程”
},
{
“role”: “user”,
“content”: “我该如何解7x + 6 = 41这个方程”
}
],
model=os.getenv(“MODEL_NAME”),
response_format=MathReasoning,
)
math_reasoning = chat_completion.choices[0].message.parsed
print(math_reasoning.model_dump_json(indent=4))
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
输出结果为:

复制
{
“steps”:[
{
“explanation”:”首先,我们需要将方程中的常数项移至等式的另一边。从7x + 6 = 41开始,我们可以从两边同时减去6。”,
“output”:”7x + 6 – 6 = 41 – 6″
},
{
“explanation”:”简化上一步的等式,得到7x = 35。”,
“output”:”7x = 35″
},
{
“explanation”:”接下来,我们需要解出x的值。为此,我们可以将方程两边同时除以7。”,
“output”:”7x / 7 = 35 / 7″
},
{
“explanation”:”简化上一步的等式,得到x = 5。”,
“output”:”x = 5″
}
],
“final_answer”:”x = 5″
}
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
JSON Schema结构化输出 VS JSON模式
JSON Schema结构化输出是JSON模式的进阶版本。JSON模式是通过设置response_format为{ “type”: “json_object” }打开。使用JSON模式时,你必须始终通过对话中的某些消息(例如系统消息)指示模型生成JSON。JSON 模式不能保证输出符合任何特定的模式。

总结
JSON Schema结构化输出提供了一个强大的解决方案,可确保您的大语言模型生成可靠、可预测且机器可读的回复。结构化输出有助于您在不同应用程序中保持一致的数据格式,从而更轻松地管理复杂的工作流程。

文章来自:51CTO

Loading

作者 yinhua

发表回复