Structured Output Specification
Nikola Balic (@nibzard)· established
问题
自由格式的Agent输出难以验证、解析,也难以与下游系统集成。当Agent返回非结构化文本时,你会面临以下问题:
- 输出格式不可预测,需要复杂的解析逻辑
- 验证与错误处理难度大
- 与自动化工作流的集成脆弱不堪,易失效
- 分类与归类结果不一致
- 需手动进行后处理以提取结构化数据
这使得构建可靠的多步骤工作流几近不可能——在这类工作流中,一个Agent的输出会作为输入传递给另一个系统或Agent。
方案
使用确定性schema约束Agent的输出,确保生成结构化、机器可读取的结果。不再允许自由文本回复,而是通过类型系统、JSON Schema或框架专属的结构化输出API来指定精确的输出格式。
核心方法:
定义明确的输出schema:
- 使用TypeScript接口、JSON Schema或Pydantic模型
- 指定必填字段、类型与约束条件
- 为分类输出定义枚举类型
- 记录字段语义与验证规则
利用框架的结构化输出API:
- OpenAI基于JSON Schema的结构化输出
- Anthropic通过工具调用实现结构化结果
- Vercel AI SDK的
generateObject函数 - LangChain的输出解析器
生成阶段验证:
- 框架确保LLM严格遵循schema
- 在输出到达应用代码前捕获类型错误
- 保证输出可被解析
示例实现:
import { generateObject } from 'ai';
import { z } from 'zod';
// 定义严格的输出schema
const LeadQualificationSchema = z.object({
qualification: z.enum(['qualified', 'unqualified', 'needs_review']),
confidence: z.number().min(0).max(1),
companySize: z.enum(['enterprise', 'mid-market', 'smb', 'unknown']),
estimatedBudget: z.string().optional(),
nextSteps: z.array(z.string()),
reasoning: z.string()
});
// Agent返回经过结构化验证的输出
const result = await generateObject({
model: openai('gpt-4'),
schema: LeadQualificationSchema,
prompt: `分析这条销售线索:${leadData}`
});
// TypeScript知晓输出的精确结构
if (result.object.qualification === 'qualified') {
await sendToSalesTeam(result.object);
}
集成优势:
graph LR
A[Agent输入] --> B[LLM + Schema]
B --> C[已验证的结构化输出]
C --> D[下游系统]
C --> E[数据库存储]
C --> F[下一Agent阶段]
style C fill:#90EE90
如何使用
适用场景:
- 需结构化交接的多阶段Agent工作流
- 分类与归类任务
- 数据提取与转换
- 与数据库或API的集成
- 合规性与审计要求
- 质量保证与验证
实施步骤:
1. 确定输出要求:
- Agent需要做出哪些决策?
- 必须提取哪些数据?
- 哪些下游系统会消费该输出?
2. 设计数据模式:
from pydantic import BaseModel, Field
from typing import Literal
class AbuseAnalysis(BaseModel):
content_type: Literal['spam', 'abuse', 'legitimate', 'unclear']
severity: Literal['critical', 'high', 'medium', 'low']
recommended_action: Literal['remove', 'warn', 'ignore', 'escalate']
confidence_score: float = Field(ge=0, le=1)
evidence: list[str]
requires_human_review: bool
3. 与Agent框架集成:
result = client.generate(
model="gpt-4",
response_format=AbuseAnalysis,
messages=[{"role": "user", "content": abuse_report}]
)
# 结果将严格匹配预设模式
if result.requires_human_review:
await send_to_human(result)
else:
await auto_execute(result.recommended_action)
4. 处理验证失败:
- 结合更明确的prompt重试
- 回退至人工审核
- 记录模式违规情况以优化prompt
前置条件:
- 支持结构化输出的Agent框架
- 清晰理解下游数据需求
- 模式验证库(Zod、Pydantic、JSON Schema)
权衡
优势:
- 可靠性: 可保证的可解析输出,消除解析错误
- 类型安全: 类型化语言中的编译时检查
- 集成性: 与数据库、API、工作流无缝对接
- 验证机制: 内置约束校验能力
- 可维护性: 系统组件间的显式契约
- 可测试性: 便于验证输出正确性
劣势:
- 僵化性: 修改Schema需同步更新相关组件
- 复杂度: 需预先投入Schema设计成本
- 表达能力受限: 可能会限制有用的自由格式输出
- 框架依赖: 依赖LLM服务商的Schema支持能力
- 过度定义: 过于严格的Schema可能导致生成失败
- 演进阻力: 随需求变更调整Schema时存在阻碍
缓解策略:
- 添加可选的
additional_context字段,用于存储自由格式备注 - 为Schema添加版本标识并支持优雅降级
- 针对动态演进的分类场景使用联合类型
- 平衡结构化与灵活性(合理搭配必填字段与可选字段)
参考文献
关键词:
聚焦大模型结构化输出技术,涵盖Vercel智能体构建实践、OpenAI/Anthropic的结构化输出实现方案、Vercel AI SDK的TypeScript原生结构化生成工具,及离散阶段分离、人机协同审批框架两类相关设计模式。
直译:
- Vercel:构建智能体的经验总结 - 基于结构化分类的销售线索资质判定
- OpenAI 结构化输出 - JSON 模式约束
- Vercel AI SDK generateObject 方法 - TypeScript 原生结构化生成
- Anthropic 工具调用 - 通过工具调用实现结构化输出
- 相关模式:离散阶段分离、人机协同审批框架
来源摘要
正在获取来源并生成中文摘要…
来源: https://vercel.com/blog/what-we-learned-building-agents-at-vercel