跳转到内容

PydanticAI 的结构化输出多模式实践

PydanticAI 的结构化输出多模式实践

学习目标

补充理解:

  • Tool/Native/Prompted 三种结构化输出模式的对比
  • OutputSchema 层次结构与处理器链
  • 流式输出的渐进验证(allow_partial

前置知识


1. 三种输出模式对比

PydanticAI 支持三种结构化输出模式:

模式机制适用场景限制
Tool通过函数调用产生结构化输出所有支持工具调用的模型最通用
Native使用模型的 response_format 原生支持OpenAI/Groq 等支持结构化输出的模型必须是唯一输出
Prompted通过 prompt 注入 JSON Schema({schema} 占位符)不支持原生结构化输出的模型依赖模型遵循 prompt

AutoOutputSchema:根据 ModelProfile.default_structured_output_mode 自动选择——用户无需关心模型支持哪种模式。

2. OutputSchema 层次

OutputSchema[T] (抽象基类)
├── TextOutputSchema — 纯文本输出,可选 TextOutputProcessor
├── StructuredTextOutputSchema (抽象)
│ ├── NativeOutputSchema — 原生结构化输出
│ └── PromptedOutputSchema — prompt 注入 schema
├── ToolOutputSchema — 通过工具调用输出
│ └── output_toolset: OutputToolset
│ └── ObjectOutputProcessor / UnionOutputProcessor
├── AutoOutputSchema — 模型自动选择
└── ImageOutputSchema — 图像输出

OutputToolset 将输出工具管理为一个 toolset,包含一个或多个 ObjectOutputProcessor 实例:

  • ObjectOutputProcessor:针对单个 Pydantic 模型的验证 + 输出函数执行
  • UnionOutputProcessor:处理多个输出类型的鉴别联合({"result": {"kind": "...", "data": {...}}}

3. 流式输出的渐进验证

PydanticAI 的 stream_output() 使用 Pydantic 的 allow_partial='trailing-strings' 进行渐进验证:

stream_output(debounce_by=0.1):
1. 接收流式 token
2. 尝试 partial validation (allow_partial)
3. 如果验证通过,yield 当前输出
4. 如果验证失败,等待更多 token
5. 流完成时,full validation (最终验证)

重要:流式输出在验证完成前可能产生部分结果——消费者需要区分 incompletecomplete 状态。

4. StructuredDict

无需 Pydantic 模型的结构化输出:

schema = {'type': 'object', 'properties': {'name': {'type': 'string'}, 'age': {'type': 'integer'}}}
agent = Agent('openai:gpt-5.2', output_type=StructuredDict(schema))

StructuredDict 创建一个 dict[str, Any] 的子类,附带 JSON Schema——适合简单的结构化输出场景。

限制:不支持递归 $ref$defs——schema 必须是扁平的。

5. 输出验证钩子链

输出验证也通过 capability 钩子链:

before_output_validate → wrap_output_validate → after_output_validate
before_output_process → wrap_output_process → after_output_process

这使得可以在输出验证前后注入自定义逻辑(如日志记录、格式转换)。