
为什么模型总爱加废话
大模型本质是「接着写」,你让它返回 JSON,它很可能顺手补一句「以下是结果」再给 JSON,或者直接包在 Markdown 代码块里。下游 json.loads 一碰就报错。要稳定,得用约束而不是靠 prompt 祈求。
办法一:response_format(最稳)
OpenAI 兼容接口原生支持 json_object 模式,DeepSeek / 通义 / 本地 vLLM 大多也支持。模型被强制只输出合法 JSON。
from openai import OpenAI
client = OpenAI()
r = client.chat.completions.create(
model="gpt-4o-mini",
response_format={"type": "json_object"},
messages=[{"role": "user", "content": "提取订单:买了3个A和2个B"}]
)
import json
print(json.loads(r.choices[0].message.content))办法二:函数调用(天然结构化)
把字段定义成 tool 的 schema,模型把参数填进 arguments,出来就是 JSON,连格式都帮你保证。
tools = [{"type": "function", "function": {
"name": "save_order",
"parameters": {
"type": "object",
"properties": {
"items": {"type": "array", "items": {"type": "object",
"properties": {"name": {"type": "string"}, "qty": {"type": "integer"}}}},
"total": {"type": "number"}
},
"required": ["items"]
}
}}]
r = client.chat.completions.create(model="gpt-4o-mini", tools=tools,
tool_choice="auto", messages=[{"role": "user", "content": "订单:3个A 2个B"}])
print(r.choices[0].message.tool_calls[0].function.arguments)办法三:schema 校验 + 重试兜底
即使有 json_object,字段也可能缺。用 pydantic 校验,失败就重试,最多 3 次。
from pydantic import BaseModel, ValidationError
class Order(BaseModel):
items: list
total: float
def parse(completion):
for _ in range(3):
try:
return Order(**json.loads(completion))
except (json.JSONDecodeError, ValidationError):
continue
raise ValueError("解析失败")几个坑
- json_object 模式要求 prompt 里明确「你要返回 JSON」,否则会拒答。
- 函数调用返回的是字符串,记得 json.loads。
- 超大结构用流式拼接再整体解析,别逐 token 解析。