限时优惠

Structured Output 是什么?AI Agent 为什么需要结构化输出?JSON Schema 与普通 JSON 有什么区别?

博客 AI Agent
2026-08-18 约 8 分钟阅读

如果模型结果只给人阅读,自然语言通常更合适;如果结果要进入前端、数据库、工作流或工具链,就需要明确的数据契约。本文按人读回答、数据抽取、工具调用、动态界面和多步骤 Agent 场景,对比普通 JSON、JSON 模式与 Structured Output 的边界,并给出可执行的选型表与验收步骤。

本文要点

  1. 模型返回的 JSON 虽然能解析,但字段名称漂移、类型变化,前端和数据库仍然频繁报错。
  2. 最快解法:普通 JSON 只解决数据格式,JSON 模式通常只保证可解析,生产环境优先用 Structured Output 配合 JSON Schema;执行工具前仍必须做业务规则和权限校验。
Structured Output 是什么?AI Agent 为什么需要结构化输出?JSON Schema 与普通 JSON 有什么区别?
Structured Output 是什么?AI Agent 为什么需要结构化输出?JSON Schema 与普通 JSON 有什么区别?

模型返回的 JSON 虽然能解析,但字段名称漂移、类型变化,前端和数据库仍然频繁报错。 最快解法:普通 JSON 只解决数据格式,JSON 模式通常只保证可解析,生产环境优先用 Structured Output 配合 JSON Schema;执行工具前仍必须做业务规则和权限校验。

谁该看这篇?

如果你刚接触 AI 应用,需要先分清普通 JSON、JSON 模式与 Structured Output 不是同一个概念。 如果你负责后端、工作流或 Agent 架构,本文重点帮助你判断:什么时候值得增加结构约束,什么时候反而应该保留自然语言。

先把三个概念放回正确的位置

普通 JSON 是一种数据表示格式,例如对象、数组、字符串、数字、布尔值和空值都可以用 JSON 表达。它本身不规定“必须有哪些字段”,也不规定字段必须是什么类型,因此下面这类结果完全可能通过 JSON 解析:

{
  "customer": "李明",
  "amount": "一千元",
  "status": "已付款"
}

问题在于,amount 有时是字符串,有时是数字;status 也可能变成 paid、已支付或完成付款。解析器只关心语法是否正确,不会替你判断业务字段是否稳定。

JSON Schema 是描述 JSON 数据结构、类型和约束的契约。它本身通常也是一个 JSON 文档,但它描述的是“数据应该长什么样”,不是业务数据本身。官方规范将 typepropertiesrequiredenum 等关键字用于定义结构和允许值,你可以参考 JSON Schema 入门说明

Structured Output 则是模型生成机制中的一种约束方式:你把 Schema 作为输出契约交给模型,让模型按照指定字段和类型生成结果。它解决的是“模型如何生成符合结构的数据”,而 JSON Schema 解决的是“结构规则如何被定义和验证”。

JSON Schema 是不是一种 JSON 格式?

严格来说,JSON Schema 文档可以用 JSON 编写,所以它看起来是 JSON;但它和被描述的 JSON 数据不是同一份东西。可以把 Schema 理解为接口协议,把普通 JSON 理解为一次具体的接口响应。

结构约束的层级差异

在实际开发中,你通常会遇到四个层次:

方案能解决什么主要风险更适合的场景
自然语言解释、总结、对话不便于程序直接消费面向用户的回答
提示词要求 JSON引导模型输出 JSON 外形字段漂移、漏字段、类型不稳定原型验证、低风险脚本
JSON 模式通常保证结果是可解析 JSON不一定保证字段、枚举和业务含义简单交换、弱约束任务
Structured Output + JSON Schema约束字段、类型和部分结构受平台支持范围、Schema 复杂度影响生产抽取、接口响应、工具参数

JSON 模式与 Structured Output 的区别,核心不在于“一个输出 JSON、另一个不输出 JSON”,而在于约束粒度。以官方 API 文档为例,旧式 json<em>object 主要对应 JSON 模式;json</em>schema 则用于让结果匹配给定 Schema,而且严格模式只支持 JSON Schema 的一个子集。你可以查看 JSON 响应格式与 Schema 说明

另一个平台的官方文档也明确区分了两者:Structured Output 用于最终响应格式,Function Calling 或 Tool Calling 用于模型请求外部工具执行动作。该平台同时只支持 JSON Schema 的一部分,而不是所有规范关键字。参考 Structured Output 与工具调用对比

Structured Output 和 JSON mode 的区别是什么?

如果你只要求“返回一个能被 JSON.parse 读取的对象”,JSON 模式可能够用;如果你要求字段必须存在、类型不能漂移、枚举不能越界,就应该使用 Schema 约束,并在服务端再次验证。前者是语法层保证,后者更接近接口契约层保证,但两者都不等于事实正确。

第一种场景:面向人的回答通常不必强制 Schema

