强类型 Message Parts 设计 (Pydantic AI)
Related topics: [[streaming-tool-assembly-pydantic-ai]], [[async-streaming-first-class]]
Overview
Pydantic AI 的强类型 Message Parts 设计展示了如何使用 Python 的类型系统来构建一个类型安全、可扩展的多模态消息系统。核心设计哲学是:通过 Discriminator 模式和泛型,让编译器帮你保证消息处理的正确性。
Key Concepts
1. UserContent 联合类型 - 多模态输入的统一抽象
# pydantic_ai/messages.py
UserContent = Union[
str, # 纯文本
ImageUrl, # 图片 URL
AudioUrl, # 音频 URL
VideoUrl, # 视频 URL
BinaryContent, # 二进制内容
DocumentUrl, # 文档 URL
]
"""User content can be a string or any of the URL/content types."""
设计亮点:
- 最简单的
str作为默认选项,向后兼容 - 多模态内容通过 URL 类型封装,延迟加载/验证
- 统一的
FileUrl基类提供公共功能(force_download, vendor_metadata)
2. ModelMessage 层次结构 - 对话消息的类型安全表达
# pydantic_ai/messages.py
ModelMessage = Annotated[
Union[
ModelRequest, # 用户/系统的请求
ModelResponse, # 模型的响应
],
Field(discriminator='kind'), # Discriminator-based 序列化
]
@dataclass
class ModelRequest:
"""A request message sent to the model."""
parts: list[ModelRequestPart]
kind: Literal['request'] = 'request'
@dataclass
class ModelResponse:
"""A response message received from the model."""
parts: list[ModelResponsePart]
kind: Literal['response'] = 'response'
timestamp: datetime = field(default_factory=now_utc)
Discriminator 模式优势:
- 序列化后自动反序列化到正确类型
- IDE 自动补全和类型检查
- 避免手动类型判断和转换
3. Part 类型系统 - 细粒度的内容组件
# pydantic_ai/messages.py - 请求 Part
ModelRequestPart = Annotated[
Union[
SystemPromptPart, # 系统提示
UserPromptPart, # 用户提示
ToolReturnPart, # 工具返回结果
RetryPromptPart, # 重试提示
],
Field(discriminator='part_kind'),
]
# pydantic_ai/messages.py - 响应 Part
ModelResponsePart = Annotated[
Union[
TextPart, # 文本内容
ImagePart, # 图片内容
ToolCallPart, # 工具调用
ThinkingPart, # 思考内容(如 Claude)
],
Field(discriminator='part_kind'),
]
每个 Part 都有 discriminator 字段:
@dataclass
class TextPart:
content: str
part_kind: Literal['text'] = 'text' # Discriminator
@dataclass
class ToolCallPart:
tool_name: str
args: dict[str, Any]
tool_call_id: str
part_kind: Literal['tool-call'] = 'tool-call' # Discriminator