AI API 结构化输出(JSON Mode/Structured Outputs)实战指南:告别解析报错
2026-08-30 · 约 9 分钟阅读
在生产环境中,让 AI 模型返回严格符合预期格式的 JSON 是绝大多数应用的刚需——无论是提取结构化数据、生成表单,还是驱动下游业务逻辑。但"模型偶尔输出多余文字导致 JSON 解析失败"是开发者最常遇到的痛点之一。本文系统讲解各家模型的结构化输出方案,以及在中转站场景下如何避坑。
三种主流方案对比
| 方案 | 代表模型 | 严格程度 | 说明 |
|---|---|---|---|
| Structured Outputs(Schema强约束) | GPT-5系列 | 强制100%符合schema | 底层用受限采样保证输出必然合法 |
| JSON Mode(弱约束) | GPT-4o/DeepSeek等 | 保证是合法JSON,字段不保证 | 需要在Prompt里明确字段要求 |
| Response Schema | Gemini系列 | 强约束 | 通过response_schema参数定义结构 |
| Prompt约束(无原生支持) | 部分国产/开源模型 | 无保证 | 完全依赖Prompt工程+后处理校验 |
GPT-5 系列 Structured Outputs 实战
这是目前最可靠的方案,模型输出会在解码层面被强制约束,不会出现字段缺失或类型错误:
from openai import OpenAI
from pydantic import BaseModel
client = OpenAI(
api_key="你的中转站API Key",
base_url="https://你的中转站域名/v1"
)
class OrderInfo(BaseModel):
product_name: str
quantity: int
price: float
is_urgent: bool
response = client.beta.chat.completions.parse(
model="gpt-5.6-sol",
messages=[
{"role": "system", "content": "从用户描述中提取订单信息"},
{"role": "user", "content": "我要紧急订购3件蓝色T恤,单价89.9元"}
],
response_format=OrderInfo,
)
order: OrderInfo = response.choices[0].message.parsed
print(order.product_name, order.quantity, order.price, order.is_urgent)
Gemini 系列 Response Schema 实战
response = client.chat.completions.create(
model="gemini-3.1-pro",
messages=[{"role": "user", "content": "提取这段文字中的人名和地点"}],
extra_body={
"response_schema": {
"type": "object",
"properties": {
"names": {"type": "array", "items": {"type": "string"}},
"locations": {"type": "array", "items": {"type": "string"}}
},
"required": ["names", "locations"]
}
}
)
弱约束模型的兜底方案
对于只支持基础 JSON Mode 甚至完全不支持结构化输出的模型(常见于部分国产/开源模型经中转站接入的情况),建议采用"Prompt强约束 + 代码层二次校验"的组合方案:
import json
from pydantic import BaseModel, ValidationError
class ExtractResult(BaseModel):
names: list[str]
locations: list[str]
prompt = """请严格按以下JSON格式输出,不要包含任何额外文字、解释或markdown代码块标记:
{"names": ["姓名1", "姓名2"], "locations": ["地点1"]}
需要提取的文本:{text}"""
response = client.chat.completions.create(
model="deepseek-v3.5",
messages=[{"role": "user", "content": prompt.format(text="张三去了北京出差")}],
)
raw = response.choices[0].message.content.strip()
# 兜底清理常见的markdown代码块包裹
if raw.startswith("```"):
raw = raw.split("```")[1].replace("json", "", 1).strip()
try:
result = ExtractResult(**json.loads(raw))
except (json.JSONDecodeError, ValidationError) as e:
# 触发重试或降级到备用模型
print(f"解析失败,需要重试: {e}")
中转站场景下的常见坑
1. response_format参数被过滤:部分中转站没有完整实现 GPT-5 的 beta.chat.completions.parse 接口,只支持基础的 {"type": "json_object"},接入前务必先做小样本验证
2. Schema复杂度导致失败率上升:过深的嵌套结构、大量枚举值会增加模型出错概率,建议尽量拍平结构、拆分成多次简单调用
3. 国产模型的中文字段名兼容性:部分模型对中文作为JSON字段名支持不佳,建议统一用英文字段名+中文描述(description)
4. 流式输出时的JSON解析:结构化输出配合流式传输时,需要在客户端做增量JSON解析(如使用 json-stream 类库),不能简单等首字返回后再拼接
实战建议
- 生产环境务必加上 Pydantic(或对应语言的schema校验库)做二次校验,不要完全信任模型输出
- 对关键业务字段设置合理的重试策略:解析失败时自动重试1-2次,仍失败则降级到更强约束的模型(如切换到GPT-5 Structured Outputs)
- 尽量选择原生支持强约束结构化输出的模型作为核心链路,弱约束模型仅用于非关键路径
总结
结构化输出的可靠性直接决定了 AI 应用能否稳定跑生产。优先选择原生支持 Schema 强约束的模型(GPT-5系列、Gemini系列),弱约束场景务必配合代码层校验和重试机制兜底。
想了解更多AI API错误处理与调试技巧,可以查看站内 AI API 错误处理与调试完全指南,或访问 openairouter.net 对比各中转站对结构化输出的支持程度。