Schema 优先的 AI 开发:在编写提示词之前先定义输出契约
大多数团队发现 Schema 问题的方式都是错误的:下游服务开始返回乱码,仪表盘充斥着垃圾数据,经过 20 分钟的调试才发现,LLM 在三周前就开始悄悄地将其 JSON 包装在 Markdown 代码块中。没人注意到,因为应用程序没有崩溃 —— 它只是在静默地消耗格式错误的数据。
修复方法只是修改了一行提示词。但造成的损失是数周的错误分析和一次非常尴尬的复盘。
Schema-first 开发是防止这种情况发生的准则。这意味着在你编写任何提示词 Token 之前,先定义 LLM 输出必须遵循的确切结构。这并不是为了限制创造力;而是将输出格式视为下游系统可以依赖的契约,就像你在编写消费者端代码之前会先对 REST API 进行版本化一样。
你已经在支付的 15% 隐形税
原始的 JSON 提示词(告知模型“返回一个包含 这些字段的 JSON 对象”)在生产环境中的失败率在 15% 到 20% 之间。失败并不总是显而易见的。它们包括:
- Markdown 包装:模型添加了
json代码块标识,导致大多数 JSON 解析器拒绝。 - 尾部逗号:语法上无效的 JSON,严格的解析器会捕捉到,而宽松的解析器则会静默地生成畸形数据。
- 幻觉字段:模型添加了 Schema 中不需要的“有用”额外键值,破坏了强类型反序列化。
- 字段重命名:根据模型的训练分布,
user_id变成了userId或id。 - 解释性文本:在左大括号之前出现了诸如“这是 JSON:”之类的开场白。
每一次这类失败都会触发重试。重试会让你的 Token 消耗翻倍甚至翻三倍。在大规模应用下, 15% 的失败率不仅是可靠性问题,更是成本问题。
解决方案不是更好的提示词,而是基础设施层的 Schema 强制执行。
Schema-First 究竟意味着什么
Schema-first 开发意味着你在设计提示词之前,先用正式的 Schema 语言指定输出契约。Schema 驱动下游的一切:验证逻辑、反序列化模型、下游消费者和错误处理。
这种工作流程逆转了典型的顺序。大多数团队先写提示词,观察输出,然后修补解析代码来处理模型选择的任何格式。Schema-first 团队则相反:他们定义 Schema,从中生成提示词结构,并将 Schema 视为单一事实来源。
在实践中 ,这表现为在编写任何关于输出格式的系统提示词指令之前,先定义 Pydantic 模型 (Python)、Zod schema (TypeScript) 或 JSON Schema 对象。Schema 捕捉了应用程序实际需要的:特定字段名、确切类型、枚举约束、必填 vs 可选字段。然后,该 Schema 会被直接传递给推理 API 或在生成时强制执行它的验证库。
行为上的差异是巨大的。没有 Schema,模型决定格式。有了 Schema,模型的 Token 生成被限制为有效的 Schema 实例 —— 从结构上就不可能产生格式错误的输出。
Schema 强制执行的三个层级
Schema 强制执行存在于一个光谱上。了解针对哪种工作负载使用哪一层是大多数团队犯错的地方。
提示词级别的 Schema 定义是最弱的形式。你在系统提示词中描述 Schema,并依赖模型来遵循它。这就是导致 15–20% 失败率的原因。仅将其用于由人工审查输出的低风险、非自动化流水线。
API 级别的结构化输出是中间层。OpenAI 的 response_format(配合 strict: true)、Anthropic 的结构化输出以及 Google Gemini 的 response_schema 都在模型 API 级别强制执行 Schema 合规性。OpenAI 的内部测试显示,他们的结构化输出将 Schema 违规率从(早期模型处理复杂 Schema 时的)近 60% 降到了 0.1% 以下。这是大多数生产工作负载的正确默认选择。你将 JSON Schema 直接传递给 API,不合规的输出在到达你的应用程序之前就会被拒绝。
受限解码 (Constrained decoding) 是最深的一层,适用于你控制推理基础设施的情况。像 vLLM 的引导解码(由 XGrammar 后端驱动)、Outlines 和 HuggingFace TGI 的引导生成等工具,在生成过程中直接修改 Token 的概率分布 —— 在每一步中,会违反 Schema 的 Token 都会被完全屏蔽。模型无法产生无效输出;在词汇表级别这在结构上就是不可能的。XGrammar 是目前该领域的先进引擎,在 JSON Schema 上的运行开销几乎为零,比基于有限状态机 (FSM) 的原始方法快 100 倍,并且在实际基准测试中仅增加了约 0–2% 的生成延迟。对于云端 API 结构化输出失败率仍然过高的自托管工作负载,受限解码完美地填补了这一空白。
Schema 设计即推理架构
这是一个大多数团队都会忽略的深刻见解:Schema 的结构直接影响模型的推理质量,而不仅仅是输出格式。
LLM 从左到右生成 Token。Schema 中字段的顺序就是模型确定值的顺序。这意味着字段排序是你推理架构的一部分。
如果你先放 category(类别)再放 reasoning(推理),模型会先选择一个类别,然后为其寻找合理化的理由。如果你先放 reasoning 再放 category,模型会在确定分类之前先分析问题。在处理复杂任务时,第二种顺序的表现可靠地优于第一种 —— 你已经将思维链(Chain-of-thought)植入了 Schema 本身。
- https://openai.com/index/introducing-structured-outputs-in-the-api/
- https://platform.openai.com/docs/guides/structured-outputs
- https://python.useinstructor.com/
- https://blog.vllm.ai/2025/01/14/struct-decode-intro.html
- https://arxiv.org/pdf/2411.15100
- https://medium.com/@rentierdigital/json-prompting-is-dead-why-your-revolutionary-llm-technique-is-actually-a-15-failure-rate-in-f74162a2c60e
- https://pydantic.dev/articles/llm-intro
- https://simonwillison.net/2025/Feb/28/llm-schemas/
- https://techbytes.app/posts/agent-first-api-design-pattern-autonomous-llm-consumers/
- https://palospublishing.com/designing-llm-friendly-schemas-for-structured-data/
