结构化输出与 JSON
将模型输出约束为可解析的 JSON — 无论是任意 JSON 对象, 还是严格符合 JSON Schema 的值。 不再需要正则兜底、重试循环或后处理。
两种模式
通过在对话补全请求中设置 response_format 来选择模式。
| 模式 | 适用场景 | 配置 |
|---|---|---|
| JSON 对象 | 需要有效 JSON,但结构灵活。 | {"type": "json_object"} |
| JSON Schema | 需要严格、经校验的结构(推荐)。 | {"type": "json_schema", "json_schema": { … }} |
verified
优先使用 JSON Schema。Schema 在解码阶段通过受控解码强制执行,
输出不仅是合法 JSON,而且保证符合该 Schema。
JSON 对象模式
最简单的模式 — 模型返回它自选结构的合法 JSON。 请始终在提示词中包含 “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。模型在解码时受文法约束,因此每个字段、类型、枚举值都保证匹配。
适用于数据抽取、RPC 风格调用,以及任何你计划 json.loads() 并直接信任结果的场景。
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
}
}
}
最佳实践
- 在提示词中也描述结构。文法约束保证语法正确,而提示词决定语义质量。
- 优先选择 JSON Schema 而非 JSON 对象。严格模式能消除一整类解析错误。
- 扁平化深层嵌套的联合类型。模型对扁平记录比深层可辨识联合生成得更干净。
- 显式标注可选字段。在 JSON Schema 中精确使用
"required"— 不要依赖模型自行省略字段。 - 先尝试更小的模型。许多抽取任务并不需要前沿推理 —
可先在验证集上对
fast档模型做评测以降本。