跳转到内容

PydanticAI 的多模型适配实践

PydanticAI 的多模型适配实践

学习目标

补充理解:

  • PydanticAI 的 Model ABC → Provider 工厂 → ModelProfile → JsonSchemaTransformer 四层抽象
  • 不同提供商对 JSON Schema 的兼容性差异如何处理
  • 30+ 提供商的注册与推断机制

前置知识


1. 四层抽象架构

PydanticAI 的多模型适配分为四层:

Model ABC (models/__init__.py)
├── request() / request_stream() — 统一请求接口
├── prepare_request() — 合并设置、验证、schema 转换
└── prepare_messages() — 系统提示包装、工具搜索消息合成
Provider (providers/__init__.py)
├── name / base_url / client — 认证和 HTTP 客户端
├── model_profile(model_name) — 模型能力查找
└── __aenter__/__aexit__ — HTTP 客户端生命周期
ModelProfile (profiles/)
├── supports_tools / supports_thinking / supports_json_schema_output
├── thinking_tags / default_structured_output_mode
└── json_schema_transformer — 每个提供商的 schema 转换逻辑
JsonSchemaTransformer (profiles/)
├── OpenAI: strict mode → additionalProperties:false, 全 required
├── Anthropic: SDK transform_schema()
└── Google: 移除 $schema、const→enum、discriminator、examples

2. Provider 推断机制

infer_provider_class(provider: str) 通过一个大型 if/elif 链将提供商名称字符串映射到具体类,支持 30+ 提供商:

openai → OpenAIProvider
anthropic → AnthropicProvider
google, google-cloud → GoogleProvider
bedrock → BedrockProvider
groq → GroqProvider
mistral → MistralProvider
# ... 共 30+ 个

Gateway Providerproviders/gateway.py 提供 gateway/{provider}:model 语法,通过 Pydantic AI 自己的网关服务路由请求。

3. JSON Schema 转换差异

不同提供商对 JSON Schema 的兼容性差异是模型适配的核心挑战:

提供商转换规则
OpenAI (strict)添加 additionalProperties: false,所有 properties 标记为 required,移除 minLength、带 lookaround 的 patternoneOf 替换为 anyOf
Anthropic使用 Anthropic SDK 的 transform_schema()
Google移除 $schemaconst(转为单值 enum)、discriminatorexamples,将 format 移入 description

每种转换逻辑由 JsonSchemaTransformer 的子类实现,在 Model.prepare_request() 中自动应用。

4. 模型 Profile 的演进

ModelProfile 使用 dataclass 定义模型能力标志:

@dataclass
class ModelProfile:
supports_tools: bool = True
supports_tool_return_schema: bool = False
supports_json_schema_output: bool = False
supports_thinking: bool = False
thinking_tags: tuple[str, str] = ('<think>', '</think>')
default_structured_output_mode: StructuredOutputMode = 'tool'

每个提供商定义自己的 Profile 子类(如 OpenAIModelProfileAnthropicModelProfile),添加提供商特定的能力标志(如 openai_supports_reasoninganthropic_supports_adaptive_thinking)。

维护挑战:模型能力标志可能过期——依赖社区贡献和测试覆盖来保持最新。Profile 中的布尔标志是静态的,不反映模型 API 的运行时变化。