跳转至

pydantic/pydantic-ai: 类型安全与执行契约

PydanticAI 解决的核心痛点是:如何将生成式模型的不确定输出,强行拉回工程级的类型化控制线。 它通过 Pydantic 的校验能力,为模型、工具与宿主系统之间立下了一份“硬契约”。

1. 核心模型:类型驱动的运行链

不要把模型看作“对话者”,要把它看作一个返回结构化对象的函数

  • Result Types (结果类型):定义模型输出的终点状态。工程直觉:模型不再是输出自由文本,而是必须填充一个由 Pydantic 校验的 Python 对象。如果结构不符,运行时会直接抛出 ValidationError
  • Run Context (运行上下文):显式承载宿主系统的依赖(如数据库连接、租户信息)。它让 Agent 逻辑与宿主逻辑通过依赖注入(DI)解耦,而不是将敏感字段塞进 Prompt。
  • Tool Manager (工具管理):工具的输入/输出同样受 Pydantic 约束。模型必须生成符合类型定义的 JSON 才能成功触发工具调用。

2. 契约前置的价值

  • 防御式执行:在工具真正执行前完成参数校验。防止模型生成非法的数据库 ID 或超出范围的金额参数。
  • 故障定位清晰化:能够明确区分是“模型理解错误”还是“输出结构违约”。这对于线上监控与 Prompt 迭代具有决定性意义。

3. 与 LangChain/LangGraph 的分层博弈

  • vs LangChain:LangChain 侧重于“链式编排”,而 PydanticAI 侧重于“结果的健壮性”。在复杂的生产环境,结果接不住(Type Mismatch)往往比流程断了更难处理。
  • vs LangGraph:LangGraph 解决的是“长任务状态流”,PydanticAI 解决的是“单步/多步交互的契约质量”。两者并不排斥,但 PydanticAI 提供了更现代的类型系统集成。

4. 常见误区与失效模式

  • 弱契约陷阱:定义的 ResultType 过于宽泛(如只用 Dict[str, Any]),导致类型系统形同虚设,业务代码依然在处理脏数据。
  • 忽略 Context 注入:依然习惯于把可信的业务字段(如 user_id)从 Prompt 里传给 Agent,而不是通过 RunContext 进行注入,增加了提示词注入(Prompt Injection)的风险。
  • 校验失败无重试:当模型输出结构微调导致校验失败时,缺乏自动纠偏(Self-correction)逻辑,导致系统可用性下降。

5. 排查顺序:从契约到逻辑

  1. 核对 Validation Error:是哪个字段缺失或类型错误?是否是因为 Prompt 里的 Schema Description 描述不清?
  2. 检查 RunContext 注入:宿主依赖是否正确传入?Agent 是否拿到了预期的数据库句柄?
  3. 分析 Tool Schema:工具参数是否因为模型“幻觉”而超出了类型限制?
  4. 监测输出分布:在大量请求中,模型违反契约的频率是多少?是否需要换用更强的推理模型(如 GPT-4o)来保住结构化输出的稳定性?

结论PydanticAI 是 Agent 的“强类型接口”。它强迫开发者从“调教提示词”转向“定义执行契约”,让 AI 系统真正具备后端工程的可维护性。