Structured Output
让模型返回便于程序解析和校验的结构化数据。
Structured Output 用于让模型按预期的数据结构返回结果,便于程序提取字段、写入数据库或进入后续工作流。典型场景包括工单分类、表单提取、内容审核结果和固定结构的分析报告。
Structured Output 和 Tool Calling 解决不同问题
如果你需要模型返回一份结构化回答,使用 Structured Output;如果你需要模型选择并请求应用执行某个函数,使用 Tool Calling。工具参数也可以由 Schema 约束,但它属于工具调用循环。
先选择合适的输出方式
| 方式 | 能解决什么问题 | 客户端还要做什么 |
|---|---|---|
| 在提示词中要求 JSON | 为不支持专用字段的模型提供基础约束 | 提取 JSON、解析、校验并在失败时重试 |
| JSON Object | 要求模型输出合法 JSON 对象 | 校验字段、类型和业务规则 |
| JSON Schema | 在请求中提供目标结构 | 处理模型支持范围、拒绝、截断和校验失败 |
是否支持 JSON Object、JSON Schema 或严格遵循取决于当前模型和协议。不要仅因为请求返回 200 就认定指定 Schema 已经生效。
定义一个小而明确的 Schema
下面的结构用于把客户问题分类为工单:
{
"type": "object",
"properties": {
"category": {
"type": "string",
"enum": ["billing", "technical", "account"]
},
"priority": {
"type": "integer",
"minimum": 1,
"maximum": 3
},
"summary": {
"type": "string"
}
},
"required": ["category", "priority", "summary"],
"additionalProperties": false
}字段名应稳定且易懂,枚举值应与业务代码一致。避免一开始就使用过深嵌套、过多可选分支或难以解释的正则约束。
使用 Chat Completions 返回结构化结果
curl 'https://api.agtcloud.cn/v1/chat/completions' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer your-api-key' \
--data '{
"model": "MODEL_ID",
"messages": [
{
"role": "user",
"content": "我的 API Key 无法使用,请帮我分类。"
}
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "support_ticket",
"strict": true,
"schema": {
"type": "object",
"properties": {
"category": {
"type": "string",
"enum": ["billing", "technical", "account"]
},
"priority": {
"type": "integer",
"minimum": 1,
"maximum": 3
},
"summary": {"type": "string"}
},
"required": ["category", "priority", "summary"],
"additionalProperties": false
}
}
}
}'strict 是目标格式的一部分,但是否可用仍由模型决定。完整字段见 Chat Completions Reference。
不同协议的字段位置
Chat 在 response_format 中选择 json_object 或 json_schema。使用 JSON Schema 时,Schema 位于 response_format.json_schema.schema。
{
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "support_ticket",
"schema": {"type": "object"}
}
}
}这些结构不能直接复制到另一种协议中。使用前分别查看 Responses Reference 和 Gemini Generate Content Reference。
解析后仍要校验
type SupportTicket = {
category: 'billing' | 'technical' | 'account';
priority: number;
summary: string;
};
function parseTicket(raw: string): SupportTicket {
const value: unknown = JSON.parse(raw);
if (
typeof value !== 'object' ||
value === null ||
!('category' in value) ||
!('priority' in value) ||
!('summary' in value)
) {
throw new Error('结构化结果缺少必要字段');
}
return value as SupportTicket;
}上例只演示最小检查。正式项目应使用与业务数据模型一致的 Schema 校验器,并检查枚举、长度、数值范围和跨字段规则。
处理不完整和无效结果
| 现象 | 处理方式 |
|---|---|
| 返回普通文本 | 确认模型支持目标格式,检查字段位置和请求是否被 SDK 改写 |
| JSON 无法解析 | 保存脱敏响应和停止原因,按业务策略有限重试 |
| 缺少必要字段 | 视为校验失败,不用默认值静默掩盖关键数据缺失 |
| 输出被截断 | 调整输出预算或简化 Schema,不拼接猜测缺失 JSON |
| 模型拒绝回答 | 单独处理拒绝,不把拒绝文本当作业务对象 |
| Schema 能解析但业务无效 | 使用业务校验返回明确错误或进入人工处理 |
上线前检查
- Schema 与应用中的类型定义由同一来源生成或保持同步。
- 模型切换前重新确认协议、Schema 子集和严格模式支持。
- 解析失败、拒绝、截断和空输出都有独立分支。
- 结构化结果在写入数据库或触发业务动作前再次校验。
- 日志只保存完成排障所需的脱敏信息。