结构化输出
当 下游是代码(写入数据库、触发工单、喂给下一个节点)时,「看起来像 JSON 的散文」不够。结构化输出 把输出合同从自然语言升级为 schema:缺字段、多字段、类型不对,应在 API 层失败,而不是在业务里 silently 错下去。
概念上你仍在写提示词:schema 是 机器可执行的「输出格式」。提示词负责语义(不要编造 owner);schema 负责形状(priority 只能是那几个枚举)。
JSON 只是形状,schema 才是合同
口头要求「只返回 JSON」常见失败:
- 前后包了 ```json 围栏或一句「好的,如下」
- 字段时有时无
- 数字写成字符串
- 幻觉出一个文档里没有的键
更稳的层次:
LangChain 1.0 里对应 response_format=YourModel 或 with_structured_output(见 模型与消息)。Dify 工作流则用「解析节点 / 结构化输出」接在生成后面。
先写人能读的 schema
把这段同时放进提示词 和 代码里的模型类。两处不一致时,以代码为准,并改提示词——否则 评估 会永远红。
最小 Pydantic + OpenAI 示例
下面用 Responses API 的 parse(Chat Completions 的 parse 同一思路:把 Pydantic 类交给 SDK)。模型名以你账号里可用的为准。
提示词仍然必要:text_format 不会教模型「不要编造 owner」。schema 保证 owner 要么是字符串要么是 null,不保证 null 用得对。
解析失败时 重试或走人工,不要用正则从散文里「抢救」一半字段——那会把评估基准打烂。
提示词怎么配合 schema
有 structured output 通道时,不要再要求「用 Markdown 详细分析 + 同一条消息里再给 JSON」。一次调用一个合同。需要分析过程:要么用厂商的 reasoning / 隐藏思维通道,要么拆成两步(先分析文本,再结构化)。
常见误用
- 用 JSON 当散文容器(一个巨大的
notes字段里什么都有)——你并没有结构化 - 枚举过于细(40 个优先级)——模型会乱跳;先粗后细
- 把密钥、身份证放进抽取目标——能抽不等于该存;见 陷阱