结构化输出完全指南
为什么需要结构化输出
LLM 返回自由文本不可靠——下游代码无法安全解析。结构化输出(JSON Schema / Pydantic Model)让 LLM 输出可预测、可校验、可直接消费。这是 Agent 系统和数据流水线的基础能力。
主流方案对比
| 方案 | 原理 | 可靠性 | 适用场景 |
|---|---|---|---|
| Prompt 约束 | 指令要求输出 JSON | 低 ~60% | 快速原型 |
| JSON Mode | API 层强制 JSON 格式 | 中 ~85% | 单层结构 |
| Function Calling | 通过工具声明约束输出 | 高 ~95% | Agent 系统 |
| 约束解码 | Grammar/FSM 限制 Token 生成 | 极高 ~99% | 生产关键路径 |
JSON Mode 使用
// OpenAI
{ "response_format": { "type": "json_object" } }
// DeepSeek
{ "response_format": { "type": "json_object" } }
// Anthropic — 用工具声明
"tools": [{
"name": "respond",
"input_schema": {
"type": "object",
"properties": { ... },
"required": [...]
}
}]
Function Calling 方案
将输出结构定义为工具声明,LLM "调用工具" 来输出结构化数据。天然支持 Schema 校验、嵌套对象、枚举约束。
tools: [
{
name: "output_result",
parameters: {
type: "object",
properties: {
summary: { type: "string" },
confidence: { type: "number", min: 0, max: 1 },
categories: { type: "array", items: { type: "string" } },
action: { type: "string", enum: ["approve", "reject", "review"] }
},
required: ["summary", "confidence", "action"]
}
}
]
约束解码(黄金方案)
在 Token 生成层面限制输出只能匹配预定义 Grammar。代表实现:Outlines(Python)、JSONFormer、Guidance。完美保证输出格式,但需要本地模型或支持 Grammar 的推理引擎(vLLM、llama.cpp)。
# Outlines 示例
from outlines import generate
schema = {
"type": "object",
"properties": { "name": {"type": "string"} }
}
generator = generate.json(model, schema)
result = generator("Extract the name from: ...")
实践建议
- 优先用 Function Calling:API 原生支持,可靠且简单
- 总是设 required:Schema 中注明必填字段,避免 LLM 遗漏
- 加二次校验:输出后 JSON.parse + Zod/Pydantic 校验,失败时重试
- 枚举代替自由文本:能用 enum 就别让 LLM 自由发挥
- 嵌套扁平化:过深嵌套容易让 LLM 出错,最多 2-3 层