如何让大模型稳定输出 JSON:结构化输出、JSON 模式与提示词写法(OpenAI / Claude)

怎么让大模型稳定输出 JSON?本文按 OpenAI 和 Anthropic 官方文档讲清只靠提示词、JSON 模式、结构化输出三种做法的可靠程度,两家的写法与 Schema 限制,以及拒答和截断两种例外。

NNathaniel bigo··原创首发·AI 辅助撰写
8 分钟读完
资料核对于 2026-10-11 · 依据官方文档与公开资料整理 其他 账号

适用于谁

  • 搜「如何让大模型稳定输出 json」「llm 结构化输出」「让模型输出结构化 json」的人;
  • 程序里解析模型返回的 JSON 时,隔三差五遇到多了一段解释、少了一个字段、括号没闭合的人。

本文根据 OpenAI 和 Anthropic 的官方文档整理,资料核对于 2026-10-11。Gemini 的做法见站内《Gemini 结构化输出怎么用》。

结论先说

  1. 有三个可靠程度不同的层级:只靠提示词要求 < JSON 模式 < 结构化输出。
  2. 能用结构化输出就用它。它用你提供的 JSON Schema 约束生成过程,保证结果符合 Schema。OpenAI 的原话是建议「只要可能,就用结构化输出而不是 JSON 模式」。
  3. JSON 模式只保证「是合法 JSON」,不保证字段对。
  4. 结构化输出也有两种情况会不符合 Schema:模型出于安全原因拒答,以及输出被长度上限截断。这两种都要在代码里判断。
  5. Claude 的旧办法「预填充」已经不能用了。官方文档说明,从 Claude 4.6 系列起,在最后一条 assistant 消息里预填内容会返回 400 错误,要改用结构化输出。

三个层级的区别

只靠提示词JSON 模式(OpenAI)结构化输出
输出是合法 JSON大多数时候是是
符合你指定的字段和类型不保证不保证是
需要自己校验和重试需要需要一般不需要(拒答和截断除外)
适用聊天界面、不支持该功能的模型较旧的模型支持的模型,优先选择

OpenAI 列出的结构化输出的三个好处:类型可靠,不用再校验和重试格式错误的回答;拒答可以被程序识别;提示词更简单,不需要用很重的措辞去强调格式。

Anthropic 的说法类似:不用结构化输出时,即使提示词写得很仔细,仍可能遇到 JSON 语法错误、缺少必填字段、数据类型不一致;结构化输出通过约束解码来保证结果符合 Schema。

步骤

OpenAI:结构化输出

用官方 SDK 时,最省事的方式是用 Pydantic(Python)或 Zod(JavaScript)定义结构,交给 parse 方法:

python
from openai import OpenAI
from pydantic import BaseModel

client = OpenAI()

class Invoice(BaseModel):
    seller: str
    total: float
    items: list[str]

response = client.responses.parse(
    model="模型名",          # 换成官方模型列表里支持结构化输出的模型
    input=[
        {"role": "developer", "content": "从用户提供的文本里提取发票信息。"},
        {"role": "user", "content": "……发票文字……"},
    ],
    text_format=Invoice,
)
print(response.output_parsed)

官方文档里的几条规则:

  • 结构化输出有两种形式:用在函数调用里,或者用作回答的格式。要把模型接到你的工具、函数、数据上,用函数调用;只是想让模型按固定结构回答用户,用回答格式;
  • 支持的是 JSON Schema 的一个子集。支持的类型有字符串、数字、布尔、整数、对象、数组、枚举和 anyOf;字符串可以加 pattern 和若干预定义的 format(如 date-time、email、uuid);
  • 官方给 Schema 设计的建议:键名清楚直观;给重要的键写清楚标题和描述;用评测来确定哪种结构最适合你的场景。

JSON 模式是更基础的版本,把格式设为 json_object 即可开启。两条官方的重要提醒:

  • 必须在对话里明确要求模型输出 JSON(比如写在系统消息里)。不写的话,模型可能一直输出空白字符直到用完 token 上限;
  • 它只保证能解析,不保证符合任何特定结构,需要你自己用校验库检查并重试。

Claude:结构化输出

Anthropic 文档描述的流程是三步:定义 Schema → 放进请求的 output_config.format(type 为 json_schema)→ 从返回的文本内容块里读取符合 Schema 的 JSON。用 SDK 时,推荐的方式是把 Pydantic 模型传给 client.messages.parse():

python
from anthropic import Anthropic
from pydantic import BaseModel

client = Anthropic()

class ContactInfo(BaseModel):
    name: str
    email: str
    plan_interest: str

response = client.messages.parse(
    model="模型名",          # 换成官方文档列出的支持模型
    max_tokens=1024,
    messages=[{"role": "user", "content": "……邮件正文……"}],
    output_format=ContactInfo,
)
print(response.parsed_output)

