跳转到主要内容

能力概述

结构化输出(Structured Outputs)让模型的回复严格遵循你定义的 JSON Schema,确保返回值可以直接被程序解析,无需正则或后处理。 与在 prompt 中要求模型”请返回 JSON”不同,结构化输出基于受约束解码(Constrained Decoding):上游将 JSON Schema 编译为语法规则,在推理过程中逐 token 约束生成,模型不可能产出违反 Schema 的内容。 典型场景:
  • 从非结构化文本中提取实体和字段
  • 分类 / 打标签 / 情感分析
  • 多步推理中间结果的标准化传递
  • Agent 工具调用参数的强类型约束

各协议参数对照

三种协议的参数名不同,但底层机制一致:模型输出严格匹配你提供的 JSON Schema。
协议参数支持模型
OpenAI Chat /v1/chat/completionsresponse_format.type: "json_schema"Claude 4.5+、GPT-4o / GPT-5 系列、Gemini 系列
Anthropic Messages /v1/messagesoutput_config.format.type: "json_schema"Claude 4.5+ (直连 / Vertex);Bedrock 仅 4.5–4.6
OpenAI Responses /v1/responsestext.format.type: "json_schema"随上游模型能力

AWS Bedrock 限制

AWS Bedrock 上 Claude 4.7 及以上版本使用 Mantle 推理路径,该路径目前不支持 output_config.format。网关会自动为这些模型剥离 format 字段并在响应头中标记降级(见下方降级机制),请求不会因此报错。

快速开始

OpenAI 协议(推荐)

适用于所有支持结构化输出的模型,跨厂商通用。
from openai import OpenAI

client = OpenAI(
    api_key="<AIHUBMIX_API_KEY>",
    base_url="https://aihubmix.com/v1",
)

response = client.chat.completions.create(
    model="claude-sonnet-5",
    messages=[
        {"role": "user", "content": "提取以下信息:张三,28岁,北京市海淀区"}
    ],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "person_info",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "age": {"type": "integer"},
                    "city": {"type": "string"}
                },
                "required": ["name", "age", "city"],
                "additionalProperties": False
            }
        }
    }
)

import json
data = json.loads(response.choices[0].message.content)
print(data)
# {"name": "张三", "age": 28, "city": "北京市海淀区"}

使用其他模型(GLM-5.2 示例)

同一套 OpenAI 协议参数适用于所有支持结构化输出的模型,切换 model 即可。
Python
from openai import OpenAI

client = OpenAI(
    api_key="<AIHUBMIX_API_KEY>",
    base_url="https://aihubmix.com/v1",
)

response = client.chat.completions.create(
    model="glm-5.2",
    messages=[
        {"role": "user", "content": "提取以下信息:张三,28岁,北京市海淀区"}
    ],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "person_info",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "age": {"type": "integer"},
                    "city": {"type": "string"}
                },
                "required": ["name", "age", "city"],
                "additionalProperties": False
            }
        }
    }
)

import json
data = json.loads(response.choices[0].message.content)
print(data)
# {"name": "张三", "age": 28, "city": "北京市海淀区"}

Claude 原生协议

使用 Anthropic SDK 直接调用,参数为 output_config.format
import anthropic

client = anthropic.Anthropic(
    api_key="<AIHUBMIX_API_KEY>",
    base_url="https://aihubmix.com",
)

response = client.messages.create(
    model="claude-sonnet-5",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "提取以下信息:张三,28岁,北京市海淀区"}
    ],
    output_config={
        "format": {
            "type": "json_schema",
            "schema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "age": {"type": "integer"},
                    "city": {"type": "string"}
                },
                "required": ["name", "age", "city"],
                "additionalProperties": False
            }
        }
    }
)

import json
data = json.loads(response.content[0].text)
print(data)

Schema 编写要点

必需字段

所有 object 类型必须显式声明 additionalProperties: false,否则部分上游会拒绝请求。
{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "score": { "type": "number" }
  },
  "required": ["name", "score"],
  "additionalProperties": false
}

嵌套对象

嵌套的 object 同样需要 additionalProperties: false
{
  "type": "object",
  "properties": {
    "user": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "email": { "type": "string" }
      },
      "required": ["name", "email"],
      "additionalProperties": false
    }
  },
  "required": ["user"],
  "additionalProperties": false
}

跨协议 Schema 差异

特性OpenAI 协议Anthropic 协议
name 字段必需不支持(网关跨协议调用时自动处理)
strict 字段可选,推荐 true不支持
数值约束 (minimum, maximum 等)支持不支持(网关自动清理,不影响请求)
字符串约束 (minLength, maxLength)支持不支持(网关自动清理)
使用 OpenAI 协议调用 Claude 模型时,网关会自动转换 Schema 格式并清理不兼容的关键字,无需手动适配。

自动降级机制

