结构化输出 JSON Mode:强制大模型返回合法 JSON

FreeGuideOnline 最新 2026-06-14

什么是 JSON Mode

在与大语言模型交互时,我们常需要模型返回结构化的数据,例如用于后续程序处理、填充数据库或生成配置文件。但默认情况下,模型可能返回带解释性文字的 JSON,或者直接在文本中夹杂 JSON 片段,甚至生成不合法的 JSON(缺少引号、尾随逗号等),导致解析失败。

JSON Mode 是一种强制模型输出合法 JSON 的功能。一旦启用,模型只会输出一个完整的 JSON 对象或数组,不会附加任何解释文本,且会严格遵循 JSON 语法,极大降低解析出错的可能。你可以把它理解为向模型下达了一条死命令:“只输出纯 JSON,别废话。”

什么时候需要 JSON Mode

  • 系统集成:你的后端服务期望从模型获得一个可直接 JSON.parse() 的数据结构。
  • 数据提取:从非结构化文本中提取实体、情感、摘要等,并以结构化格式返回。
  • 工具调用:需要模型生成符合特定 Schema 的参数,以便调用外部 API。
  • 自动化流程:多个步骤协同工作,每个步骤的输出必须能被下一个程序可靠读取。

总之,任何需要“机器可读”输出的场景,都推荐使用 JSON Mode。

开启 JSON Mode 的方法

OpenAI 平台

OpenAI 在 GPT-3.5 Turbo 和 GPT-4 等模型中提供了原生 JSON Mode。使用时需要在 API 请求中设置 response_format 参数:

{
  "model": "gpt-4-turbo",
  "messages": [
    {
      "role": "system",
      "content": "你是一个数据提取助手,请返回包含姓名和年龄的 JSON。"
    },
    {
      "role": "user",
      "content": "张三今年28岁。"
    }
  ],
  "response_format": { "type": "json_object" }
}

关键点:

  • 必须在 systemuser 消息中明确提到“JSON”这个词,否则 OpenAI API 可能会拒绝(这是安全机制,防止模型在非预期场景下输出 JSON)。
  • 模型输出将是一个纯 JSON 对象,例如:
    {
      "name": "张三",
      "age": 28
    }
    
  • 不会再有 好的,这是提取的结果: 这类引导语。

其他大模型平台与框架

许多平台也支持类似功能,只是命名和实现稍有不同:

  • Anthropic Claude:通过提示词强制,例如在 Human 消息中写“你必须只返回 JSON,不要包含任何其他文本。”,并在代码层面检查输出是否以 { 开头。
  • Google Gemini:提供 generationConfig.responseMimeType 设为 application/json
  • 开源模型与 llama.cpp:可以通过 Grammar 约束输出,限制生成 token 只能符合 JSON 语法。
  • LangChain:使用 JsonOutputFunctionsParserStructuredOutputParser 来解析并强制输出格式。
  • VLLM:支持 guided_json 参数,可传入 JSON Schema 严格限制输出。

无论哪种工具,核心思想都是约束生成空间,让模型只能选择符合 JSON 语法的 token 序列。

使用 JSON Schema 精确定义输出结构

普通的 JSON Mode 只保证输出是合法 JSON,但不保证字段名、类型符合你的预期。为了精确控制,可以使用 JSON Schema(或 Function Calling)来定义输出结构。

OpenAI 的 Structured Outputs

OpenAI 在新的模型中推出了更强大的 Structured Outputs,允许你直接传入 JSON Schema,模型会严格按照 Schema 输出,甚至不会遗漏必填字段。

示例请求:

{
  "model": "gpt-4o-2024-08-06",
  "messages": [...],
  "response_format": {
    "type": "json_schema",
    "json_schema": {
      "name": "person_schema",
      "strict": true,
      "schema": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "age": { "type": "number" },
          "city": { "type": "string" }
        },
        "required": ["name", "age", "city"],
        "additionalProperties": false
      }
    }
  }
}

输出将严格匹配:

{
  "name": "张三",
  "age": 28,
  "city": "北京"
}

Function Calling 绕道实现

在没有原生 Structured Outputs 的模型上,你可以使用 Function Calling 来实现类似效果。定义函数的参数 Schema,然后让模型调用该函数,实际不执行函数,只取参数 JSON。这种方式同样能保证字段和类型的准确性。

实践演示:构建一个电影信息提取器

假设我们要从一段影评中提取电影名、评分和情绪标签,返回结构化 JSON。

步骤一:编写提示词

即使开启 JSON Mode,System Prompt 依然很重要,它定义了任务和输出格式:

你是一个专业的影评分析助手。根据用户提供的影评,提取以下信息并以 JSON 格式返回:
{
  "movie": "电影名称",
  "rating": 评分(数字,1-10),
  "sentiment": "positive/negative/neutral"
}
只返回 JSON,不要任何额外文字。

步骤二:调用 API(Python 示例)

import openai
client = openai.OpenAI()

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": "你是一个影评分析助手……只返回JSON。"},
        {"role": "user", "content": "《流浪地球》太震撼了,特效拉满,我给9分!"}
    ],
    response_format={"type": "json_object"}
)
print(response.choices[0].message.content)

步骤三:输出结果

{
  "movie": "流浪地球",
  "rating": 9,
  "sentiment": "positive"
}

如果使用 JSON Schema 进一步约束,可以确保 rating 是数字类型,且必须在 1 到 10 之间。

常见问题与注意事项

模型有时仍会输出额外文字怎么办?

  • 检查提示词是否明确要求“只返回 JSON”,并在 System 或 User 消息中出现了“JSON”字样(针对 OpenAI)。
  • 减小 temperature,使用 0 或较小的值,让输出更确定。
  • 在代码层面添加保护:检查输出第一个字符,如果不是 {[ 则尝试提取 JSON 片段,或重新请求。
  • 升级至支持严格 JSON 模式的模型或平台。

JSON Mode 会影响模型推理能力吗?

有些研究表明,强制输出格式可能会让模型在“思考”上表现得略微受限,因为它必须尽早进入 JSON 序列。但在多数结构化提取任务中,影响可忽略。如果你的任务需要大量推理后再输出结构,可以考虑两阶段:先自由输出分析,再让另一个模型(或同一模型在第二回合)转化为 JSON。

如何处理很长的 JSON 输出?

模型有最大输出 token 限制。如果 JSON 过大,可能被截断,导致非法 JSON。解决方案:

  • 分块生成,让模型输出部分内容,然后拼接。
  • 缩小预期结构,只保留必要字段。
  • 使用支持更长上下文的模型。

流式输出对 JSON Mode 的影响

启用流式(streaming)时,每个 chunk 只是整体 JSON 的一部分,直接 parse 会失败。你需要收集所有 chunks 拼接后再解析。许多 SDK 提供了自动拼接的方法。

最佳实践总结

  1. 明确指令:在提示词中清晰描述你需要的 JSON 结构,并强调“只输出 JSON”。
  2. 合理使用 Schema:如果对字段要求严格,尽量使用 JSON Schema 或 Function Calling。
  3. 设置低温度temperature=0 可降低输出的随机性,提高结构一致性。
  4. 错误处理:始终用 try...catch 包裹 JSON 解析,失败时采取重试或 fallback 策略。
  5. 测试真实场景:用各种边界输入测试你的提示词和解析器,确保鲁棒性。

JSON Mode 是大模型走向生产环境的重要基石。掌握它,你就能可靠地将自然语言能力嵌入到结构化工作流中,实现真正的自动化。