让 Agent 输出可验证:Structured Outputs 与 JSON Schema 实战
# 让 Agent 输出可验证:Structured Outputs 与 JSON Schema 实战
Agent 不只是“生成一段文字”。在真实应用里,模型结果还要交给前端渲染、工作流编排或下一次工具调用。如果输出字段缺失、枚举值拼错,后续逻辑就会被迫依赖大量重试和字符串解析。
OpenAI 在 API 中提供了 Structured Outputs:开发者提交 JSON Schema 后,模型输出会按这个结构返回。它适合把 Agent 的结果变成稳定的“数据契约”,但仍然需要对拒答、输入不匹配和业务语义错误做单独处理。
## 一、先区分两类结构化场景
- **模型调用工具**:需要把模型连接到数据库、搜索、界面操作等能力时,使用 function calling,让模型生成工具参数。
- **模型返回结果**:需要让前端得到固定字段(例如摘要、状态、下一步)时,使用结构化的 text.format 或 SDK 的解析辅助函数。
JSON mode 只能保证返回的是合法 JSON,并不保证字段一定存在,也不保证枚举值符合约定。因此,只要模型版本支持,优先使用 Structured Outputs。
## 二、用一个小契约约束 Agent 输出
下面的示例把任务总结定义成一个可消费的对象。状态使用枚举,下一步使用数组,避免下游再从自然语言中猜测任务是否完成。
~~~python
from typing import Literal
from openai import OpenAI
from pydantic import BaseModel
class TaskResult(BaseModel):
summary: str
status: Literal["todo", "done", "blocked"]
next_steps: list[str]
risk: str | None
client = OpenAI()
response = client.responses.parse(
model="gpt-5.6",
input=[
{"role": "system", "content": "把任务结果整理成结构化对象。"},
{"role": "user", "content": "检查部署日志并给出下一步。"},
],
text_format=TaskResult,
)
result = response.output_parsed
~~~
在 Python 中可以用 Pydantic 描述类型,JavaScript 则可以用 Zod;SDK 会帮助把类型定义转换为请求所需的 schema。这样,Agent 的规划层、执行层和展示层都围绕同一份契约协作。
## 三、不要忽略拒答与异常输入
结构化输出并不等于“任何输入都有业务答案”。当用户输入触发安全拒答时,响应可能出现独立的 refusal 字段,而不是你定义的对象。应用应先判断是否拒答,再读取解析后的结果,并向用户展示合适的提示。
如果输入与任务完全无关,模型可能为了满足 schema 而填入不可靠内容。系统提示词可以约定:无法判断时返回空数组、特定状态或说明字段,而不是编造事实。业务代码还应对关键字段做二次校验,例如检查资源 ID 是否真实存在、日期是否落在允许范围内。
## 四、把 schema 当作 Agent 的边界
实践中可以把 schema 放在几个边界上:
1. **规划到执行**:规划器只输出允许的动作和参数,执行器拒绝未知动作。
2. **工具到观察**:工具结果先归一化,再交给下一轮推理,避免不同工具返回的字段名称漂移。
3. **执行到用户界面**:用稳定的状态、摘要和证据列表渲染进度,而不是解析一段长文本。
4. **版本治理**:类型定义和 JSON Schema 必须一起变更,可在 CI 中生成或比对 schema,减少两者逐渐分叉。
当响应需要逐步展示时,也可以结合流式处理,先接收已经完成的字段;不过仍要在最终响应完成后做一次完整校验。
## 五、一个可落地的检查清单
- 能用 Structured Outputs 时,不要只依赖 JSON mode。
- 工具调用和用户展示使用不同的结构化契约。
- 给枚举、数组和必填字段设置清晰约束。
- 对拒答、空结果和不相关输入分别设计分支。
- 用 Pydantic/Zod 或自动化检查保持类型与 schema 同步。
- 把 schema 版本写入日志,便于定位 Agent 行为变化。
Structured Outputs 解决的是“输出长什么样”的可靠性问题;业务仍需验证“输出是否正确”。把格式约束、语义校验和人工确认组合起来,Agent 才能在复杂流程中稳定地把结果交给下游系统。
**参考来源**
- OpenAI Developers:《Structured model outputs》:https://developers.openai.com/api/docs/guides/structured-outputs
- OpenAI:《Introducing Structured Outputs in the API》:https://openai.com/index/introducing-structured-outputs-in-the-api/
- 点赞
- 收藏
- 关注作者
评论(0)