客服答复、产品解释、故障排查建议和长篇摘要,主要消费方是人。此时自然语言可以根据上下文调整详略,模型也能补充说明、承认不确定性,并把多个条件组织成易读段落。

如果你强行规定:

{
  "answer": "string",
  "reason": "string",
  "confidence": "number"
}

看起来更整齐,却可能带来额外负担。你需要维护字段定义、处理空值、设计版本变化,还要考虑 confidence 到底表示模型自评、证据覆盖率,还是业务系统的可信等级。若前端不消费这些字段,Schema 只是增加了接口复杂度。

✅ 适合自然语言的情况:

  • 结果直接展示给用户;
  • 内容需要根据上下文自由展开;
  • 下游没有固定字段或自动执行动作;
  • 失败时人工可以快速判断和修正。

❌ 不适合只依赖自然语言的情况:

  • 结果要直接写入数据库;
  • 结果要驱动表单、卡片或流程节点;
  • 结果包含工具参数;
  • 结果需要跨服务长期保存。

第二种场景:数据抽取从普通 JSON 升级到 Schema

假设你从发票、合同或工单中抽取客户名、金额、日期和风险等级。提示词可以要求模型输出 JSON,但模型仍可能遗漏字段,或者把日期写成不同格式,把金额写成带货币符号的文本。

更稳妥的 Schema 会明确:

{
  "type": "object",
  "properties": {
    "customer_name": { "type": "string" },
    "amount": { "type": "number" },
    "currency": { "type": "string", "enum": ["CNY", "USD", "EUR"] },
    "risk_level": { "type": "string", "enum": ["low", "medium", "high"] }
  },
  "required": ["customer_name", "amount", "currency", "risk_level"],
  "additionalProperties": false
}

这里真正有价值的不是 JSON 外观,而是下游可以根据固定类型处理结果:数据库把 amount 当数值存储,流程引擎根据 risk_level 分支,前端根据字段是否存在决定显示内容。

抽取要求普通 JSONSchema 约束采购建议
只需快速读取可选先用提示词或 JSON 模式
字段名称固定⚠️使用 propertiesrequired
类型必须稳定明确 stringnumberboolean
值只能来自有限集合使用 enum
数据要写入生产库风险高模型约束后再做服务端校验

AI Agent 为什么不能只输出普通 JSON?

不是因为普通 JSON 无法使用,而是因为 Agent 的每一步都可能成为下一步的输入。一个字段从 task_id 变成 taskId,一个布尔值从 false 变成“否”,就可能让状态机、重试逻辑或数据库写入失败。普通 JSON 对低风险交换仍然有价值,但不应承担生产接口契约的全部责任。

第三种场景:Tool Calling 参数需要严格约束和双重检查

Tool Calling 的参数通常比普通回答更敏感,因为它可能触发发邮件、创建订单、修改权限、删除资源或调用内部 API。工具定义中的参数可以用 JSON Schema 描述,例如要求 user_id 为字符串、limit 为整数、action 只能是预设枚举。

官方工具调用文档通常把 Schema 放在工具的输入定义中,并要求应用在收到工具调用后提取工具名、调用 ID 和输入,再由自己的代码执行工具。参考 工具输入 Schema 与调用流程说明

但格式正确不等于应该执行。下面两道检查不能省:

  1. 结构校验:字段是否齐全,类型是否正确,枚举值是否允许;
  2. 业务与权限校验:用户是否有权限,目标资源是否存在,金额是否在限额内,当前状态是否允许执行。

例如,delete<em>file 的参数完全符合 Schema,并不代表这个用户可以删除该文件;transfer</em>money 的金额是合法数字,也不代表账户余额、风控状态和审批条件已经满足。

⚠️ 经验提醒:不要把“模型输出符合 Schema”写成“系统可以直接执行”。Schema 约束的是数据形状,权限系统约束的是谁能做什么,业务服务还要确认资源和状态真实存在。

第四种场景:动态界面要优先考虑版本兼容

当模型输出要驱动表单、卡片或组件时,结构化结果可以让前端根据 componentlabelvalueoptions 动态渲染页面。这比让前端从自然语言中猜测按钮、字段和选项更可靠。

不过,动态界面会把 Schema 变成前后端共同依赖的协议。你新增必填字段,旧客户端可能无法渲染;你把 options 从字符串数组改成对象数组,已有转换逻辑可能直接失效。

建议至少保留以下兼容策略:

  • 在顶层加入 schema_version 或等价版本标识;
  • 新字段优先设为可选,并提供默认值;
  • 不要随意重命名旧字段;
  • 客户端遇到未知组件时回退为文本;
  • 服务端保留旧版本 Schema 的解析能力;
  • 对模型拒答、截断和验证失败设计回退响应。

这里不建议把所有内容都设计成高度嵌套的 Schema。动态界面需要扩展性,过度严格的结构会使每次组件迭代都变成接口迁移。

第五种场景:多步骤 Agent 区分中间状态与最终结果

