主题
结构化输出(response_format)
让模型严格按 JSON Schema 返回结构化数据,无需 prompt 反复约束格式。适合数据抽取、API 包装、表单填写等场景。
待验证(TODO/VERIFY):json_schema 是否强制
以下内容基于旧平台实测(2026-06),尚未在 Shuro 复测,仅供参考。
旧平台对 gpt-5.4-mini 等模型传 response_format: {type: "json_schema", ...} 时,上游会忽略该约束,返回普通聊天文本而非严格 JSON。旧平台实测可靠的三种替代方案:
response_format: {"type": "json_object"}—— ✅ 返回严格 JSON(但无 schema 字段约束)- OpenAI 强制工具调用(
tools+tool_choice: "required")—— ✅arguments严格按 schema - Claude 强制 tool_use(
tool_choice: {"type": "tool", "name": "..."})—— ✅input严格按 schema,见下文
需要 schema 级约束时建议用方案 2 / 3;只需要"保证是合法 JSON"用方案 1 + prompt 描述字段。
何时用
- 让 Claude / GPT 返回严格 JSON(非 Markdown / 自然语言)
- 输出要直接
JSON.parse()喂给下游程序 - 需要枚举值约束(status: 只能是 "open"/"closed")
- 表单/工单字段抽取
端点
POST https://shuro.vip/v1/chat/completionsOpenAI 兼容协议。
请求 Header
| Header | 必需 | 示例 |
|---|---|---|
Content-Type | ✅ | application/json |
Authorization | ✅ | Bearer <您的 API Key> |
请求 Body
json
{
"model": "gpt-5.4",
"messages": [
{
"role": "user",
"content": "以 JSON 格式返回一个人的基本信息:姓名、年龄、职业"
}
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "person_info",
"schema": {
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer" },
"occupation": { "type": "string" }
},
"required": ["name", "age", "occupation"]
}
}
}
}response_format 字段详解
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
type | string | ✅ | 取值 "json_schema"(最常用)或 "json_object" |
json_schema.name | string | ✅ | Schema 命名(任意,仅做标识) |
json_schema.schema | object | ✅ | 标准 JSON Schema |
json_schema.strict | boolean | 可选 | true 表示严格模式(推荐) |
完整示例
curl
bash
curl -X POST 'https://shuro.vip/v1/chat/completions' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <您的 API Key>' \
-d '{
"model": "gpt-5.4",
"messages": [
{
"role": "user",
"content": "以 JSON 格式返回一个人的基本信息:姓名、年龄、职业"
}
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "person_info",
"schema": {
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer" },
"occupation": { "type": "string" }
},
"required": ["name", "age", "occupation"]
}
}
}
}'Python
python
from openai import OpenAI
client = OpenAI(
api_key="<您的 API Key>",
base_url="https://shuro.vip/v1"
)
resp = client.chat.completions.create(
model="gpt-5.4",
messages=[{"role": "user", "content": "以 JSON 格式返回一个人的基本信息:姓名、年龄、职业"}],
response_format={
"type": "json_schema",
"json_schema": {
"name": "person_info",
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"occupation": {"type": "string"}
},
"required": ["name", "age", "occupation"]
}
}
}
)
import json
person = json.loads(resp.choices[0].message.content)
print(person)
# {'name': '张伟', 'age': 30, 'occupation': '软件工程师'}Node.js
javascript
import OpenAI from 'openai';
const client = new OpenAI({
apiKey: '<您的 API Key>',
baseURL: 'https://shuro.vip/v1'
});
const resp = await client.chat.completions.create({
model: 'gpt-5.4',
messages: [{ role: 'user', content: '以 JSON 格式返回一个人的基本信息:姓名、年龄、职业' }],
response_format: {
type: 'json_schema',
json_schema: {
name: 'person_info',
schema: {
type: 'object',
properties: {
name: { type: 'string' },
age: { type: 'integer' },
occupation: { type: 'string' }
},
required: ['name', 'age', 'occupation']
}
}
}
});
const person = JSON.parse(resp.choices[0].message.content);
console.log(person);响应示例
json
{
"id": "chatcmpl-DaFEmSINXzfoRHsMHxHRMNp4vXbxe",
"object": "chat.completion",
"created": 1777530752,
"model": "gpt-5.4",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "{\"name\":\"张伟\",\"age\":30,\"occupation\":\"软件工程师\"}",
"refusal": null,
"annotations": []
},
"logprobs": null,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 65,
"completion_tokens": 17,
"total_tokens": 82,
"prompt_tokens_details": {
"cached_tokens": 0,
"audio_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 0,
"audio_tokens": 0
}
},
"service_tier": "default",
"system_fingerprint": "fp_af7f7349a4"
}content 字段是严格符合 schema 的 JSON 字符串,直接 JSON.parse() 即可。
进阶:复杂 Schema
枚举值约束
json
{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": ["open", "in_progress", "closed"]
},
"priority": {
"type": "string",
"enum": ["low", "medium", "high", "critical"]
}
},
"required": ["status", "priority"]
}模型只能从枚举值里选,不会乱编。
嵌套对象
json
{
"type": "object",
"properties": {
"user": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" }
}
},
"order": {
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"product": { "type": "string" },
"qty": { "type": "integer" },
"price": { "type": "number" }
}
}
}
}
}
}
}数组 + minItems
json
{
"type": "object",
"properties": {
"tags": {
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"maxItems": 10
}
},
"required": ["tags"]
}Nullable 字段
json
{
"type": "object",
"properties": {
"email": {
"type": ["string", "null"],
"format": "email"
}
}
}各方案支持情况
待验证(TODO/VERIFY)
以下内容基于旧平台实测(2026-06),尚未在 Shuro 复测,仅供参考。
| 方案 | 旧平台实测结果 |
|---|---|
response_format: json_schema(GPT 系列) | ❌ 不强制——返回普通聊天文本,schema 被上游忽略 |
response_format: json_schema(claude-* 走 chat 协议) | ❌ 不强制——返回 markdown 包裹的 JSON,非严格输出 |
response_format: json_object(gpt-5.4-mini 级别模型) | ✅ 返回严格 JSON |
OpenAI tools + tool_choice: "required" | ✅ arguments 严格按 schema |
Claude 原生 tool_choice: {"type": "tool"} | ✅ input 严格按 schema |
Claude 系列直接用 tool_use
Anthropic 原生协议没有 response_format。对 Claude 要严格 JSON 输出,直接用 Anthropic 原生 tool_use(旧平台实测可靠),不要依赖 response_format 转译。
Anthropic 原生 tool_use(Claude 推荐)
bash
curl -X POST 'https://shuro.vip/v1/messages' \
-H 'content-type: application/json' \
-H 'anthropic-version: 2023-06-01' \
-H 'x-api-key: <您的 API Key>' \
-d '{
"model": "claude-opus-4-7",
"max_tokens": 1024,
"tools": [
{
"name": "extract_person",
"description": "Extract person info as JSON",
"input_schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"occupation": {"type": "string"}
},
"required": ["name", "age", "occupation"]
}
}
],
"tool_choice": {"type": "tool", "name": "extract_person"},
"messages": [{"role": "user", "content": "..."}]
}'tool_choice.name 强制 Claude 调用指定 tool → 输出严格按 schema。
常见问题
返回的不是 JSON 而是有 json 包裹
模型没按 response_format 走。检查:
- 模型 ID 是否在支持列表
- 是否真的传了
response_format字段(不是只在 prompt 里说) - Provider 是否透传该字段(有些中转商会吃掉它)
字段缺失
Schema 里 required 没列全。所有期望必出现的字段都要列在 required。
类型不对(说要 integer 给了 "30")
OpenAI 严格模式默认不会出错,但部分 Provider 会偷懒。要强制:
json
"json_schema": {
"name": "...",
"strict": true, // ← 严格模式
"schema": { ... }
}为什么 json_schema 不生效
部分上游可能未启用 structured output 能力,网关也可能不透传 json_schema 约束——这是旧平台实测 json_schema 不强制的可能原因(Shuro 行为待验证,TODO/VERIFY)。生产环境请用本页开头列出的三种可靠方案(json_object / 强制工具调用),不要假设 json_schema 会被严格执行。
跟 tool_use 的区别
| response_format | tool_use | |
|---|---|---|
| 协议 | OpenAI Chat Completions | Anthropic Messages |
| 模型偏好 | GPT 系列 | Claude 系列 |
| 输出位置 | content 字段(JSON 字符串) | input 字段(结构化对象) |
| 强制性 | strict 模式很强 | tool_choice 很强 |
| 多 tool 选择 | ❌ 单一 schema | ✅ Claude 可选多个 |
Shuro 都支持,按你模型偏好选。
