3.5 结构化输出的定义与约束

在生产环境中,大语言模型往往不只是作为一个“聊天机器人”存在,而是作为数据处理流水线中的一个节点。为了让下游程序能够解析模型的输出,我们需要模型返回严格的结构化数据(如 JSON、XML 或 YAML),而不是自由格式的自然语言文本。

本节将深入探讨如何通过提示词设计,稳定地获取结构化输出。

3.5.1 主流结构化格式对比

不同格式在解析友好度、Token 消耗和模型适配性上有所差异:

格式
优点
缺点
适用场景

JSON

生态最完善,几乎所有语言原生支持;OpenAI 有特殊优化

括号和引号占用较多 Token;对人类阅读略不友好

API 交互、数据抽取的主力格式

XML

结构清晰;Claude 模型原生偏好

闭合标签占用大量 Token

Claude 模型 任务;长文本分块处理

YAML

Token 消耗最少(免去大量括号大括号);人类可读性极佳

强依赖缩进,模型偶尔会缩进错误导致解析失败

配置生成;复杂层级但不要求 100% 稳定解析的场景

Markdown

最自然的输出方式,几乎不会翻车

解析成结构化数据较复杂(需要正则或专用解析器)

表格生成;直接面向最终展示的报告

3.5.2 JSON 模式的提示词设计

强制模型输出真实的 JSON 数据,通常需要遵循以下三步法:

1. 明确的输出指令

在系统提示词或指令开头,必须非常坚定地说明输出格式。

❌ 错误示范:
请将结果输出为 JSON。
(模型可能回复:"好的,以下是为您生成的 JSON:\n```json\n...",这包含了多余的自然语言文本。)

✅ 正确示范:
你是一个数据提取 API。请严格以 JSON 格式输出结果。
你的输出必须是合法的、可解析的单一 JSON 对象,不要包含任何自然语言解释,也不要包含 Markdown 代码块标记(如 ```json)。

2. 提供 JSON Schema(模式定义)

通过提供目标 JSON 的结构定义,可以大幅度降低字段遗漏或类型错误的概率。

3. 容错与逃生通道

考虑到模型可能遇到无法处理的情况,必须在 JSON 结构中设计“逃生通道”,避免模型强行捏造数据。

3.5.3 各平台的结构化输出特性

主流模型厂商为了提高结构化输出的稳定性,在 API 层面提供了专属支持:

OpenAI 结构化输出

OpenAI 提供了 response_format 参数。当设置为 json_schema 并且提供严格的 JSON Schema 时,OpenAI 保证 模型的输出 100% 符合该 Schema。 (注:详见 13.1 OpenAI GPT 系列最佳实践)

Anthropic Claude 与 XML

Claude 在大规模训练时使用了广泛的 XML 标签。因此在使用 Claude 时,用 <xml-tag> 来包裹指令和限定输出格式会得到超出预期的效果。

Gemini 与 JSON 约束

Google Gemini 的 API 同样支持传递 JSON Schema 来限定输出格式(responseMimeType: "application/json")。对长文本提取,Gemini 的长上下文窗口结合 JSON 约束非常强悍。

3.5.4 解析错误处理策略

即使提示词设计得再好,普通的 API 调用(未使用强制 Schema 的情况)依然有千分之一的概率输出损坏的格式。在工程实现时,你需要:

  1. 自动清理:使用正则剥离模型可能产生的多余前缀/后缀(例如去除开头结尾的 Markdown 代码块标记)。

  2. 多重重试机制:如果解析(如 json.loads)失败,触发重试。

  3. 反射纠错:将报错信息重新发给 LLM:“你刚才输出的 JSON 在第 14 行缺少逗号导致了解析失败,请修复并重新发送。”

思考

  1. 在你的项目中,如果 LLM 未能返回合法的 JSON,你会如何优雅地降级处理?

  2. 对比 JSON 和 XML,试着将本节 3.5.2 中的 JSON Schema 转换为针对 Claude 模型优化的 XML 格式约束提示词。

最后更新于