多步骤 Agent 至少存在两类数据:

  • 中间事件:工具调用、调用 ID、参数、工具结果、重试状态;
  • 最终结果:给用户看的答案、摘要、下一步建议或可展示卡片。

中间事件应尽量机器可读,因为编排器需要根据事件继续运行;最终回答则可以同时提供结构和文本。例如,前端需要卡片数据时返回结构字段,同时保留一个 display_text 作为无法渲染时的回退内容。

但不要把内部推理过程当作必须输出的 JSON 字段。Agent 真正需要传递的是可审计的事件、工具输入、工具结果和状态变化,而不是要求模型暴露一段所谓“完整思考过程”。这样既减少协议耦合,也方便你控制敏感信息和日志内容。

推荐的状态对象可以包含:

{
  "run_id": "run_123",
  "status": "waiting_for_tool",
  "tool_call": {
    "id": "call_456",
    "name": "search_order",
    "arguments": {
      "order_id": "A100"
    }
  },
  "display_text": "正在查询订单状态……"
}

其中 run<em>idstatustool</em>call.idarguments 适合纳入严格结构;display_text 则应允许自然语言变化。这样既能让工作流继续执行,也不会牺牲用户体验。

按消费方选择 JSON、Schema 或自然语言

你可以用下面的决策表快速判断,而不是先选某个平台再倒推架构:

你的消费方与风险推荐输出是否需要 Schema额外验收
用户阅读说明、总结、解释自然语言通常不需要检查事实、语气和敏感内容
脚本读取少量字段普通 JSON 或 JSON 模式可选JSON 解析、空值和超时处理
批量数据抽取Structured Output建议需要服务端 Schema 验证、抽样复核
Tool Calling 参数工具 Schema必须权限、资源、状态和幂等校验
动态表单或卡片版本化结构输出需要默认值、未知组件和文本回退
多步骤 Agent 状态事件 Schema + 最终响应结构中间状态需要调用 ID、重试、超时和审计日志

工具参数和最终回答都需要 Schema 吗?

工具参数通常应严格约束,因为它们会进入可执行代码;最终回答则取决于消费方。如果最终回答只是聊天文本,不必强制完整 Schema;如果前端要渲染卡片、数据库要入库,或者另一个 Agent 要继续消费,就应为最终响应定义结构,并保留人类可读的回退文本。

结构化输出对内容准确性没有直接担保。

它主要降低格式错误、字段漂移和类型不一致的风险,不能证明模型抽取出的日期、金额、客户名称或事实判断一定正确。即使结果通过 Schema 验证,你仍需要做来源核对、范围检查、业务规则验证和必要的人工抽样。关于支持范围与实现限制,可参考 Structured Output 官方说明

落地时按这 6 步验收

第一步,先写清楚消费方:人、前端、数据库、工作流还是工具执行器。消费方不同,结构约束强度就不应相同。

第二步,列出真正需要稳定的字段,只把会被程序读取的内容放进 Schema,不要为了“看起来完整”把所有解释文字都塞进去。

第三步,明确类型、必填项、枚举、默认值和未知字段策略。尤其要区分“字段缺失”“字段为空”和“模型无法判断”这三种状态。

第四步,确认目标模型支持哪些 Schema 特性。不同平台的 Structured Output 支持范围并不完全一致,复杂嵌套、引用、正则或特殊格式不能想当然地跨平台复用。

第五步,在模型返回后执行本地验证。验证失败时记录原始响应、请求 ID 和 Schema 版本,再决定重试、转人工或回退到自然语言。

第六步,给工具执行加业务闸门。即使参数通过 Schema,也要检查登录身份、资源归属、权限、额度、状态和幂等键;高风险动作还应加入人工确认。

如果你需要为批量抽取、工具执行或持续工作流准备稳定的运行环境,先从 kvmboot 帮助中心确认远程开发、连接和运维方式,再安排验收任务;涉及团队协作或节点规划时,也可以通过 联系 kvmboot 获取环境层面的建议。

当前方案和 Mac 方案的取舍

如果你现在主要依赖个人电脑、本地临时脚本或多人共用的云主机,常见缺点是环境版本容易漂移、权限边界不清晰、长时间批处理会被本地休眠或网络中断打断;当 Agent 还需要固定的开发工具链和持续运行时,这些问题会直接影响复现与验收。

自购 Mac 的长期成本和维护责任更高,但设备归属、系统版本和本地工具链更可控;普通云主机弹性较好,却可能在远程桌面体验、权限配置和图形化调试上增加额外工作。对需要临时算力、短期测试环境或跨团队验收的人,租赁 kvmboot 的 Mac 环境更适合先验证 Structured Output、Tool Calling 和工作流稳定性,再决定是否购买设备或建设长期基础设施。你也可以先了解 kvmboot 的服务与团队信息,把环境选择和应用验收分开决策。

为你的 AI Agent 准备稳定的远程 Mac 环境

在 kvmboot 租用远程 Mac,快速搭建结构化输出、JSON Schema 与工具调用的测试环境。

查看套餐 · 首页