结构化输出
问题
如何让 LLM 可靠地输出结构化数据(JSON、XML)?有哪些约束生成的技术?
答案
一、为什么需要结构化输出
LLM 默认生成自由文本。但在应用开发中,下游系统需要可解析的结构化数据(JSON、函数调用参数等)。
二、实现方式
| 方式 | 可靠性 | 原理 |
|---|---|---|
| Prompt 指令 | 低~中 | 在 Prompt 中要求 JSON 格式 |
| JSON Mode | 中 | API 参数保证输出为合法 JSON |
| Structured Output | 高 | 提供 JSON Schema,约束解码 |
| Function Calling | 高 | 工具调用接口,自动结构化 |
三、OpenAI Structured Output
from openai import OpenAI
from pydantic import BaseModel
class MovieReview(BaseModel):
title: str
rating: float
summary: str
pros: list[str]
cons: list[str]
client = OpenAI()
response = client.beta.chat.completions.parse(
model="gpt-4o",
messages=[
{"role": "user", "content": "分析电影《盗梦空间》"}
],
response_format=MovieReview, # 传入 Pydantic 模型
)
review = response.choices[0].message.parsed
print(review.title) # "盗梦空间"
print(review.rating) # 9.3
约束解码原理
在每一步 Token 生成时,根据 JSON Schema 只允许合法的 Token——例如在 "rating": 之后只允许数字 Token。这从根本上保证了输出格式的正确性。
四、Anthropic Tool Use
Claude 通过 Tool Use 实现结构化输出:
tools = [{
"name": "analyze_sentiment",
"description": "分析文本情感",
"input_schema": {
"type": "object",
"properties": {
"sentiment": {"type": "string", "enum": ["positive", "negative", "neutral"]},
"confidence": {"type": "number"},
"keywords": {"type": "array", "items": {"type": "string"}}
},
"required": ["sentiment", "confidence"]
}
}]
五、最佳实践
| 实践 | 说明 |
|---|---|
| 优先用 API 约束 | Structured Output / Function Calling |
| Pydantic 定义 Schema | 类型安全、自带验证 |
| 添加描述 | Schema 中的 description 帮助模型理解字段含义 |
| 设置 enum | 有限选项用 enum 约束 |
| 加验证层 | 即使有约束,仍应验证输出值的合理性 |
常见面试问题
Q1: JSON Mode 和 Structured Output 的区别?
答案:
- JSON Mode:保证输出是合法 JSON,但不保证 Schema 正确(可能缺字段、类型错误)
- Structured Output:保证符合指定的 JSON Schema——字段名、类型、必填项全部正确
- Structured Output 使用约束解码实现,reliability 从约 90% 提升到接近 100%