Claude 这边同样有两种形式:JSON 输出(output_config.format)和严格工具调用(工具定义里加 strict: true),可以一起用。

官方列出的 Schema 限制,写 Schema 时最容易踩的几条:

  • 对象的 additionalProperties 必须设为 false;
  • 不支持数值范围约束(minimum、maximum、multipleOf)和字符串长度约束(minLength、maxLength);
  • 不支持递归的 Schema;数组的 minItems 只支持 0 和 1;
  • 用了不支持的特性会直接返回 400 错误,并说明原因。

范围和长度这类约束,写进字段的描述里让模型遵守,再在代码里校验。

两家都要处理的例外

即使开了结构化输出,下面两种情况的返回仍可能不符合 Schema:

情况OpenAI 怎么判断Claude 怎么判断
模型出于安全原因拒答输出内容的类型为 refusalstop_reason 为 refusal(HTTP 状态码仍是 200)
输出被长度上限截断响应状态为 incomplete,原因是 max_output_tokensstop_reason 为 max_tokens

处理办法:拒答时按业务逻辑提示用户;截断时调高输出上限后重试。

Claude 文档还有两个细节值得知道:一是不保证枚举值的大小写完全一致,比较时最好先统一大小写;二是不要在 Schema 里设一个让模型「写出思考过程」的字段,可能触发拒答,官方建议改成要一段简短的说明。

不能用结构化输出时:提示词写法

在聊天界面里,或者用的模型不支持这个功能时,只能靠提示词。尽量做到这几点:

  1. 给出完整的示例,而不是只描述。把期望的 JSON 原样贴出来,字段名、类型、嵌套关系一目了然;
  2. 明确边界:「只输出 JSON,不要任何解释,不要用代码块包裹」。Anthropic 文档给出的消除开场白的写法是:直接回答,不要以「以下是……」「根据……」这类话开头;
  3. 规定缺失值怎么填:找不到的字段填 null,不要编造,也不要省略键;
  4. 用标签包住输出:让模型把 JSON 放在 <json> 标签里,程序只取标签内的内容;
  5. 代码里做兜底:解析失败时把报错信息连同原输出发回去让模型修正,最多重试两三次。

示例:

从下面的招聘信息中提取字段,严格按示例的 JSON 结构输出。
只输出 JSON,不要解释,不要用代码块。找不到的字段填 null。

示例:
{"company": "某某科技", "position": "数据分析师", "city": "杭州",
 "salary_min": 15000, "salary_max": 25000, "remote": false}

招聘信息:
<posting>
[粘贴内容]
</posting>

常见问题

Q:结构化输出会让回答质量变差吗?

官方文档没有给出这样的结论。需要注意的是字段顺序:两家文档都说明输出会按 Schema 里定义的顺序生成字段(Claude 另注明必填字段排在可选字段之前)。所以把「依据」这类字段排在「结论」字段前面,通常更合理。

Q:字段很多、嵌套很深可以吗?

两家都对 Schema 的复杂度有上限,具体数字以官方文档为准。能拆成两次调用的,不要硬塞进一个巨大的 Schema。

Q:为什么以前在 Claude 上用的「预填一个左花括号」不灵了?

Anthropic 文档说明:从 Claude 4.6 系列模型起,不再支持在最后一条 assistant 消息里预填充,带预填充的请求会返回 400 错误。官方给的迁移方向就是结构化输出,或者先直接要求模型按结构输出,新模型在这方面已经相当可靠。

Q:国产模型、本地模型怎么办?

看各自的文档是否提供 JSON 模式或结构化输出参数。兼容 OpenAI 接口的服务不一定完整支持,以实际返回为准;不支持时用上面的提示词写法加代码校验。

参考资料

  • OpenAI 文档:Structured model outputs — https://developers.openai.com/api/docs/guides/structured-outputs
  • Anthropic 文档:Structured outputs — https://platform.claude.com/docs/en/build-with-claude/structured-outputs
  • Anthropic 文档:Prompting best practices(Migrating away from prefilled responses)— https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices
需要开通或续费?ChatGPT Plus 充值 →

