# 结构化输出

> 用 response_format 约束模型输出 JSON,以及解析失败时该怎么兜底。

需要机器可读的结果时,用 `response_format` 约束输出格式,而不是在提示词里写「请只输出 JSON」。

## JSON 对象模式

```python
resp = client.chat.completions.create(
    model="gpt-5.4-mini",
    messages=[{"role": "user", "content": "把「张三,28 岁,北京」抽成 JSON"}],
    response_format={"type": "json_object"},
)
print(resp.choices[0].message.content)   # {"name":"张三","age":28,"city":"北京"}
```

<Callout type="warn" title="json_object 要求提示词里提到 JSON">
OpenAI 协议要求 `json_object` 模式下提示词中出现 "JSON" 字样,否则部分模型会报错。
更稳妥的是用 JSON Schema 模式。
</Callout>

## JSON Schema 模式

```python
schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "age": {"type": "integer"},
        "city": {"type": "string"},
    },
    "required": ["name", "age", "city"],
    "additionalProperties": False,
}

resp = client.chat.completions.create(
    model="gpt-5.4-mini",
    messages=[{"role": "user", "content": "把「张三,28 岁,北京」抽成结构化数据"}],
    response_format={"type": "json_schema", "json_schema": {"name": "person", "schema": schema, "strict": True}},
)
```

## 解析失败怎么办

即使有 schema 约束,也建议在客户端保留一层容错:

1. 先 `json.loads`,失败则把**原始文本**与错误信息一起回填给模型,让它只修格式
2. 仍失败则降级为「返回原始文本 + 人工确认」
3. 不要把解析失败的输出当成空结果静默丢弃 —— 用户会以为模型没回答

## 模型支持差异

- 支持 `json_schema` 严格模式的模型对字段类型、必填项约束最可靠
- 只支持 `json_object` 的模型仍可能在字段名或类型上偏离
- 不支持任何 `response_format` 的模型,只能在提示词里约束,并依赖上面的容错

选型参考[模型](/zh/models/)页。
