2025年底的共识是:想把 LLM 真正用到生产里,几乎绕不开“结构化输出”这一关。

目前主流的几种实现方式(由弱到强)

方式 可靠性 实现难度 代表工具/技术 备注
纯提示词工程 ★☆☆☆☆ 写 “必须用 JSON 格式输出,不要多说一句话” 最简单,但最容易翻车
模型原生支持结构化输出 ★★★☆☆ OpenAI structured outputs, Claude 的 tool use, Gemini 等 2024-2025年大模型厂商陆续都加了这个功能,比较推荐的入门方式
代码侧后处理 + 重试 ★★★★☆ Instructor (Pydantic + 重试 + 修复) 目前 Python 社区最受欢迎的生产方案之一
约束解码 / 引导生成 ★★★★★ Outlines, Guidance, jsonformer 等 最强保证,几乎不可能输出非法格式(靠有限状态机/grammar 强制)

为什么它对生产级 LLM 应用这么重要?

  1. 下游系统才能可靠对接(解析不出 JSON → 整个链路崩)
  2. 减少幻觉(很多实验表明约束输出格式后,模型胡编乱造的概率显著下降)
  3. 能做复杂信息提取(合同、发票、病例、法规、简历、日志…… → 结构化字段)
  4. Agent / Function Calling / Tool Use 的基础(Agent 要调用工具,必须先结构化输出参数)
  5. RAG / 知识库构建(干净的结构化 chunk 质量远高于纯文本)、

Instructor

Instructor 比较好理解,发现结果不符合规则,则重试,重试几次即可。

Outlines

这里Outlines 就比较奇特了,从表格可以看到Outlines 比Instructor 优秀太多了,那么它是如何做到的呢 ?

维度 Instructor Outlines
保证程度 很高(靠重试) 100%(生成时强制)
延迟 & token 消耗 可能翻倍(重试) 几乎不变
兼容性 最好(几乎所有 API 厂商) 很好(最好本地/vLLM/ollama)
实现难度 ★☆☆☆☆ 最简单 ★★☆☆☆ 稍复杂
对小模型友好度 一般(function calling 弱) 优秀
适用场景 快速原型、API 模型、复杂 Pydantic 生产级、本地部署、高可靠性需求
社区热度(2026) 最高(下载量第一) 增长最快(硬核用户多)

核心解决思路:

在 LLM 每生成一个 token 前,就用有限状态机 + logits 屏蔽的方式,强制只允许生成符合 schema 的下一个 token。 比如 JSON 要求下一个必须是 { 或 [,就直接把其他 token 的概率设为 0。

具体来说,当模型要生成下一个 token 时,Outlines 做了什么?
  1. 模型先正常算出所有 token 的 logits(原始分数,代表模型认为每个 token 有多大概率)。
  2. Outlines 拿到当前生成进度(用有限状态机 FSM 表示),计算出此时此刻,哪些 token 是合法的(能让输出继续保持在 schema 轨道上)。
  3. 所有不合法的 token,直接把它们的 logit 值设为 -∞(或者等效地概率设为 0)。
  4. 模型只能从剩下的合法 token 集合里采样/选下一个 token。

→ 所以模型永远不可能输出一个会让 JSON 崩掉的 token(比如在应该写 “ 的地方写 ,,或者在对象里突然写数字开头)。

可以看到 Outlines是和模型深度耦合的,所以只有支持 logits processor 的模型才能使用 Outlines。而很多闭源大模型不支持 logits processor。