30秒快速回答: 结构化输出(Structured Outputs)是一类让大模型严格按预定义格式(通常是 JSON 对象)返回结果的技术,由模型厂商(OpenAI、Anthropic、Google 等)在 API 层面原生保证”输出 100% 符合你的 JSON Schema”。它解决的痛点是:普通 LLM 输出是自由文本,一旦用于程序对接,格式稍微偏差(多一个逗号、字段名变了)程序就崩溃。核心价值一句话:让 AI 的输出像数据库记录一样规范,程序拿来就能用,不解析、不报错

一、为什么需要结构化输出?——AI 输出的”原生困境”

大模型的本质是”预测下一个 token”,天生输出的是自由文本。当你让它”返回 JSON”时,它可能:

// 模型经常返回的样子  程序直接崩溃
{"name": "张三", "age": "28", "courses": ["Python", "AI", "数据库",]} 
// 多了一个逗号
常见问题 具体表现 后果
格式不完整 省略结束括号、截断在中间 JSON 解析直接抛异常
类型不可靠 年龄返回 "28"(字符串)而非 28(数字) 程序强类型校验失败
字段名漂移 约定 user_name,返回 usernamename 按字段取值拿不到数据
夹带噪音 前后缀”好的,以下是结果:```json” 需要额外清洗

传统方案(”提示词里多加一句’只输出 JSON’“)只能降低概率,不能根治。Structured Outputs 的价值在于:把”格式保证”从模型自觉,变成 API 层面的硬性约束——返回的内容在服务端就用约束解码器保证合法,非法就直接拒发或强制修正。

二、三种实现方式:从”软约束”到”硬保证”

方案 原理 可靠性 适用场景
提示词约束 Prompt 里写”必须返回 JSON” 低(约 60-80%) 快速原型、人读为主
Function Calling / JSON Schema 校验 把输出约束声明为工具参数,调用后前端再校验重试 中(约 90-95%) 兼容老模型、已有业务
原生 Structured Outputs API 层内置约束解码(constrained decoding),逐 token 保证合法 高(99.9%+) 生产环境、程序对接

关键区别在第三档:原生模式下,模型生成每个 token 时只允许产生”下一跳依然是合法 JSON”的候选,从根本上杜绝语法错误——这也是 2026 年主流厂商的做法(OpenAI response_format、Anthropic Tool Use 强约束、Gemini responseSchema、本地 Outlines 的 JSON Schema Grammar)。

三、实战:三大平台 + 本地开源,怎么写代码

1. OpenAI / 兼容接口:response_format + JSON Schema

from openai import OpenAI

client = OpenAI()

response = client.chat.completions.create(
    model="gpt-5",
    response_format={"type": "json_schema", "json_schema": {
        "name": "summary_result",
        "strict": True,
        "schema": {
            "type": "object",
            "properties": {
                "title": {"type": "string"},
                "rating": {"type": "number"},
                "tags": {"type": "array", "items": {"type": "string"}}
            },
            "required": ["title", "rating", "tags"],
            "additionalProperties": False
        }
    }},
    messages=[{"role": "user", "content": "用 5 星制点评这篇教程"}]
)
data = json.loads(response.choices[0].message.content)
print(data["rating"] + 1)  # 可靠:less是数字

strict: True 表示严格模式——要求所有字段都在 properties 中声明、required 全部列出、禁止额外字段,保证每个返回对象都精确匹配 Schema。

2. Anthropic:把输出约束声明为 Tool

import anthropic

c = anthropic.Anthropic()
resp = c.messages.create(
    model="claude-opus",
    tools=[{
        "name": "extract_contact",
        "description": "从文本中抽取联系方式",
        "input_schema": {
            "type": "object",
            "properties": {
                "name": {"type": "string"},
                "emails": {"type": "array", "items": {"type": "string"}}
            },
            "required": ["name", "emails"]
        }
    }],
    messages=[{"role": "user", "content": "帮我提取:张三,邮箱 a@b.com 和 c@d.com"}]
)
# 读取 tool_use 块,直接拿到结构化参数
print(resp.content[-1].input)  # {'name': '张三', 'emails': ['a@b.com', 'c@d.com']}

3. Google Gemini:responseSchema(最直观)

from google import genai

client = genai.Client()
resp = client.models.generate_content(
    model="gemini-2.5-pro",
    contents="给这篇文章生成 3 个 SEO 标题",
    config={"response_mime_type": "application/json",
            "response_schema": {"type": "ARRAY",
                                "items": {"type": "STRING"}}}
)
print(resp.text)  # 直接是合法 JSON 数组

4. 本地开源模型:Outlines / Pydantic(结构化解码)

本地部署同样可以做到”硬保证”,代表工具是 Outlines(约束解码)和 Pydantic 2.x(类型定义 + 校验):

import outlines

# 用 JSON Schema 约束本地 vLLM / llama.cpp 的生成
generator = outlines.generate.json(model, 
    '{"type": "object", "properties": {"city": {"type": "string"}, "temp": {"type": "number"}}}')
result = generator("北京的今日气温?")
print(result)  # {'city': '北京', 'temp': 32.5} —— 同步生成时就保证合法
from pydantic import BaseModel, Field
from openai import OpenAI

class Order(BaseModel):
    id: int
    amount: float = Field(gt=0)

client = OpenAI()
# 直接把 Pydantic 模型传进去,返回即强类型对象
order: Order = client.beta.chat.completions.parse(
    model="gpt-5",
    messages=[{"role": "user", "content": "订单:编号 1001,金额 99.9 元"}],
    response_format=Order,
)
print(order.id, order.amount)  # 1001 99.9 —— 无需手写 json.loads

四、踩坑与最佳实践:6 条落地清单

  1. Schema 越窄越稳:字段必须全部声明,能不用自由文本数组就不用;additionalProperties: false + required 全列,杜绝模型”自由发挥”。
  2. 区分”语法合法”与”语义正确”:Structured Outputs 只保证格式,不保证内容正确——返回的 JSON 合法但含义可能是幻觉,语义校验仍需业务层兜底。
  3. 务必处理拒答(refusal):OpenAI 等平台在模型拒绝时返回 message.refusal,字段为空,程序要单独判空而不是直接解析,否则静默失败。
  4. 不要与流式输出打架:部分平台 Strict 模式与 stream=True 不兼容,生产环境要先验证组合可用性;本地 Outlines/SGLang 对解码有额外速度开销(通常 <20%),可接受。
  5. Schema 变更成本高:两套 Schema 之间的字段迁移会影响下游全部消费方,上线前用版本化(v1.0)管理。
  6. 组合技更优:Structured Outputs 定格式 + Function Calling 定行为 + 业务端再做一次 Pydantic 二次校验,三层防线几乎不会出错。

总结

结构化输出解决的是 AI 落地中最实际的一环:让不可预测的自由文本,变成程序可直连的强类型数据。记住三句话:

  • 提示词约束是”软”的,原生 Structured Outputs 是”硬”的——生产环境一律用硬约束;
  • 格式有保证 ≠ 内容没幻觉——语义校验必须留在业务层;
  • 企业级标配是”结构化输出 + 函数调用 + 二次校验”三层组合

延伸阅读:

  • 想理解结构化输出的应用前置(让 AI 调用外部工具),请看本站《怎么用 Function Calling?》(guide-28);
  • 想了解如何让 Agent 组合工具完成复杂任务,请看《什么是 A2A 协议?Agent 之间的 TCP/IP 标准》(guide-33)与《怎么搭建 AI 工作流?》(guide-27);
  • 想防止输出内容本身不可靠,请看《什么是 AI 幻觉?》(guide-88)。