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

| 做法 | 写法 | 可靠程度 |
|---|---|---|
| 提示词里要求 | 「请只返回 JSON,格式如下……」 | 大多数时候可以,但偶尔会多出解释文字、用错字段名 |
| JSON 模式 | response_format: {"type": "json_object"} | 保证是合法 JSON,但字段由模型自己决定 |
| JSON Schema | response_format: {"type": "json_schema", ...} | 按你给的结构生成,字段名和类型都固定 |
能用 JSON Schema 就用 JSON Schema。
写一个 Schema

例子:从一段简历文字里抽出姓名、工作年限和技能。
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,下面几种情况仍然会发生,代码里要处理:
- 被截断:输出太长触发了长度上限,
finish_reason是length,JSON 不完整。办法:调大输出上限,或让抽取的内容少一点。 - 拒答:内容触发了安全策略,模型可能返回拒绝说明,而不是你的 JSON。
- 值不合理:结构对了,但内容不对,比如年限算错。这需要业务规则来校验。
一个稳妥的写法:
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。