精选·提示工程

如何保证大模型输出严格的 JSON 格式?结构化输出有哪些手段?

91学AI·2026/7/13·12 阅读

考察点

这是阿里系面试题库里出现过原题的高频题(「如何设计一个 Prompt,确保模型输出严格的 JSON 格式」)。面试官想看的分层很清楚:只会答「在 Prompt 里要求输出 JSON」的是初级;能讲出约束解码原理、解析失败兜底策略的才是做过生产的。追问方向:模型还是输出非法 JSON 怎么办、Function Calling 和 JSON mode 什么区别。

参考答案

第一档:Prompt 层约束

基础但必要。三件事:给出完整 JSON Schema 或字段清单;给一个输入输出示例(few-shot 对格式对齐效果极好);加负面指令——「不要输出 JSON 以外的任何文字,不要用 markdown 代码块包裹」。其中第三条很重要,模型特别爱在 JSON 外面套 ```json 栅栏或者加一句「以下是结果」。

Prompt 层能到 95% 以上的合规率,但剩下的几个百分点对程序集成是致命的——json.loads 一次失败就是一次线上异常。所以它只是起点。

第二档:API 层能力

  • JSON mode:OpenAI、通义千问等主流 API 都提供 response_format={"type": "json_object"},服务端保证输出是合法 JSON(保证语法合法,不保证字段符合你的 Schema)。
  • Function Calling / Tool Use:把目标结构定义成工具的 parameters Schema,模型输出结构化参数。这本质是让模型走训练时专门强化过的结构化通道,合规率比裸 Prompt 高得多,还能拿到字段级的类型保证。
  • 约束解码(Constrained Decoding):最强的一档。vLLM 的 guided decoding、Outlines、lm-format-enforcer 这类方案,把 JSON Schema 编译成状态机,解码时每个 token 位置只允许符合 Schema 的词表子集——从机制上 100% 合法,不可能输出非法 JSON。代价是可选 token 被剪枝,对生成质量有轻微影响,且需要自建推理服务才能用。

第三档:解析端兜底

不管前面用了哪档,消费端都假设输出可能坏,这是工程师的基本素养:

  1. 预处理:截取第一个 { 到最后一个 } 之间的内容,剥掉代码块栅栏。
  2. Schema 校验:用 Pydantic(Python)或 zod(TS)做字段级校验,类型错误、缺字段、枚举越界都能拦下来,比裸 json.loads 能发现问题。
  3. 修复重试:校验失败时,把报错信息和原始输出一起回喂给模型让它修——「你上次输出缺了字段 reason,请只输出修正后的完整 JSON」。一次重试能救回绝大部分失败 case,重试两次还失败就走降级(人工队列或默认值)。
  4. 监控:格式失败率是个重要指标,Prompt 或模型版本变更后要盯它的回归。

设计层面的两个建议

Schema 尽量扁平。 嵌套三层以上的 JSON 出错率明显上升,能拍平就拍平;字段名用含义明确的英文,别用 abc

枚举值先在 Prompt 里穷举。 分类字段把可选值全部列出来并说明含义,否则模型会自造标签。我们踩过的坑:要求输出「投诉/咨询/建议」三选一,模型输出「complaint」,格式合法但下游路由直接崩。

可能的追问

  • Function Calling 和 JSON mode 有什么区别? JSON mode 只保证合法 JSON;Function Calling 有 Schema 约束、字段级类型保证,且模型在训练时对工具调用格式专门强化过,合规率更高。需要严格结构优先 Function Calling。
  • 约束解码会影响模型智力吗? 会有一点点——剪枝限制了模型的表达路径,复杂推理任务里可能感觉输出变「僵」。常见做法是推理内容自由生成,只在最终答案字段上约束。
  • 流式输出场景怎么解析 JSON? 用增量 JSON 解析器(partial json parser)逐段拼装,或者改协议——SSE 按字段事件推送。别等流结束再解析,失去流式的意义了。

评论 (0)

暂无评论,快来抢沙发吧!

91学AI

© 2026 91学AI · 按岗位学 AI 与大数据. All rights reserved.