英伟达发布开源大模型Nemotron 3 Super

用 JSON Schema 拿到稳定的结构化输出:让大模型返回可直接入库的数据

结构化输出 · JSON Schema · Tool Use阅读时间:8 分钟发表时间:2026.07.09
用 JSON Schema 拿到稳定的结构化输出:让大模型返回可直接入库的数据

用 JSON Schema 拿到稳定的结构化输出:让大模型返回可直接入库的数据

本站为独立第三方技术服务平台,提供多模型 API 聚合接入服务,与 Anthropic、OpenAI、Google 等模型提供商无任何关联、授权或合作关系。

TL;DR

  • 让模型"输出 JSON"最脆弱的做法是在 prompt 里求它,返回里常混着 ```json 包裹、解释性文字,json.loads 直接崩。
  • 更稳的做法是用 response_format 传一份 JSON Schema,把字段、类型、必填项都约束死,模型按 schema 填空。
  • Code0 兼容 OpenAI SDK,这套写法对 Claude、GPT、Gemini 等模型都是同一份代码,切模型只改 model 字段。
  • 下面给一个可直接运行的完整示例:从一段自由文本里抽出结构化的"发票信息"。

为什么 prompt 里求 JSON 不靠谱

先看反面教材。很多人一开始这么写:

messages=[{"role": "user", "content": "把下面这段话解析成 JSON:张三,13800000000,北京"}]

模型返回可能是:

  • 前面加一句"好的,解析结果如下:"
  • ```json ... ``` 代码块包起来
  • 多轮调用字段顺序、有无某个键都不稳定

于是你的解析代码就得写一堆正则去剥壳、容错,还是三天两头挂。问题的根源是——你没有给模型一个明确的输出契约

正确姿势:把契约交给 JSON Schema

response_format 支持 json_schema 模式,你把期望的数据结构用 JSON Schema 描述清楚,模型会严格按这个结构返回,返回体本身就是一个干净可解析的 JSON 对象。

前置准备

  1. 注册 Code0 账号:https://console.code0.ai/console/dashboard
  2. 获取 API Key(控制台 → API Keys → 创建)
  3. 安装 SDK:pip install openai

步骤拆解

步骤 1:定义你的数据结构

假设我们要从一段客服消息里抽出下单信息,目标结构是:客户名、电话、商品列表、总金额。先把它写成 JSON Schema:

invoice_schema = {
    "type": "object",
    "properties": {
        "customer_name": {"type": "string", "description": "客户姓名"},
        "phone": {"type": "string", "description": "联系电话"},
        "items": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "quantity": {"type": "integer"},
                    "unit_price": {"type": "number"},
                },
                "required": ["name", "quantity", "unit_price"],
            },
        },
        "total": {"type": "number", "description": "订单总金额"},
    },
    "required": ["customer_name", "items", "total"],
    "additionalProperties": False,
}

required 决定哪些字段必须出现,additionalProperties: False 禁止模型自由发挥加字段——这两项是稳定性的关键。

步骤 2:填写接入参数并发起请求

  • Base URL: https://hk.code0.ai/v1
  • API Key: 粘贴你在控制台获取的 Key
  • Model: claude-opus-4-8gpt-5.4(按需选择)
from openai import OpenAI

client = OpenAI(base_url="https://hk.code0.ai/v1", api_key="sk-你的Key")

resp = client.chat.completions.create(
    model="claude-opus-4-8",
    messages=[
        {"role": "system", "content": "你是订单信息抽取助手,只输出符合 schema 的结果。"},
        {"role": "user", "content": "客户李雷 13900001111,要 2 个保温杯单价 59,1 个笔记本单价 30,一共 148 元。"},
    ],
    response_format={
        "type": "json_schema",
        "json_schema": {"name": "invoice", "schema": invoice_schema, "strict": True},
    },
)

步骤 3:直接解析,无需剥壳

因为返回已经是规整 JSON,直接 json.loads 就能拿到 dict:

import json

data = json.loads(resp.choices[0].message.content)
print(data["customer_name"])          # 李雷
print(len(data["items"]))             # 2
print(data["total"])                  # 148.0

没有 ```json 外壳,没有多余解释,字段结构和你定义的 schema 一致——可以直接入库或往下游传。

完整代码示例(可复制运行)

import json
from openai import OpenAI

client = OpenAI(base_url="https://hk.code0.ai/v1", api_key="sk-你的Key")

invoice_schema = {
    "type": "object",
    "properties": {
        "customer_name": {"type": "string"},
        "phone": {"type": "string"},
        "items": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "quantity": {"type": "integer"},
                    "unit_price": {"type": "number"},
                },
                "required": ["name", "quantity", "unit_price"],
            },
        },
        "total": {"type": "number"},
    },
    "required": ["customer_name", "items", "total"],
    "additionalProperties": False,
}

resp = client.chat.completions.create(
    model="claude-opus-4-8",  # 换 gpt-5.4 / gemini-3-pro 同一套代码
    messages=[
        {"role": "system", "content": "你是订单信息抽取助手,只输出符合 schema 的结果。"},
        {"role": "user", "content": "客户李雷 13900001111,要 2 个保温杯单价 59,1 个笔记本单价 30,一共 148 元。"},
    ],
    response_format={
        "type": "json_schema",
        "json_schema": {"name": "invoice", "schema": invoice_schema, "strict": True},
    },
)

data = json.loads(resp.choices[0].message.content)
print(json.dumps(data, ensure_ascii=False, indent=2))

几个实战建议

  • schema 越具体越稳:给字段加 description、约束好 type,模型的猜测空间越小,结果越可预期。
  • 枚举值用 enum:分类任务里把可选值写进 enum,能避免模型返回同义词导致的对不上号。
  • 多模型横向验证:同一份 schema,把 model 换成不同厂商的模型跑一遍,挑抽取质量最好的那个——这正是一 Key 通模的用处,不用为每家改代码。
  • 必要时再套一层校验:拿到结果后用 pydanticjsonschema 再验一次,生产环境更稳妥。

常见问题

  • Q: 某个模型不支持 json_schema 怎么办? → 退一步用 response_format={"type": "json_object"},或改用 Tool Use 定义函数入参来约束结构。
  • Q: 返回里字段缺失? → 检查 schema 的 required 是否写全,并在 system prompt 里强调"字段必须齐全"。
  • Q: 想换模型对比效果? → 只改 model 字段,其余代码不动。

小结

结构化输出的稳定性,本质是"你有没有给模型一份明确的契约"。用 JSON Schema 把契约写死,比在 prompt 里反复叮嘱可靠得多。在 Code0 上,这套写法对多种模型通用,切模型只是改一个字段——先去控制台拿个 Key,把上面的示例跑起来就有直观感受。具体可用模型与计费口径以 console.code0.ai 控制台为准。