网关默认为所有请求开启结构化输出的自动降级保护。当模型或平台不支持时,网关不会返回错误,而是自动剥离 Schema 约束并在响应头中标记降级原因。你的请求仍然会得到正常的模型回复,只是输出不受 Schema 强制约束。 这意味着你可以放心地在客户端统一启用结构化输出,而无需针对每个模型做兼容判断:
  • 多模型切换无忧:同一套代码在 Claude、GPT、Gemini、GLM 之间切换模型时,即使目标模型不支持结构化输出,请求也不会报错
  • Fallback 路由透明:当主渠道不可用触发 Fallback 路由到备用渠道时,即使备用渠道的模型版本不支持结构化输出,请求仍然正常完成
  • 客户端逻辑简化:不需要维护一份”哪些模型支持结构化输出”的列表,网关已自动处理;客户端只需检查响应头决定是否需要额外解析

响应头

X-Structured-Output-Degraded: <reason>
reason含义
model_unsupported该模型(或该模型在当前平台上)不支持结构化输出
json_object_unsupported_on_anthropicjson_object 模式无法转换为 Anthropic 格式
json_schema_missing_schema指定了 json_schema 类型但缺少 schema 字段
schema_keywords_strippedSchema 中的部分约束关键字被清理(如 minimummaxLength

检测示例

Python
import httpx

response = httpx.post(
    "https://aihubmix.com/v1/chat/completions",
    headers={
        "Authorization": "Bearer <AIHUBMIX_API_KEY>",
        "Content-Type": "application/json",
    },
    json={
        "model": "claude-sonnet-5",
        "messages": [{"role": "user", "content": "提取信息:张三,28岁"}],
        "response_format": {
            "type": "json_schema",
            "json_schema": {
                "name": "person",
                "strict": True,
                "schema": {
                    "type": "object",
                    "properties": {"name": {"type": "string"}, "age": {"type": "integer"}},
                    "required": ["name", "age"],
                    "additionalProperties": False,
                }
            }
        }
    }
)

# 检查是否发生降级(例如请求被路由到不支持的 Bedrock 渠道时)
degraded = response.headers.get("X-Structured-Output-Degraded")
if degraded:
    print(f"结构化输出已降级:{degraded}")
    # 此时模型回复仍然正常,但输出不受 Schema 强制约束
else:
    import json
    data = json.loads(response.json()["choices"][0]["message"]["content"])
    print(data)  # {"name": "张三", "age": 28}

json_object 模式的区别

json_schema (结构化输出)json_object
输出保证严格匹配指定 Schema仅保证是合法 JSON
字段控制字段名、类型、是否必需均受约束无约束
适用协议OpenAI / Anthropic / Responses仅 OpenAI 兼容协议
Claude 支持通过 output_config.format不支持
json_object 模式不支持转换到 Claude 原生协议。如果你通过 OpenAI 协议向 Claude 发送 response_format: {"type": "json_object"},响应头会标记 json_object_unsupported_on_anthropic 降级。建议直接使用 json_schema 类型。

常见问题

Claude 系列(通过 Anthropic API 的 output_config.format):
  • Opus / Sonnet / Haiku 4.5 及以上版本
  • Fable / Mythos 5 及以上版本
  • Bedrock 平台仅 4.5–4.6;Vertex AI 与直连一致
OpenAI 系列(通过 response_format):
  • GPT-4o 及以上、GPT-5 系列
Gemini 系列(通过 responseSchema):
  • Gemini 2.5 及以上
可通过 模型列表页 查看各模型的能力标签。
AWS Bedrock 上 Claude 4.7+ 使用了新的 Mantle 推理路径,该路径目前不接受 output_config.format 参数。网关会自动处理:剥离 format 并正常返回响应,同时标记降级头 X-Structured-Output-Degraded: model_unsupported。Claude 4.5–4.6 在 Bedrock 上完全支持。
会。当通过 OpenAI 协议调用 Claude 模型时,网关自动:
  1. response_format 转换为 output_config.format
  2. 移除 Anthropic 不支持的 Schema 关键字(minimummaxLength 等)
  3. 如果有关键字被清理,响应头标记 schema_keywords_stripped
反向(Claude 协议调用 OpenAI 模型)同样自动转换。
可以。output_config 中的 format(结构化输出)和 reasoning 中的 effort(思考强度)是独立参数,可以同时设置:
{
  "output_config": {
    "format": {
      "type": "json_schema",
      "schema": { ... }
    }
  },
  "reasoning": {
    "effort": "high"
  }
}
大多数 API 聚合平台在模型不支持结构化输出时会直接返回错误。AIHubMix 采用优雅降级策略:自动剥离不兼容的参数,正常返回模型响应,并通过 X-Structured-Output-Degraded 响应头告知客户端降级原因。你的应用不会因此中断。