为什么需要结构化输出?
AI的输出如果给人看,自然语言就够了。但如果输出要被程序处理——存入数据库、传给下一个API、渲染到页面——就必须是机器可读的结构化格式。否则你的代码要写大量的字符串解析逻辑,脆弱且难维护。
强制JSON输出的3种方法
方法1:Prompt约束(最通用)
从文本中提取以下信息,只输出JSON,不要任何解释:
{
"name": "人名",
"age": 年龄数字,
"city": "城市"
}
文本:张三,28岁,来自上海方法2:JSON Mode(OpenAI/部分国产模型支持)
response = client.chat.completions.create(
model="gpt-4o",
response_format={"type": "json_object"}, # 强制JSON输出
messages=[{"role": "user", "content": "提取人名和年龄..."}]
)方法3:Function Calling(最稳定)
tools = [{
"type": "function",
"function": {
"name": "extract_person",
"parameters": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"city": {"type": "string"}
},
"required": ["name", "age"]
}
}
}]处理非法JSON的容错方案
import json, re
def safe_parse_json(text: str) -> dict:
# 1. 直接解析
try:
return json.loads(text)
except json.JSONDecodeError:
pass
# 2. 提取代码块中的JSON
match = re.search(r'```(?:json)?\s*([\s\S]+?)\s*```', text)
if match:
try:
return json.loads(match.group(1))
except:
pass
# 3. 找最外层的{}
match = re.search(r'\{[\s\S]+\}', text)
if match:
try:
return json.loads(match.group())
except:
pass
return {} # 兜底返回空字典XML vs JSON:选择场景
- JSON:大多数场景首选,轻量、易解析、与现代API天然兼容
- XML:当输出中包含大量HTML/代码等特殊字符时,XML的CDATA可以更安全地包含;也适合与传统系统对接
Markdown结构化输出
当输出要给人读但又需要结构时,Markdown是最好的中间格式:
请按以下Markdown格式输出分析报告:
## 摘要
[2-3句话总结]
## 优点
- 优点1
- 优点2
## 风险
- 风险1
## 建议
[具体操作建议]最终建议:优先用Function Calling(最稳定),不支持时用JSON Mode,都不支持则用Prompt约束+容错解析。