重要提示:如需以 Markdown 形式查看本页,请在 URL 后追加 `.md`。 完整文档索引见 llms.txt
跳到主要内容
完整文档索引见 llms.txt。 在任意 URL 后追加 `.md` 即可查看该页面的 Markdown 版本。

结构化输出(Structured outputs)

Structured outputs 指的是遵循特定机器可读格式的 LLM 响应,例如 JSON、XML 或由 regex 定义的模式。模型不再生成自由形式的 prose,而是产出可被下游系统直接解析和使用的数据。

下面是一个示例:

{
"name": "LLM Inference Handbook",
"author": "Modular",
"website": "handbook.modular.com",
"summary": "A practical handbook for engineers building, optimizing, scaling, and operating LLM inference systems in production."
}

为什么 structured outputs 很重要?

当你使用 LLM 时,输出通常是自由形式文本。对人类来说,我们可以很容易阅读并理解这些响应。

但如果你正在构建一个更大的、集成了 LLM 的应用(例如把模型响应连接到另一个服务、API 或数据库的系统),你就需要可预测的结构。否则,程序怎么知道该提取什么内容,或者哪个字段应当放到哪里?

这正是 structured outputs 的价值所在。它们为模型提供了清晰、机器可读的格式约束,让自动化和集成更可靠。

例如,你正在构建一个分析助手,用来读取支持工单并为产品团队总结洞察。你希望 LLM 返回:

  • 用户提到的主要问题,
  • 这些问题的频次,
  • 以及整体情绪分数。

如果模型用纯文本回复,比如:

“大多数客户都在抱怨加载速度慢和支付错误。整体语气略显负面。”

这对人类读者当然没问题,但对自动化 dashboard 来说几乎没什么用。你必须手动提取这些洞察,或者编写复杂的解析代码。

现在对比下面这个 structured output:

{
"issues": [
{"topic": "Slow loading", "count": 42},
{"topic": "Payment errors", "count": 31}
],
"sentiment": "negative",
"confidence": 0.87
}

你的系统可以直接解析这份输出,将其存入数据库,并在 dashboard 上可视化数据。整个过程不需要猜测,也不需要后处理。

Structured outputs 现在已经广泛存在于许多真实世界的 LLM 系统中,包括:

  • 信息抽取(Information extraction):把文档中的实体、数字或关系提取为 JSON 或表格。
  • 数据增强(Data enrichment):为 CRM 或分析流水线对记录进行分类、打标签或总结。
  • 函数调用与 API 链接(Function calling and API chaining):让 LLM 选择应调用哪个工具或 endpoint,并以结构化方式传递参数。
  • Agent 编排(Agent orchestration):协调多步骤工作流,其中每一步都消费上一步的输出。
  • 评估与测试(Evaluation and testing):收集一致的响应,用于基准测试模型质量和准确性。
  • 内容审核或合规检查(Content moderation or compliance checks):返回结构化决策,例如 { "action": "flag", "reason": "PII detected" }

如何获得 structured outputs

既然你已经理解了 structured outputs 的重要性,下一个问题就是:到底该如何得到它们?

当然,你可以编写自定义解析逻辑,从模型响应中清洗并提取所需数据。但这种方法很快就会变得混乱。它耗时、易错,并且在大规模场景下非常脆弱。每增加一种格式或规则,你的代码复杂度都会进一步上升。

更好的方法是让 LLM 自身直接生成结构化数据,但并非所有 LLM 都开箱即支持 structured outputs。对于这些模型,你通常需要通过精心设计的 prompt,或者结合某些 framework 的 schema 定义来引导它们。当格式写得足够清晰时(例如使用明确示例或 regular expressions),模型通常可以可靠地产生符合预期结构的输出。

目前,获得 structured outputs 主要有三种方式。

Serverless 模型 API 提供商

使用原生支持 structured outputs 的模型 API,是最容易上手的方式。

像 OpenAI、Anthropic 和 Google 这样的 provider 允许你在 API 调用中直接指定 schema 或 JSON 结构。模型随后会自动生成符合该 schema 的响应。

这个能力最初源自早期的 JSON mode,它只是要求模型以 JSON 格式响应。JSON mode 是能工作的,但一致性不足。模型经常会产生 malformed 或不完整的 JSON。为了解决这个问题,OpenAI 推出了 Structured Outputs,这是一个更严格的系统,通过强制 schema 来确保响应始终匹配定义的结构。

下面是一个使用 OpenAI structured output API 的示例:

from pydantic import BaseModel
from openai import OpenAI

client = OpenAI()

# Define the expected fields with Pydantic
class SupportSummary(BaseModel):
issues: list[str]
sentiment: str
confidence: float

completion = client.chat.completions.parse(
model="gpt-5",
messages=[
{"role": "system", "content": "Summarize support ticket feedback."},
{"role": "user", "content": "The app is terrible! It crashes every time it opens."},
],
response_format=SupportSummary,
)

event = completion.choices[0].message.parsed

通过第三方模型 API 实现 structured outputs 非常直接。你不需要维护自定义解析逻辑,模型会替你处理 schema validation。

不过,这种方式也有一些权衡:

  • Vendor lock-in。你会绑定到某个特定 provider 的 API。
  • Output limits。较大的 payload 可能被截断,导致 JSON 不完整。
  • Inconsistent enforcement。不同 provider 对 schema validation 的处理强度并不一致。

重新提示(Re-prompting)

借助 Instructor 这样的库,re-prompting 是一种简单且有效的 structured outputs 获取方式。

它的工作流程如下:

  1. 你向模型发送一个 prompt,描述期望格式(例如 JSON schema)。
  2. 库会检查响应是否有效。
  3. 如果无效,它会自动重新 prompt 模型,并附带说明哪里出了问题。
  4. 这个过程会重复,直到输出通过验证,或者达到重试上限。

这个循环确保你最终能拿到一个有效的 structured output,而无需自己编写重试逻辑。

它也非常灵活。你可以定义自定义 regex 规则,并强制日期或数字格式。它几乎适用于任何模型或 API provider。

代价是延迟和成本。每次重试都意味着额外的一次模型调用,会增加时间和 token 消耗。如果你的 schema 很复杂,或者模型本身不擅长遵循指令,可能需要多次重试,甚至在耗尽所有尝试后仍然失败。

约束解码(Constrained decoding)

如果你在 self-host open-source LLM,那么 constrained decoding,也就是 structured generation,是生成 structured outputs 最可靠的方法之一。

这种方法不是在输出生成后再做验证,而是在 token 生成过程中直接强制结构。它确保模型只能采样符合你定义格式或 schema 的 token。

底层原理如下:

当 LLM 生成文本时,它会预测每个可能下一个 token 的概率(这些概率通常称为 logits)。在 constrained decoding 中,这些 logits 会被实时修改,移除所有会破坏目标结构的 token。于是模型只能生成有效的后续内容,从而保证最终输出始终符合你的 schema。

这种方法很快,因为它不依赖重试或后处理。它与 open-source 模型配合良好,并被 OutlinesMicrosoft GuidanceXGrammar 等库支持。像 vLLMSGLang 这样的 inference frameworks 已经直接集成了这些工具。

它的主要优势是速度、精度和可靠性。Outlines 团队甚至展示过, structured output can improve LLM performance