为什么你的 AI 输出格式总是飘移?
如果你的 AI 工作流程经常因为输出格式变动而中断,问题不在你的提示写得不好。你是用错工具处理结构化资料问题。大型语言模型逐个 token 生成文字,「格式」对它来说只是一种模仿出来的模式。没有硬性约束,同一个提示今天回传 JSON、明天回传散文。
实践者最常在串接步骤时注意到这个问题。第一步 AI 产出一个项目清单。第二步本应接收这份清单并执行动作。然后某天一个多余的逗号、一个被改名的键,或一个凭空产生的栏位,就让整条链崩溃。根据 2026 年 DEV Community 一篇针对 LLM 结构化输出的技术报告,用 regex 解析 AI 文字几乎是生产环境 AI 流程每一次可靠性事故的根源。
解法不是写更好的提示,而是在模型层直接约束输出。这正是 JSON Schema 模式(又称 Structured Outputs)的设计目的。一旦启用,模型在数学上就无法生成违反 Schema 的 token。
结构化输出是什么?实际运作原理为何?
结构化输出确保模型每次都产出完全符合你提供的 JSON Schema 的回应。模型不能省略必填栏位、不能凭空增加 Schema 没有定义的键、不能在你要求数字时回传字串。格式在推论阶段透过「受限解码」强制执行。
受限解码是技术机制。每一个 token 生成步骤,执行环境都会检查哪些 token 在当前 Schema 下合法,将不合法的 token 遮蔽。模型只能从合法的子集取样。所以结构化输出不是「模型更努力」,而是模型实质上无法生成违规的输出。
根据 OpenAI 于 2024 年 8 月的官方公告,启用 Structured Outputs 的 GPT-4o-2024-08-06 在复杂 JSON Schema 遵循评测上达到 100% 满分,相对于未启用时的约 40%。同样机制如今已成为各大模型供应商的标配,名称不同但底层原理一致。
核心好处是:你可以把 AI 输出当成一个有型别的物件处理,而不是一堆等待解析的字串。下游程式收到的是你定义好结构的 JSON 物件。这是「稳定运行半年的工作流程」与「每周二崩溃一次的工作流程」之间的差别。
三大供应商如何支援结构化输出?
三大供应商都支援结构化输出,但各自的称呼略有不同。底层机制相似到一个心智模型可以涵盖全部三家。应该根据你已经在用的模型选择,而不是仅凭这项功能。
OpenAI GPT-4o 及之后版本。 透过将 response_format 参数设为 json_schema 并附上你的 Schema 即可启用。GPT-4o、GPT-4o-mini 与后续模型皆支援。Python SDK 对 Pydantic 提供一级支援,意即你写一个 Pydantic class 直接传入即可。根据 OpenAI 2024 年发布的官方 cookbook,这个方式在多数抽取使用情境下已取代 function calling 与旧版 JSON mode。
Google Gemini 1.5 Pro 及之后版本。 透过生成设定中的 responseSchema 启用。Google 在 2026 年初公告所有 Gemini 模型支援完整 JSON Schema 与隐式属性排序。OpenAI 用的同一份 Pydantic 或 Zod 定义可直接沿用。根据 Google 开发者部落格,有序属性对于栏位顺序敏感的抽取任务特别实用。
Anthropic Claude。 透过工具呼叫(tool calling)实作,而非专属参数。你定义一个工具,其 input_schema 即为你想要的 JSON Schema,再强制模型呼叫这个工具,工具呼叫的输入即为你要的结构化资料。机制不同,但可靠性结果一致。
实测 Schema:可直接运作的结构化输出范本
学习结构化输出最快的方式,是拿一个真实的文字抽取任务,为它写一份 Schema。以下是可直接复制贴上 OpenAI playground 或任何呼叫 API 的工具的完整范例。它从一段杂乱的文字(例如电邮签名或 LinkedIn 简介)抽取结构化的联络资讯。
试用以下 Schema:
{ "name": "extract_contact", "schema": { "type": "object", "properties": { "full_name": { "type": "string", "description": "全名,照原样输出" }, "job_title": { "type": "string", "description": "目前职称" }, "company": { "type": "string", "description": "目前任职公司名称" }, "email": { "type": "string", "description": "主要电邮,全部小写" }, "phone_country_code": { "type": "string", "description": "国码含加号,例如 +852" }, "phone_number": { "type": "string", "description": "本地号码,不含国码" }, "linkedin_url": { "type": "string", "description": "完整 LinkedIn URL,若无则回空字串" } }, "required": ["full_name","job_title","company","email","phone_country_code","phone_number","linkedin_url"], "additionalProperties": false }, "strict": true }
搭配一句简单提示「从这段签名抽取结构化联络资料:[贴上签名]」,跑 50 次不同签名。每次的输出都会是包含这 7 个栏位的有效 JSON。空栏位会回传空字串而非省略,这正是 required 加上 additionalProperties: false 所保证的行为。
什么情况该用结构化输出,什么情况不该用?
结构化输出适合以下情境:AI 输出直接喂给自动化下游程式、需要型别保证、或多个系统消费同一份回应。它不适合自由写作、脑力激荡,或任何「文字本身就是价值」的任务。
适合用于文件、电邮、会议记录与网页的资料抽取。经典案例是发票抽取:供应商名称、总金额、到期日、每行明细、税项拆分。根据 OpenAI 结构化输出 cookbook,这个单一使用情境占据生产部署的最大比重。
适合用于分流与分类。客服工单贴上类别、优先级与所需动作标签。销售线索按行业、案值与跟进时程分类。输出直接喂入 CRM 或队列,一致性比表达丰富度更重要。
适合用于建构会执行动作的 AI Agent。每一次工具呼叫都需要严格的输入结构。没有 Schema 强制,Agent 可能在应传数字的地方传字串,或漏掉下一个工具需要的栏位,整条链就停下。
不适合用于第一稿写作、创意发想、给人类阅读的摘要,或对话式互动。把 JSON 强加在这些任务上会破坏自然语言品质,并增加摩擦而没有相应的可靠性回报。
使用 JSON Schema 模式的常见错误是什么?
几乎每个团队第一次尝试结构化输出都会犯三个错误。每个错误都会伪装成不同问题,所以一直反覆出现。提前知道可省下一周除错时间。
第一个错误是把应该设为必填且带空值预设的栏位设为选填。选填栏位可被完全省略,意即下游程式必须处理键缺失情况。所有栏位都设为必填、在描述中注明「无值」时的预设(例如空字串或 0),下游程式会简单得多。
第二个错误是过度设计 Schema。深度巢状物件、条件式 Schema、union 型别都会给模型压力。Schema 应该在下游程式允许的范围内尽可能扁平。根据 2026 年 DEV Community 报告,巢状超过三层的 Schema,失败率明显高于扁平设计。
第三个错误是把 Schema 合法性当成语意正确性。模型可以回传一个结构完全合法、但内含错误订单编号或编造信心分数的 JSON。Schema 强制保证结构,不保证真实性。永远在 Schema 之后加一层语意验证,特别是数字栏位与识别码。
如何把结构化输出整合进真实工作流程?
整合最快的路径是挑一个经常崩溃的现有 AI 流程重做。多数实践者至少有一个:每次掉电话的「电邮转 CRM」步骤、漏掉税码的收据解析器、丢失行动项目的会议记录拆分器。
从用纯 JSON Schema 写出 Schema 开始,先别碰提示。列出下游真正需要的每个栏位、全部标为必填、为每个栏位写一句描述。先定义 Schema 的纪律通常会揭露原本提示要的太多。
用 10 个真实输入跑这个结构化提示。和旧做法比较需要人工修正的数量,落差通常很大。根据 多份 2026 年产业报告,从纯提示抽取改用 JSON Schema 模式的团队,在同一份资料集上失败率从 15 至 25% 降到 1% 以下。
然后加上语意验证。检查抽取的电邮是否符合电邮格式、日期是否可解析、金额是否为正数。结构验证加语意验证的组合,才是真正的生产级 AI。
对香港实践者而言,结构化输出是今年最值得学的高杠杆技术之一。它是「展示时很惊艳」与「真实使用一季仍能存活」的差别。一旦开始用 Schema 思考,你就不再与提示词纠缠。懂AI,更懂你 UD相伴,AI不冷。
📐 打造真正能在生产环境存活的 AI 工作流程
结构化输出只是可靠性堆叠的其中一块。UD 的 AI 工程团队协助香港组织设计能承受真实负载的 AI 流程:以 Schema 为先的思考、验证层、人类介入检查点。我们手把手带你完成每一步:从你的第一份 Schema 到你第一个上线的 Agent。