Agno 结构化输出四层管线
Agno 结构化输出四层管线
学习目标
本章将分析 Agno 的结构化输出四层管线:
- 四种方式实现结构化输出及其优先级
structured_outputs利用模型原生支持output_schema通过 JSON Schema 注入系统提示parser_model使用二级模型解析响应output_model使用输出模型转换格式
前置知识
建议先阅读:
- 结构化输出策略 — JSON Schema 与 Pydantic 验证
下文假设你已理解上述概念,直接聚焦 Agno 的具体实现。
项目实践
四层优先级
Agno 按以下优先级尝试结构化输出:
| 层级 | 配置 | 原理 | 适用场景 |
|---|---|---|---|
| 1 | structured_outputs=True | 使用模型原生 API(如 OpenAI Responses 的 structured_outputs 参数) | 模型支持时最高质量 |
| 2 | output_schema=MyModel | 将 Pydantic model 转为 JSON Schema 注入系统提示 | 通用方案,所有模型可用 |
| 3 | parser_model=... | 使用独立的二级模型解析主模型的响应 | 主模型结构化能力弱时 |
| 4 | output_model=... | 使用输出模型转换响应 | 需要格式转换时 |
structured_outputs:模型原生支持
# 伪代码:原生结构化输出agent = Agent( model=OpenAIResponses(id="gpt-4o"), output_schema=WeatherResponse, structured_outputs=True, # 使用 OpenAI 的 structured_outputs API)当 structured_outputs=True 时,Agno 将 Pydantic schema 传给模型的原生 API:
# 伪代码:模型调用response = model.chat( messages=messages, response_format=output_schema, # OpenAI 原生参数)优势:模型内部优化结构化输出,质量更高 限制:只有部分模型支持(OpenAI、部分兼容模型)
output_schema:JSON Schema 注入
# 伪代码:JSON Schema 注入agent = Agent( model=OpenAIResponses(id="gpt-4o"), output_schema=WeatherResponse, parse_response=True,)Agno 将 Pydantic model 转为 JSON Schema 并注入系统提示:
# 伪代码:Schema 转字符串schema_str = json.dumps(output_schema.model_json_schema())system_message += f"\n请以以下 JSON Schema 格式返回响应:\n{schema_str}"然后使用 pydantic 解析模型响应:
# 伪代码:响应解析parsed = output_schema.model_validate_json(response.text)return parsedparser_model:二级模型解析
# 伪代码:二级模型解析agent = Agent( model=OpenAIResponses(id="gpt-4o"), output_schema=WeatherResponse, parser_model=OpenAIResponses(id="gpt-4o-mini"), # 用更便宜的模型解析 parser_model_prompt="将以上响应转换为 WeatherResponse 格式。",)流程:
- 主模型生成原始响应
- parser_model 接收原始响应 + schema,输出结构化格式
- 解析结果返回给调用方
优势:可以使用更便宜的模型做解析,降低成本
output_model:输出模型转换
# 伪代码:输出模型转换agent = Agent( model=OpenAIResponses(id="gpt-4o"), output_schema=WeatherResponse, output_model=OpenAIResponses(id="gpt-4o"), output_model_prompt="将以上天气信息转换为标准格式。",)流程:
- 主模型生成响应
- output_model 接收响应 + 转换指令,输出转换后的格式
与 parser_model 的区别:parser_model 侧重于”解析为结构化格式”,output_model 侧重于”转换响应格式”。
use_json_mode
agent = Agent( output_schema=WeatherResponse, use_json_mode=True, # 不传 JSON Schema,改用系统提示中的 JSON 描述)当 use_json_mode=True 时,Agno 不将 Pydantic schema 转为 JSON Schema 传给模型,而是在系统提示中用自然语言描述格式。
适用场景:模型不支持 structured_outputs 参数,或 JSON Schema 导致模型输出质量下降。
问题与规避
1. structured_outputs 与模型不兼容
某些模型不支持 structured_outputs,开启后报错。
规避:Agno 的 determine_tools_for_model 中检查模型能力,自动降级为 JSON Schema 注入模式。
2. 复杂 Pydantic model 的 Schema 转义
嵌套 model、可选字段、自定义验证器的 JSON Schema 可能很复杂。
规避:
- 使用简单扁平 model
use_json_mode=True避免 Schema 转义问题- 测试不同模型的 Schema 兼容性
3. parser_model 的双重 LLM 成本
使用 parser_model 会产生两次 LLM 调用。
规避:
- parser_model 使用更便宜的模型(如 gpt-4o-mini)
- 只在主模型结构化能力弱时使用
设计取舍
为什么提供四种方式?
优势:不同场景不同需求——有原生 API 用原生,没有用 Schema 注入,都不行用二级模型 代价:用户需要理解四种方式的区别 替代方案:只提供两种方式——简单但可能在某些场景下效果不佳
为什么 parser_model 和 output_model 分开?
优势:关注点分离——解析(结构化)与转换(格式化)是两个不同的任务 代价:配置参数多 替代方案:合为一个参数——语义模糊