Nathaniel 的更多内容

  1. 01

    promptfoo 使用教程:对比提示词和模型、写断言自动评测(安装与配置)

    promptfoo 是什么、怎么使用?按官方 README 和入门文档讲清它的用途、三种安装方式、用示例项目起步、promptfooconfig.yaml 里提示词、模型和测试用例三部分怎么写、常用断言类型的含义、eval 与 view 两条命令,以及把它放进日常改提示词流程的方法。

    ChatGPT其他 AI 工具0
  2. 02

    Kimi API怎么用:API Key获取、Python调用、K3价格与429报错处理

    Kimi API Key 在哪里获取、怎么用 Python 调用 K3、价格怎么算、429 和 401 报错怎么办?本文按 Kimi API 开放平台官方文档讲清注册认证、创建 Key、base_url 与模型名、计费规则和常见错误排查。

    Kimi0
  3. 03

    Cursor Agent 模式怎么用:Agent、Plan、Ask 三种模式,检查点回滚与消息排队

    Cursor Agent 模式是什么、和 Plan / Ask 模式怎么选?按官方文档讲清 Agent 能调用哪些工具、Shift+Tab 切换模式、Plan 模式先出方案再动手、用检查点撤销改动、任务进行中排队或插话,以及 /goal 长目标。

    Cursor0
  4. 04

    Gemini 聊天记录怎么导出:导出到文档 / 表格、生成 PDF 与用 Takeout 批量导出完整对话

    Gemini 没有「一键导出全部对话」的按钮,但有三条官方路径:单条回答导出到 Google 文档、Gmail、表格;让 Gemini 直接生成 PDF、Word、Markdown 文件;用 Google Takeout 批量下载全部活动记录。本文给出每种方法的步骤和限制。

    Gemini0
  5. 05

    ChatGPT 生成图片中文乱码、文字错误怎么办:7 个按顺序试的办法

    让 ChatGPT 做海报、封面、信息图,中文总是缺笔画、错字、乱码?本文按 OpenAI 官方图像提示指南,给出从写法、字数、局部修改、质量档位到后期排版的 7 个办法,以及什么时候干脆别让 AI 写字。

    ChatGPT0
  6. 06

    OpenCode Skills 使用指南:技能目录、命名规则、权限配置与不加载排查

    OpenCode 的 Skills 放在哪个目录、怎么控制哪些技能能用?按 OpenCode 官方文档讲清六个扫描位置、name 的正则规则、skill 工具的工作方式、在 opencode.json 里用 allow / deny / ask 配置权限、按智能体覆盖,以及技能不出现时的五项检查。

    其他 AI 工具0

同产品的其他教程

  1. 01

    Cursor、Claude Code、Codex、GitHub Copilot 有什么区别:按形态、账号、计费和规则文件对比

    Cursor 和 Claude Code 的区别是什么、和 Codex、GitHub Copilot 怎么选?只用各家官方文档的事实对比:产品形态、用什么账号、怎么计费、能选哪些模型、规则文件与 MCP、权限模式、代码审查;不做「谁更强」的排名,给出按场景选择的思路。

    ClaudeCursor0
  2. 02

    npx skills add 怎么用:从 GitHub 安装 Skill、skills.sh 是什么与常用命令

    网上的 Skill 安装命令大多是 npx skills add 开头,它是什么、装到哪去了?按官方 README 讲清 skills 命令行工具支持的来源写法、项目与全局两种范围、-a 指定工具、list / find / update / remove 等命令、软链接与复制的区别,以及怎么关掉遥测。

    Claude其他 AI 工具0
  3. 03

    提示词里的角色设定有用吗:「你是一位专家」该怎么写才有效(官方文档怎么说)

    提示词开头写「你是一位资深专家」到底有没有用?本文按 Anthropic、OpenAI、Google 官方文档讲清角色设定管什么、不管什么,一句话角色和详细人设各自适合什么场景,角色应该放在哪里,以及比「你是专家」更有效的四个写法。

    ChatGPTClaude0
  4. 04

    提示词链(Prompt Chaining)怎么用:把复杂任务拆成几步,前一步的输出交给后一步

    提示词链是什么、什么时候该把大提示词拆开?本文按 Anthropic 和 Google 官方文档讲清拆指令、串成链、分块聚合三种拆法,最常用的「起草 → 审查 → 修改」链,以及哪些情况不必拆。

    ClaudeGemini0
  5. 05

    OpenAI API 价格怎么看、余额怎么查:按 token 计费、用量与预付额度

    OpenAI API 按 token 计费,价格页上的 input、cached input、output、Batch、Flex、Fast 分别是什么意思?余额在哪里看、自动充值怎么关、额度会不会过期、怎么设支出上限?本文按官方价格页和帮助中心逐项讲清,不列具体单价,以官方页面为准。

    ChatGPT0
  6. 06

    Claude Code 切换模型:/model 命令、模型别名、effort 与 fast 模式

    Claude Code 怎么切换模型?讲清 /model 命令与选择器、opus / sonnet / haiku / fable / opusplan 等别名、默认模型、推理强度 effort 怎么调、ultrathink、fast 模式,以及换了模型下次又变回去的原因。

    Claude0

0 条评论

登录 后参与评论

还没有评论,来抢沙发~