当代码读取模型的回答时,“大致符合预期的形状”就是一个 bug。结构化输出提示词是一整套实践,目的是让模型每次都返回你的程序能够解析的数据:明确定义的格式、显式的约束,以及验证。
可靠性的三个层级
| 层级 | 做法 | 保证 |
|---|---|---|
| 仅提示词 | 在提示词中描述格式 | 无。通常正确,有时不对 |
| JSON 模式 | 让 API 返回 JSON 响应 | 有效的 JSON,但不一定符合你的 schema |
| schema 约束的输出 | 向 API 提供 JSON Schema | 输出符合 schema |
使用服务商提供的最强层级。OpenAI、Anthropic 和 Google 都提供了把响应约束到某个 schema 或某个工具输入 schema 的方式。在每个层级上提示词仍然重要,因为 schema 控制输出的形状,而提示词控制它的内容。
在提示词中写出输出约束
说明格式、字段、类型和允许的取值。然后说明哪些内容不得出现。
Extract the order details from the email in the tags.
Return a JSON object with exactly these fields:
- "order_id": string, as written in the email
- "items": array of {"name": string, "quantity": integer}
- "total": number, without currency symbol
- "currency": one of "USD", "EUR", "GBP"
If a field is not present in the email, use null.
Return only the JSON object, with no explanation and no code fence.
<email>
{{email}}
</email>
这个提示词中的四个细节能避免大多数失败:
- “恰好这些字段” 阻止模型好心地添加额外内容。
currency的允许取值避免出现“US dollars”和“$”。- null 规则给了模型一种正确表示“未找到”的方式,使它不会编造值。
- “只返回 JSON” 去掉了会破坏
JSON.parse的那句说明性文字。
为模型设计 schema
schema 是提示词的一部分。模型会把字段名和描述当作指令来读。
- 按内容给字段命名。
shipping_address比addr2好。 - 为含义不明显的字段添加描述,包括单位和格式:“ISO 8601 日期,UTC”。
- 凡是字段有固定取值集合的,使用枚举。
- 保持扁平。 嵌套过深会增加错误。把非常复杂的提取拆分成串联的提示词。
- 把推理放在答案之前。 如果你既要解释又要结论,把字段顺序设为
"reasoning"然后是"verdict"。模型按顺序写字段,所以先写的推理可以影响结论。
不止 JSON
结构化输出并不只有 JSON。
- 带固定标题的 Markdown 适合给人阅读的回答:“恰好使用这些标题:摘要、风险、后续步骤。”
- XML 风格的标签很容易用正则表达式提取,并且允许其中包含自由文本:
<answer>…</answer>。 - 单个 token 是所有格式中最可靠的。做分类时,只要求返回标签。
- CSV 或表格适用于小而规整的数据;遇到自由文本时,引号规则会变得脆弱。
选择能承载信息的最简单格式。
篇幅和内容约束
输出约束同样涵盖大小和风格:
- At most 3 bullet points, each under 20 words.
- Use only facts from the document. If the document does not say, write "not stated".
- Write in the present tense.
用数字给出大小。“简短”不是解析器或版式可以依赖的约束。
始终进行验证
即使使用了 schema 约束的输出,在使用数据之前也要验证。
- 解析并检查每个响应的 schema。 响应在达到输出 token 上限时可能被截断,留下不完整的 JSON。
- 检查 schema 无法表达的语义:总额等于各项之和,日期不在未来。
- 决定失败路径。 带上验证错误重试一次,然后回退到备选方案或标记人工审核。
- 永远不要盲目执行结构化输出。 会变成 SQL 子句、文件路径或 shell 参数的字段,需要与用户输入同样的净化。参阅提示词安全。
常见失败模式
| 失败 | 原因 | 修正 |
|---|---|---|
| JSON 前后有文字 | 没有“只”的指令 | 添加该指令,或使用 JSON 模式 |
| 被包在代码块里 | 模型的习惯 | 写明“不要代码块”,或在代码中剥离 |
| 编造的值 | 没有处理缺失数据的规则 | 添加 null 或“未说明”规则 |
| 多余的字段 | 措辞开放 | 写明“恰好这些字段”;禁止额外属性 |
| 输出被截断 | 达到输出上限 | 提高上限或拆分任务 |
| 枚举拼写不一致 | 没有列出取值 | 列出允许的取值 |
运行前检查提示词
在为代码供给输入的提示词中,缺少输出格式是最常见的发现。PromptFlowEngine 提示词分析器会报告它,同时报告缺少篇幅要求和未加分隔的变量。JSON 提取模板是一个通过所有检查的完整示例。
关于它如何融入应用代码,请参阅面向开发者的提示词工程。