LLM API 结构化输出跨服务商指南:JSON Mode、JSON Schema 及各家实际支持情况(2026)
跨服务商结构化输出 (response_format) 实战指南,覆盖 OpenAI、Anthropic、DashScope、DeepSeek 和 SiliconFlow。我们详解 json_object 模式、json_schema 严格模式、Anthropic 的 output_config、流式输出交互、schema 深度限制以及多服务商路由时的兼容性问题。
让 LLM 返回有效 JSON 听起来简单——直到你在五家服务商上同时尝试。一家提供严格 schema 约束解码,另一家支持 json_object 但不支持 json_schema,第三家用的参数名完全不同。当你通过网关路由同一个请求时,结构化输出参数能不能被正确翻译,也是个问题。
我们每天通过 OpenAI、Anthropic、DashScope、DeepSeek 和 SiliconFlow 路由结构化输出请求。本文详细记录了每家服务商实际支持什么,兼容性问题在哪里,以及如何构建一个不管哪家服务商处理请求都能拿到可靠 JSON 的生产管线。
OpenAI 兼容指供应商提供一个 chat-completions 接口,其请求与响应结构与 OpenAI API 契约足够接近——只需替换三个值(API key、base URL、模型名),原来的 OpenAI SDK 调用即可直接工作。最小实践面是POST /v1/chat/completions 带 messages、model, 并返回 OpenAI 形式的流式响应。
速查对比表
| 服务商 | json_object | json_schema(严格) | 原生参数 | 需要 prompt 含 "json" | 流式 + 结构化 |
|---|---|---|---|---|---|
| OpenAI | 是 | 是(受约束解码) | response_format | 仅 json_object | 是 |
| Anthropic | 否(用 output_config) | 是(基于语法) | output_config.format | 否 | 是 |
| DashScope | 是 | 否(仅 json_object) | response_format | 是 | 是 |
| DeepSeek | 是 | 否(仅 json_object) | response_format | 是 | 是 |
| SiliconFlow | 是(取决于模型) | 否 | response_format | 是(推荐) | 是 |
核心结论:只有 OpenAI 和 Anthropic 通过受约束解码提供 schema 保证的结构化输出。DashScope、DeepSeek 和 SiliconFlow 支持 json_object 模式——JSON 语法有效性有保证,但 schema(字段名、类型、嵌套结构)并不在 token 级别强制执行。你拿到的是有效 JSON,但不是保证 schema 合规的 JSON。
底层原理
了解 json_schema 和 json_object 的本质区别,有助于做出正确的技术选择。
JSON Object 模式(type: "json_object")告诉模型输出有效 JSON。服务商约束 token 生成,使输出可被解析——大括号匹配、字符串正确引用等。但模型可以返回任意有效 JSON 结构。如果你期望 {"name": string, "age": number},可能得到 {"full_name": "Alice", "years_old": 25}。有效 JSON,但 schema 不对。
JSON Schema 模式(type: "json_schema")使用有限状态机进行受约束解码,在 schema 中追踪当前位置。每生成一个 token,模型只能生成在当前 schema 位置有效的 token。结果保证匹配你的 schema——不仅是有效 JSON,而是你指定的确切结构。
这个区别对生产系统至关重要。使用 json_object 时仍需应用层验证;使用 json_schema 时服务商替你处理。
OpenAI:完整的结构化输出方案
OpenAI 提供最完整的结构化输出实现。通过 response_format 参数提供两种模式。
JSON Object 模式(已过时)
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
model="gpt-5.6",
messages=[
{"role": "system", "content": "提取事件详情,返回 JSON。"},
{"role": "user", "content": "Alice 和 Bob 周五中午见面吃午饭。"}
],
response_format={"type": "json_object"}
)
# JSON 有效性有保证,但 schema 未被强制执行
data = json.loads(response.choices[0].message.content)
消息中必须包含 "json" 一词,否则 API 会报错。输出是有效 JSON 但不一定匹配特定 schema。
JSON Schema 模式(推荐)
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-5.6",
input=[
{"role": "system", "content": "提取事件信息。"},
{"role": "user", "content": "Alice 和 Bob 周五要去参加科技展。"}
],
text_format=CalendarEvent,
)
event = response.output_parsed # CalendarEvent 实例,schema 保证合规
关键信息:
- 受约束解码 — 模型在 token 级别无法生成违反 schema 的内容
- 支持的模型 — GPT-4o 及以后版本,包括 GPT-5.6
- Schema 特性 — 嵌套对象、数组、枚举、可选字段、
anyOf/allOf - 拒绝处理 — 如果模型拒绝请求,
response.refusal会被设置;output_parsed为None - 流式输出 — 支持流式;分片拼装后的结果 schema 有效
Schema 限制:所有字段必须为 required(用 nullable 类型表示可选),additionalProperties 必须为 false,递归 schema 有深度限制。
来源:OpenAI 结构化输出指南(检索日期 2026-08-04)
Anthropic Claude:基于语法的 output_config
Anthropic 采用不同的方案。Claude 使用独立的 output_config 参数,配合基于语法的受约束解码。
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-4-6",
max_tokens=1024,
messages=[
{"role": "user", "content": "从以下文本中提取实体:会议在周二 Google 总部举行。"}
],
output_config={
"format": "json",
"schema": {
"type": "object",
"properties": {
"entities": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string"},
"type": {"type": "string", "enum": ["person", "org", "location", "date"]},
"confidence": {"type": "number", "minimum": 0, "maximum": 1}
},
"required": ["name", "type", "confidence"]
}
}
},
"required": ["entities"]
}
}
)
与 OpenAI 的关键区别:
- 参数名 —
output_config,不是response_format。非 OpenAI 兼容。 - 语法在段落间重置 — 使用扩展思考时,语法仅应用于最终响应,不约束思考块。Claude 可以自由推理,再生成结构化输出。
- 不支持
json_object模式 — Anthropic 不支持简单的「给我有效 JSON」模式。要么提供完整 schema,要么用 tool-use 变通。 - 不兼容 — citations 和 prefix-filling(assistant 消息预填)与
output_config不兼容。 - 支持的模型 — Claude Opus 4 和 Claude Sonnet 4.5 及以后版本。
来源:Anthropic 结构化输出博客(检索日期 2026-08-04)
DashScope(通义千问):通过 OpenAI 兼容 API 使用 json_object 模式
DashScope 通过其 OpenAI 兼容端点支持结构化输出,但仅支持 json_object 模式——没有 json_schema 严格约束。
from openai import OpenAI
client = OpenAI(
api_key="your-dashscope-key",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)
response = client.chat.completions.create(
model="qwen-plus",
messages=[
{"role": "system", "content": "提取用户的姓名和年龄,返回 JSON。"},
{"role": "user", "content": "大家好,我是 Alex Brown,今年 34 岁。"}
],
response_format={"type": "json_object"}
)
# JSON 有效,但 schema 不被强制执行
data = json.loads(response.choices[0].message.content)
关键信息:
- 支持的模型 — Qwen-Max、Qwen-Plus、Qwen-Flash、Qwen-Turbo、Qwen-Coder、Qwen-Long(均为非思考模式)。多模态模型(Qwen-VL、Qwen-Omni)也支持。
- prompt 需含 "json" — 系统消息或用户消息中必须包含 "JSON"(不区分大小写),否则 API 报错。
- 思考模式注意事项 — 思考模式下的模型接受
response_format: json_object不会报错,但部分模型在思考模式激活时可能返回非严格有效的 JSON。 - 不支持
json_schema— DashScope 不支持type: "json_schema"加严格 schema。传入可能被忽略或报错。
来源:DashScope 结构化输出文档(检索日期 2026-08-04)
DeepSeek:仅支持 json_object 模式
DeepSeek 的结构化输出支持与 json_object 方案一致。
from openai import OpenAI
client = OpenAI(
api_key="your-deepseek-key",
base_url="https://api.deepseek.com"
)
response = client.chat.completions.create(
model="deepseek-v4-pro",
messages=[
{"role": "system", "content": "将问答解析为 JSON 格式。"},
{"role": "user", "content": "世界最高的山是什么?珠穆朗玛峰。"}
],
response_format={"type": "json_object"}
)
data = json.loads(response.choices[0].message.content)
关键信息:
- 支持的模型 — DeepSeek V4 Pro、DeepSeek V4 Flash
- prompt 需含 "json" — 与 OpenAI 的
json_object模式相同 - 不支持
json_schema— 仅支持json_object - 推理模型 — DeepSeek-R1 和推理模式对
json_object的支持有限;推理 token 可能干扰 JSON 输出
来源:DeepSeek JSON Output 文档(检索日期 2026-08-04)
SiliconFlow:OpenAI 兼容的 json_object
SiliconFlow 通过其 OpenAI 兼容 API 提供 json_object 支持,但可用性因模型而异。
from openai import OpenAI
client = OpenAI(
api_key="your-siliconflow-key",
base_url="https://api.siliconflow.cn/v1"
)
response = client.chat.completions.create(
model="Qwen/Qwen3-8B",
messages=[
{"role": "system", "content": "以 JSON 格式返回答案。"},
{"role": "user", "content": "列出前三名编程语言。"}
],
response_format={"type": "json_object"}
)
关键信息:
- 取决于模型 — 并非 SiliconFlow 上所有模型都支持
response_format,需查看模型页面 - OpenAI 兼容 — 使用与 OpenAI 相同的
response_format参数 - 不支持
json_schema— 仅json_object模式 - prompt 含 "json" — 推荐包含以获得一致的结果
来源:SiliconFlow Chat Completions API(检索日期 2026-08-04)
多服务商路由的坑
通过 TheRouter 或任何网关路由结构化输出请求时,会出现几个兼容性问题。
1. json_schema 降级
如果请求使用 response_format: {type: "json_schema", json_schema: {...}} 并路由到 DashScope 或 DeepSeek,严格 schema 约束会丢失。网关可以降级为 json_object 并将 schema 注入系统 prompt,但这是尽力而为——模型可能遵循也可能不遵循 schema。
缓解方案: 无论哪家服务商处理请求,都在每次响应后进行应用层 JSON Schema 验证。jsonschema(Python)或 ajv(JavaScript)的延迟可以忽略。
2. Anthropic 参数翻译
Anthropic 用 output_config 而不是 response_format。网关路由到 Claude 时必须翻译参数——并处理 Claude 根本不支持 json_object 模式的事实。网关必须提供完整 schema 或回退到 tool-use。
3. prompt 中的 "json" 要求
OpenAI(json_object 模式)、DashScope 和 DeepSeek 都要求消息中包含 "json"。Anthropic 不要求。如果你的 prompt 不含 "json" 而请求路由到需要它的服务商,API 会报错。
缓解方案: 使用 response_format 时,始终在系统 prompt 中包含 "json"。对于不需要它的服务商也无害。
4. 流式输出 + 结构化输出的交互
所有服务商都支持流式 + 结构化输出,但行为有差异:
- OpenAI — 每个分片是部分 JSON 片段;拼装后的结果 schema 有效
- Anthropic — 流式与
output_config配合工作;语法约束跨分片生效 - DashScope / DeepSeek — 流式产生部分 JSON 分片;只有最终拼装结果保证是有效 JSON
如果你需要增量解析流式分片(如渐进式 UI 更新),需要一个能容忍不完整对象的部分 JSON 解析器。
5. Schema 深度和复杂度限制
OpenAI 的 json_schema 模式有限制:
anyOf最多 5 层嵌套- 每个对象最多约 100 个属性(软限制)
- 所有属性必须为
required(用nullable表示可选) additionalProperties: false是强制的
DashScope 和 DeepSeek 没有 schema 约束,因此没有 schema 限制——但也没有 schema 保证。
生产清单
部署结构化输出到生产环境前的检查:
-
始终在生成后验证 — 即使使用了
json_schema模式,也在应用代码中验证响应是否符合 schema。这能捕获拒绝响应、截断响应和网关翻译错误等边界情况。 -
设置重试策略 — 如果 JSON 解析失败,用更简单的 prompt 或通过回退路由切换到另一家服务商重试。
-
max_tokens设够大 — 在 JSON 生成中途碰到 token 限制会产生无效 JSON。为完整响应预留空间,尤其是深层嵌套 schema。 -
记录原始响应 — 调试 schema 不匹配时,原始响应能显示问题是出在模型、网关翻译还是你的解析代码。
-
在路由池中的所有服务商上测试 — 在 OpenAI 上完美工作的 schema 在 DashScope 上可能产生不同的字段顺序或命名规范。解析代码应能处理字段顺序变化。
-
优雅处理拒绝 — OpenAI 返回
refusal字段。Anthropic 返回stop_reason: "end_turn"和可能为空的内容。DashScope 和 DeepSeek 可能返回文本说明而非 JSON。你的错误处理应考虑所有模式。
TheRouter 集成说明
TheRouter 路由 OpenAI 兼容请求通过配置的服务商,包括结构化输出请求。当请求包含 response_format 时,TheRouter 为支持它的服务商(OpenAI、DashScope、DeepSeek、SiliconFlow)保留该参数。对于 Anthropic,由于参数名和语义不同,翻译遵循服务商特定映射。
如果请求指定了 json_schema 模式而路由到的服务商仅支持 json_object,schema 约束取决于服务商。我们建议无论哪家服务商处理请求,都添加应用层验证作为安全网。
对于回退路由场景——请求在一家服务商失败后在另一家重试——结构化输出参数在重试间被保留。回退服务商可能有不同的 schema 支持级别,因此同样的验证建议适用。
常见错误与修复
| 错误 | 服务商 | 原因 | 修复 |
|---|---|---|---|
messages must contain the word 'json' | OpenAI、DashScope、DeepSeek | json_object 模式但消息中没有 "json" | 在系统 prompt 中加上「返回 JSON」 |
Invalid response_format type | DashScope、DeepSeek | 在仅支持 json_object 的服务商上使用 json_schema | 降级为 json_object + 在 prompt 中描述 schema |
output_config is incompatible with citations | Anthropic | output_config 与 citations 同时使用 | 禁用 citations 或用 tool-use 变通 |
| 截断的 JSON | 所有 | max_tokens 太低 | 增加 max_tokens;为 schema 开销预留缓冲 |
| 有效 JSON 但 schema 不对 | DashScope、DeepSeek、SiliconFlow | json_object 模式不强制 schema | 添加生成后 JSON Schema 验证 |
| 空内容和 stop_reason | Anthropic | 模型拒绝了请求 | 检查是否拒绝;调整 prompt 后重试 |
常见问题
问:推理/思考模型能用 json_schema 模式吗?
取决于服务商。OpenAI 的 o 系列推理模型支持 json_schema。Anthropic 的 output_config 可以与扩展思考并用——语法仅应用于最终响应,不约束思考块。DashScope 指出思考模式下的模型即使设置了 json_object 也可能返回非严格有效的 JSON。
问:应该用 tool-use 还是 response_format 来做结构化输出?
当你希望模型的响应本身是结构化 JSON 时,用 response_format(或 Anthropic 上的 output_config)。当你在把模型连接到实际函数或 API 时,用 tool-use。函数调用指南详细介绍了 tool-use 方案。
问:Instructor 或 Outlines 怎么样?
Instructor(Python/TypeScript)和 Outlines(Python)提供跨服务商的框架级结构化输出。Instructor 封装服务商客户端并添加 Pydantic/Zod schema 验证加自动重试。Outlines 对本地模型使用语法受约束解码。两者都可用于生产,但增加了依赖层且可能不使用服务商的原生受约束解码。
问:结构化输出与 prompt 缓存如何交互?
在 OpenAI 上,使用相同 json_schema 的请求受益于 prompt 缓存——schema 是缓存前缀的一部分。在 Anthropic 上,output_config 不与 cache_control blocks 交互。在 DashScope 上,json_object 模式的请求通过上下文缓存正常缓存。
最后验证:2026 年 8 月 4 日。服务商 API 持续演进,请查看官方文档获取最新的 schema 支持信息。