Skip to content

Structured Output / JSON Mode

生产级 LLM 应用的第一道门槛:模型输出必须可解析、可验证、可类型化。Structured Output 不是"让模型输出 JSON"这么简单,而是一套从 schema 定义到运行时保证的完整工程体系。

Overview

Structured Output(结构化输出)指强制大语言模型的输出遵循预定义的数据格式(通常是 JSON,也可以是 YAML、XML 或自定义格式)。这是将 LLM 从"文本生成器"转变为"可靠系统组件"的关键技术。

与让模型"尽量输出 JSON"不同,现代 Structured Output 技术通过**约束解码(Constrained Decoding)**在生成阶段就保证输出合法,而非事后解析和重试。

The Problem

python
# ❌ 不可靠:纯文本提示
prompt = "分析这段评论的情感,输出 JSON:{\"sentiment\": \"...\"}"
response = model.generate(prompt)
# 风险:模型输出额外文字、JSON 格式错误、字段缺失、幻觉字段...

# ❌ 脆弱:事后正则提取
try:
    data = json.loads(extract_json(response))
except:
    data = fallback_parse(response)  # 永远不知道会出什么问题

生产环境中的真实问题

  • 模型在 JSON 前后添加解释文字
  • 字符串未正确转义(含换行符、引号)
  • 枚举值超出定义范围
  • 数字字段输出字符串
  • 必填字段缺失
  • 幻觉出 schema 中不存在的字段

Technical Approaches

1. JSON Mode(软约束)

模型在训练时被教导输出合法 JSON,但无运行时保证。

提供商实现可靠性
OpenAI JSON Moderesponse_format: {type: "json_object"}~95% — 偶尔仍有格式问题
OpenAI Structured Outputsresponse_format: {type: "json_schema", schema: ...}~99% — 基于 constrained decoding
Anthropic通过 Prompt + 后处理~90% — 依赖模型遵循指令
Geminiresponse_mime_type: "application/json"~95%

2. Constrained Decoding(硬约束)⭐

在 token 采样阶段限制模型只能生成符合 schema 的 token,从原理上保证输出合法。

实现原理

每步生成时:
  1. 根据已生成的 token 和 schema,计算当前允许的下一个 token 集合
  2. 将不允许的 token 的概率设为 -∞(或 0)
  3. 从允许的 token 中采样

关键优势:100% 保证输出符合 schema(只要实现正确),无需事后验证。

3. 主流 Constrained Decoding 实现

库/框架原理性能开销
Outlines基于正则/EBNF 的 FSM 约束低(预编译 FSM)
GuidanceMicrosoft 的约束语言,上下文无关文法中等
JSON Schema → CFG将 JSON Schema 转为上下文无关文法中等
llama.cpp GrammarGBNF 文法,原生集成在 C++ 推理中极低
vLLM Guided Decoding集成 Outlines,生产级性能
XGrammar高性能 GPU 加速的 structured decoding极低

Schema-Driven Development

Structured Output 推动了 LLM 应用开发范式的转变:

python
# 先定义 schema(Pydantic / Zod / JSON Schema)
class SentimentAnalysis(BaseModel):
    sentiment: Literal["positive", "neutral", "negative"]
    confidence: float = Field(ge=0, le=1)
    topics: list[str] = Field(max_length=5)
    key_phrases: list[str]

# 然后让模型严格输出符合 schema 的数据
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[...],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "sentiment_analysis",
            "schema": SentimentAnalysis.model_json_schema()
        }
    }
)

开发流程变化

  1. 设计数据 schema(而非设计 Prompt 模板)
  2. 用 schema 驱动 Prompt("输出必须符合以下 JSON Schema...")
  3. 运行时自动验证和类型转换
  4. 下游系统直接消费结构化数据

Advanced Patterns

嵌套结构化输出

json
{
  "entities": [
    {
      "name": "OpenAI",
      "type": "organization",
      "attributes": {"founded": 2015, "location": "San Francisco"}
    }
  ],
  "relations": [
    {"from": "OpenAI", "to": "GPT-4", "type": "develops"}
  ]
}

条件字段(OneOf / AnyOf)

根据某个字段的值,后续字段结构变化:

json
{
  "action": "search",
  "params": {"query": "..."}  // action=search 时的参数
}
// 或
{
  "action": "book",
  "params": {"flight_id": "...", "passenger": "..."}  // action=book 时的参数
}

流式结构化输出

逐 token 解析部分 JSON,实现渐进式 UI 更新:

javascript
// 模型正在生成:{"sentiment": "pos...
// 已可解析部分:{sentiment: "positive"}

Benchmark & Reliability

方法格式合规率Schema 合规率延迟影响
纯 Prompt~70%~50%
JSON Mode~95%~80%
Structured Outputs (OpenAI)~99%~95%+5-10%
Outlines (constrained)100%100%+10-20%
llama.cpp Grammar100%100%+0-5%

注:Schema 合规率指不仅 JSON 合法,且字段类型、枚举值、必填约束都满足。

Why It Matters

  • 生产可靠性的底线:没有 Structured Output,LLM 应用就是"概率性正确"的——无法集成到确定性系统中
  • 类型安全的终点:让动态生成的 LLM 输出进入静态类型的下游系统(TypeScript、Pydantic、Go struct)
  • Agent 编排的基础:Function Calling 的参数生成、Agent 状态更新、工具结果解析都依赖 Structured Output
  • 降低 Prompt 复杂度:当 schema 本身定义了输出结构,Prompt 可以大幅简化

Relationships

  • 底层机制:Function Calling / Tool Use — Function Calling 的参数生成是 Structured Output 的最重要应用场景
  • 约束工具:Outlines / llama.cpp — 开源 constrained decoding 的核心实现
  • 应用基础:AI Agents — Agent 的状态管理和工具调用输出都依赖结构化数据
  • 开发范式:Prompt Engineering — Structured Output 是 Prompt Engineering 在工程化方向的延伸
  • 类型系统:与 Pydantic、Zod、JSON Schema 等类型系统深度集成

Open Questions

  • Constrained Decoding 对模型生成质量有负面影响吗?限制 token 选择空间是否会降低输出多样性/创造性?
  • 复杂 schema(深层嵌套、条件字段、递归结构)的约束解码性能如何?当前实现是否可扩展?
  • 多模态结构化输出(图像+JSON、视频+JSON)的 schema 定义和约束方法尚不成熟
  • 当模型需要"思考"后输出结构化结果时,如何分离 reasoning chain 和 final structured output?

Sources

AI Knowledge Base — 持续积累