结构化输出与 JSON
结构化输出用于约束模型返回可解析的 JSON。你可以要求模型返回普通 JSON 对象, 也可以要求它严格符合指定的 JSON Schema, 从而减少正则兜底、重复重试和额外后处理。
两种模式
通过在 对话请求 请求中设置 response_format,即可选择输出模式。
| 模式 | 适用场景 | 配置 |
|---|---|---|
| JSON 对象 | 需要返回合法 JSON,结构可以相对灵活。 | {"type": "json_object"} |
| JSON Schema | 需要返回严格、可校验的结构(推荐)。 | {"type": "json_schema", "json_schema": { … }} |
verified
优先使用 JSON Schema。
Schema 会在解码阶段参与约束,输出不仅是合法 JSON,也会尽量符合你声明的字段和类型要求。
JSON 对象模式
JSON 对象模式最容易接入,模型会返回一个合法 JSON,但具体字段结构由模型自行决定。 使用时请在提示词中明确包含 “JSON” 一词,并尽量说明你期望的字段。
如下以 Python 和 cURL 为例展示了如何请求模型返回一个 JSON 对象,以及如何解析响应。
import json, os
from openai import OpenAI
client = OpenAI(base_url="https://api.wylon.cn/v1", api_key=os.environ["WYLON_API_KEY"])
resp = client.chat.completions.create(
model="moonshotai/kimi-k2.5",
response_format={"type": "json_object"},
messages=[
{"role": "system", "content": "仅以 JSON 回复。"},
{"role": "user", "content": "列出三个北欧国家的首都及其人口。"},
],
)
data = json.loads(resp.choices[0].message.content)
print(data)
curl https://api.wylon.cn/v1/chat/completions \
-H "Authorization: Bearer $WYLON_API_KEY" -H "Content-Type: application/json" \
-d '{
"model": "moonshotai/kimi-k2.5",
"response_format": {"type": "json_object"},
"messages": [{"role":"user","content":"以 JSON 格式列出三个北欧首都。"}]
}'
JSON Schema 模式
JSON Schema 模式需要提供完整的 Schema。
模型在生成时会受到结构约束,保证每个字段、类型、枚举值都保证匹配。
更适合数据抽取、表单填充、工作流编排、RPC 风格调用,以及任何你计划 json.loads() 并直接信任结果的场景。
如下以 Python 和 Node.js 为例展示了如何请求模型返回一个符合 JSON Schema 的对象,以及如何解析响应。
from pydantic import BaseModel
from openai import OpenAI
import os
class Capital(BaseModel):
city: str
country: str
population: int
class Capitals(BaseModel):
items: list[Capital]
client = OpenAI(base_url="https://api.wylon.cn/v1", api_key=os.environ["WYLON_API_KEY"])
resp = client.chat.completions.create(
model="moonshotai/kimi-k2.5",
messages=[{"role": "user", "content": "三个北欧首都及其人口。"}],
response_format={
"type": "json_schema",
"json_schema": {
"name": "capitals",
"schema": Capitals.model_json_schema(),
"strict": True,
},
},
)
parsed = Capitals.model_validate_json(resp.choices[0].message.content)
for c in parsed.items: print(c.city, c.population)
import OpenAI from "openai";
import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";
const Capital = z.object({ city: z.string(), country: z.string(), population: z.number().int() });
const Capitals = z.object({ items: z.array(Capital) });
const client = new OpenAI({ baseURL: "https://api.wylon.cn/v1", apiKey: process.env.WYLON_API_KEY });
const resp = await client.chat.completions.create({
model: "moonshotai/kimi-k2.5",
messages: [{ role: "user", content: "三个北欧首都及其人口。" }],
response_format: {
type: "json_schema",
json_schema: { name: "capitals", schema: zodToJsonSchema(Capitals), strict: true },
},
});
const parsed = Capitals.parse(JSON.parse(resp.choices[0].message.content));
{
"type": "json_schema",
"json_schema": {
"name": "capitals",
"strict": true,
"schema": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"city": { "type": "string" },
"country": { "type": "string" },
"population": { "type": "integer" }
},
"required": ["city", "country", "population"],
"additionalProperties": false
}
}
},
"required": ["items"],
"additionalProperties": false
}
}
}
最佳实践
- 在提示词中也描述结构。Schema 约束结构,提示词决定字段内容是否符合业务语义。
- 优先选择 JSON Schema 对象。严格结构可以减少解析错误和异常分支。
- 尽量扁平化深层嵌套的联合类型。 相比深层嵌套或复杂联合类型,扁平记录通常更稳定。
- 明确标注必填字段。 在 JSON Schema 中准确使用
"required", 不要依赖模型自行判断字段是否可省略。 - 先用小模型评估抽取任务。许多结构化抽取任务不一定需要最强模型,可先在验证集上评估
fast档模型以控制成本。