Skip to content
A · AI 应用开发入门第 3 课⏱ 15 分钟

结构化输出:让模型稳定返回 JSON

学完你能
  • 说清楚「在提示词里要 JSON」和「JSON Schema 约束」的区别
  • 用 response_format 拿到一定能解析的 JSON
  • 在代码里校验结果,失败时重试或降级
用模具约束模型稳定产出结构化结果
用模具约束模型稳定产出结构化结果AI 生成配图

做应用时,模型的输出往往要交给程序:存数据库、填表单、调别的接口。这时你需要的是格式固定的 JSON,而不是一段自然语言。

三种做法 ​

三种输出方式像三条不同分拣通道
三种输出方式像三条不同分拣通道AI 生成配图
做法写法可靠程度
提示词里要求「请只返回 JSON,格式如下……」大多数时候可以,但偶尔会多出解释文字、用错字段名
JSON 模式response_format: {"type": "json_object"}保证是合法 JSON,但字段由模型自己决定
JSON Schemaresponse_format: {"type": "json_schema", ...}按你给的结构生成,字段名和类型都固定

能用 JSON Schema 就用 JSON Schema。

写一个 Schema ​

严格Schema像模具限定字段与类型
严格Schema像模具限定字段与类型AI 生成配图

例子:从一段简历文字里抽出姓名、工作年限和技能。

json
{
  "name": "resume",
  "strict": true,
  "schema": {
    "type": "object",
    "properties": {
      "name": { "type": "string", "description": "姓名" },
      "years": { "type": "integer", "description": "工作年限" },
      "skills": { "type": "array", "items": { "type": "string" } }
    },
    "required": ["name", "years", "skills"],
    "additionalProperties": false
  }
}
  • strict: true 时,模型严格按这个结构输出:字段不多也不少,类型一致。
  • 严格模式下,所有字段都要写进 required,并且 additionalProperties: false。想表达「可以没有」,就把类型写成 ["string", "null"]。
  • description 会被模型看到,写清楚每个字段的含义,抽取会更准。

动手:抽取简历信息 ​

改改下面这段简历再运行,看输出的结构是不是一直不变:

▶ 动手试试
系统提示词(这次请求一起发送,点开查看)
从用户给的简历文字里抽取信息。
登录后运行登录 HiveGPT 后每天有免费运行次数
示例输出(之前运行的结果)
{
  "name": "张三",
  "years": 6,
  "skills": ["Go", "Redis", "Kafka", "PostgreSQL", "大模型应用开发"]
}

对应的代码:

python
import json, os
from openai import OpenAI

client = OpenAI(base_url="https://hivegpt.cn/v1", api_key=os.environ["HIVEGPT_API_KEY"])

RESUME_SCHEMA = {
    "name": "resume",
    "strict": True,
    "schema": {
        "type": "object",
        "properties": {
            "name": {"type": "string"},
            "years": {"type": "integer"},
            "skills": {"type": "array", "items": {"type": "string"}},
        },
        "required": ["name", "years", "skills"],
        "additionalProperties": False,
    },
}

resp = client.chat.completions.create(
    model="gpt-5.5",
    messages=[
        {"role": "system", "content": "从用户给的简历文字里抽取信息。"},
        {"role": "user", "content": "张三,2019 年毕业后一直做后端开发……"},
    ],
    response_format={"type": "json_schema", "json_schema": RESUME_SCHEMA},
)
data = json.loads(resp.choices[0].message.content)
print(data["name"], data["years"], data["skills"])

结果还是要校验 ​

即使用了 Schema,下面几种情况仍然会发生,代码里要处理:

  1. 被截断:输出太长触发了长度上限,finish_reason 是 length,JSON 不完整。办法:调大输出上限,或让抽取的内容少一点。
  2. 拒答:内容触发了安全策略,模型可能返回拒绝说明,而不是你的 JSON。
  3. 值不合理:结构对了,但内容不对,比如年限算错。这需要业务规则来校验。

一个稳妥的写法:

python
def extract(text, retries=1):
    for attempt in range(retries + 1):
        resp = client.chat.completions.create(...)  # 同上
        choice = resp.choices[0]
        if choice.finish_reason == "stop":
            try:
                data = json.loads(choice.message.content)
                if 0 <= data["years"] <= 60:   # 业务规则
                    return data
            except (json.JSONDecodeError, KeyError, TypeError):
                pass
    return None  # 交给人工或者走降级逻辑

小结 ​

  • 要给程序用的输出,用 response_format 加 JSON Schema,不要只靠提示词。
  • 严格模式:全部字段进 required,additionalProperties: false。
  • 依然要检查 finish_reason、解析失败和业务规则,失败时重试一次或降级。

下一课更进一步:不只是「按格式回答」,而是让模型决定调用你的哪个函数、传什么参数,这就是 Function Calling。

代码示例在页面里运行时使用 HiveGPT 的模型接口。延伸阅读来自 JavaGuide(Apache-2.0),版权归原作者。