跳转到内容

PydanticAI 的 Capabilities 中间件系统

PydanticAI 的 Capabilities 中间件系统

学习目标

补充理解:

  • AbstractCapability 的 20+ 生命周期钩子体系
  • CombinedCapability 的拓扑排序与 CapabilityOrdering 约束
  • 内置 Capabilities(Thinking、WebSearch、MCP 等)的具体实现

前置知识


1. 生命周期钩子体系

PydanticAI 的 AbstractCapability 提供四个层级的钩子:

层级钩子用途
Runwrap_run(handler)包装整个 agent run
before_run() / after_run()run 生命周期
Nodewrap_node_run(node, handler)包装单个节点执行
before_node_run() / after_node_run()节点生命周期
Modelwrap_model_request(handler)包装模型调用
before/after_model_request()模型请求前后
Toolwrap_tool_validate(handler)包装工具验证
wrap_tool_execute(handler)包装工具执行
Outputwrap_output_validate(handler)包装输出验证
wrap_output_process(handler)包装输出处理

与通用 Hook 系统的差异

  • 通用 Hook 系统通常只提供 before/after 两个点
  • PydanticAI 的 wrap_* 模式提供了环绕(around) 能力——可以在调用 handler() 前后执行任意逻辑,甚至可以跳过 handler() 短路

2. CombinedCapability 与拓扑排序

CombinedCapability 将多个 capability 组合为一个,并按 CapabilityOrdering 约束进行拓扑排序:

CapabilityOrdering:
position: int # 显式位置
wraps: CapabilityRef # 在某 capability 之后
wrapped_by: CapabilityRef # 在某 capability 之前
requires: CapabilityRef # 依赖某 capability

为什么需要拓扑排序?

  • 某些 capability 必须在其他 capability 之前执行(如 Instrumentation 必须在最外层包装)
  • wraps 约束确保正确的嵌套顺序——A.wraps = B 意味着 A 的 wrap_* 钩子会包裹 B
  • CombinedCapability 会扁平化嵌套的 CombinedCapability——避免深层嵌套导致的性能问题

3. 内置 Capabilities 分类

PydanticAI 内置的 Capabilities 按功能分为:

类别Capabilities
Provider 自适应工具ThinkingWebSearchWebFetchImageGenerationXSearchMCPToolSearch
工具处理PrepareToolsPrepareOutputToolsPrefixToolsIncludeToolReturnSchemasSetToolMetadata
生命周期InstrumentationHooksProcessHistoryProcessEventStreamThreadExecutor
Human-in-the-LoopHandleDeferredToolCalls
原生工具注册NativeTool

Provider 自适应工具模式NativeOrLocalTool 基类同时注册原生工具和本地回退工具集。当模型支持原生工具时,本地回退自动被 unless_native 机制丢弃。

4. Hooks Capability 的装饰器模式

Hooks capability 提供装饰器风格的钩子注册,作为 AbstractCapability 子类化的替代方案:

from pydantic_ai.capabilities import Hooks
hooks = Hooks()
@hooks.before_model_request
async def log_request(ctx):
print(f"Model request: {ctx.prompt}")

支持超时(timeout)和按工具过滤(tool_selector),适合不需要完整 capability 类的简单钩子。