大模型JSON模式输出:从调用到解析的完整配置指南
很多人在调用大模型API时,希望直接拿到JSON格式的结果,方便程序解析入库。
但模型有时会在JSON前后加说明文字,导致json.loads报错。
本文以兼容OpenAI接口的模型为例,说明如何正确开启JSON模式并稳定解析输出。
先确认你的模型和接口是否支持JSON模式
不是所有模型都支持强制JSON输出。
通常需要在请求体里设置response_format参数,并且模型本身要支持该特性。
你可以先查看所用平台的API文档,确认模型名称和参数说明。
一个典型的请求结构如下:
import requests
url = "https://你的API地址/v1/chat/completions"
headers = {
"Authorization": "Bearer 你的API_KEY",
"Content-Type": "application/json"
}
data = {
"model": "你的模型名称",
"messages": [
{"role": "system", "content": "你是一个只输出JSON的助手。"},
{"role": "user", "content": "提取以下文本中的人名和年龄,输出JSON对象,包含name和age字段。文本:张三今年30岁。"}
],
"response_format": {"type": "json_object"}
}
resp = requests.post(url, headers=headers, json=data, timeout=30)
print(resp.status_code)
print(resp.text)
如果返回状态码为200,并且choices[0].message.content是一个合法的JSON字符串,说明配置成功。
如果返回400或提示参数不支持,需要检查模型是否支持json_object类型。
提示词里必须明确要求输出JSON
即使开启了JSON模式,部分模型仍可能输出非JSON内容。系统提示词或用户提示词中要明确要求“只输出JSON,不要包含任何解释文字”。
例如:
你是一个JSON生成器。请根据用户输入提取信息,严格按以下格式输出,不要添加任何额外文字:
{"name": "", "age": 0}
同时,在用户消息里给出具体字段和类型,减少模型自由发挥的空间。
拿到响应后如何安全解析
建议在代码里做两层处理:先检查响应状态和内容是否为空,再尝试json.loads。
如果解析失败,打印原始内容便于排查。
import json
content = resp.json()["choices"][0]["message"]["content"]
try:
result = json.loads(content)
print(result["name"], result["age"])
except json.JSONDecodeError as e:
print("JSON解析失败:", e)
print("原始内容:", content)
如果原始内容包含Markdown代码块标记(如`json),说明模型没有严格遵守指令,可以尝试降低temperature参数(例如设为0),或在提示词中强调“不要使用代码块”。
常见报错与避坑说明
- 返回400,提示
response_format不支持:确认模型版本是否支持JSON模式,部分旧模型或非OpenAI兼容接口可能不支持该参数。 - JSON解析失败,内容前后有说明文字:检查提示词是否明确要求只输出JSON,并尝试在系统消息中重复强调。
- 字段缺失或类型不对:在提示词中给出示例JSON,并说明每个字段的类型(字符串、数字、布尔值)。
- 中文乱码:确保请求头
Content-Type为application/json,响应内容按UTF-8解析。
验证输出是否稳定
建议用同一段提示词连续调用3到5次,观察每次返回的content是否都能被json.loads成功解析,且字段齐全。
如果偶尔失败,记录失败时的原始内容,调整提示词或参数后重试。
生产环境中,可以在解析失败时加入一次重试逻辑,但不要无限重试。
如果模型持续输出非JSON内容,可以退一步:让模型输出纯文本,再用正则或固定分隔符提取,但这会增加维护成本。
优先使用官方支持的JSON模式参数。
适用条件与限制
JSON模式适合需要结构化数据的场景,如信息抽取、表单生成、接口返回。
但它不保证字段值一定符合业务规则,仍需在代码层做校验。
另外,不同厂商对JSON模式的支持程度不同,具体参数名和可用模型请以所用平台的API文档为准。
如果你在配置过程中遇到其他报错,可以先检查请求体格式和模型名称是否拼写正确,再对照平台文档核对参数。