Zod vs Pydantic 用于 AI 验证:并排对比
AI 输出的模式验证对比——比较 Zod 和 Pydantic 的类型安全性
Zod vs Pydantic 用于 AI 验证:并排对比
AI 输出的模式验证对比——比较 Zod 和 Pydantic 的类型安全性
Zod vs Pydantic 用于 AI 输出验证(2026):TypeScript 栈使用 Zod(Vercel AI SDK),Python 栈使用 Pydantic(OpenAI SDK/Instructor)。LLM 输出是不可信输入——包含两个栈的实际代码、自修复重试、反幻觉语义验证以及跨栈 JSON Schema 同步。
Zod vs Pydantic 用于 AI 验证:并排对比
如果你只需要一句话:这很少是非此即彼的选择——Zod 是 TypeScript 应用的默认选择(也是 Vercel AI SDK 所期望的),Pydantic 是 Python 应用的默认选择(也是 OpenAI/Anthropic SDK 和大多数代理框架所依赖的)。真正的问题是你的 AI 层使用哪种语言。
但在处理 AI 工程的核心问题——LLM 输出是不可信输入——方面,两者确实存在有趣的差异。模型会返回格式错误的 JSON、幻觉枚举值、省略必填字段,并将所有内容包裹在 Markdown 代码块中。你的验证层是“模型说了什么”和“我的代码可以安全使用它”之间的边界。
概览
两者完成相同任务
从 LLM 中提取结构化数据并拒绝垃圾数据:
typescript
// Zod + Vercel AI SDK
import { generateObject } from 'ai';
import { z } from 'zod';const Invoice = z.object({
vendor: z.string().min(1),
totalCents: z.number().int().nonnegative(),
currency: z.enum(['USD', 'EUR', 'CNY']),
dueDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/)
});
const { object } = await generateObject({
model: 'anthropic/claude-sonnet-4-5',
schema: Invoice,
prompt: Extract the invoice fields from: ${emailBody}
});
// object 是完全类型化的:{ vendor: string; totalCents: number; ... }
python
Pydantic + OpenAI SDK(原生结构化输出)
from openai import OpenAI
from pydantic import BaseModel, Field
from typing import Literalclass Invoice(BaseModel):
vendor: str = Field(min_length=1)
total_cents: int = Field(ge=0)
currency: Literal['USD', 'EUR', 'CNY']
due_date: str = Field(pattern=r'^\d{4}-\d{2}-\d{2}$')
client = OpenAI()
completion = client.chat.completions.parse(
model='gpt-4o',
messages=[{'role': 'user', 'content': f'Extract the invoice fields from: {email_body}'}],
response_format=Invoice
)
invoice = completion.choices[0].message.parsed # 类型化的 Invoice 实例
两个栈在底层都做了三件事:将你的模式转换为 JSON Schema 供模型的结构化输出模式使用,解析响应,并进行验证——在坏数据通过时抛出异常/错误。
实际差异
强制转换哲学
LLM 喜欢在你期望42 的地方返回 "42"。Pydantic 的默认(宽松)模式会自动处理常见情况;严格模式可以按字段或按模型关闭此功能。Zod 默认是严格的,你需要通过 z.coerce.number() 或 .transform() 选择启用强制转换。对于 AI 输出,两边的务实做法是一样的:强制转换标量,绝不强制转换结构——缺失的字段应该大声失败,而不是静默地使用默认值。自修复循环
当验证失败时,你通常希望重试一次,并将错误信息反馈给模型:python
Instructor 在 Pydantic 之上添加了此功能
import instructor
from openai import OpenAIclient = instructor.from_openai(OpenAI())
invoice = client.chat.completions.create(
model='gpt-4o',
response_model=Invoice,
max_retries=2, # 验证错误被发送回模型
messages=[{'role': 'user', 'content': email_body}]
)
在 TypeScript 领域,Vercel AI SDK 的 generateObject 内部处理格式错误的 JSON 修复;对于自定义流程,你捕获 ZodError,序列化 error.issues,然后重新提示。如果你正在选择 Python 结构化输出栈,我们在 PydanticAI vs Instructor 中比较了两个主要选项。
超越形状的验证
真正的 AI 验证是语义上的,而不仅仅是结构上的。两者都很好地支持自定义规则:typescript
const Answer = z.object({
quote: z.string(),
sourceId: z.string()
}).refine(a => knownSourceIds.has(a.sourceId), {
message: 'sourceId must reference a retrieved document' // 反幻觉检查
});
python
from pydantic import model_validatorclass Answer(BaseModel):
quote: str
source_id: str
@model_validator(mode='after')
def source_must_exist(self):
if self.source_id not in known_source_ids:
raise ValueError('source_id must reference a retrieved document')
return self
这种模式——根据检索上下文验证模型声明——是 RAG 系统中最高杠杆的反幻觉防护之一。
性能
Pydantic v2 的 Rust 核心快速验证大型负载;Zod 4 也带来了重大速度提升。对于典型的 AI 工作负载,验证成本与 LLM 调用本身相比微不足道(毫秒 vs 秒)——不要根据性能来选择。全栈现实:两者都用
一个常见的生产设置是 TypeScript 前端/API 层,后面跟着 Python ML 服务。保持它们诚实的契约是 JSON Schema:一次定义模式(通常在 Pydantic 中,更接近模型层),使用 model_json_schema() 导出,并在 CI 中生成 Zod 镜像(例如使用 json-schema-to-zod),这样两者就不会漂移。
FAQ
结构化输出模式是否使验证变得多余? 不。提供商的 JSON Schema 强制保证形状,而不是意义——类似枚举的字符串、看似合理但虚假的 ID 和语义约束仍然需要你的验证器。
哪个有更好的错误消息用于重新提示? 两者都生成机器可读的问题列表(ZodError.issues,ValidationError.errors())。Pydantic 的错误消息往往稍微冗长一些,模型实际上能更好地从中修复。
流式传输呢? Vercel AI SDK 的 streamObject 根据 Zod 模式逐步验证;在 Python 中,部分验证是 Instructor 的 create_partial / PydanticAI 流式传输所处理的。
*最后更新:2026 年 6 月。API 变化很快——请对照 Zod、Pydantic 和提供商 SDK 文档进行验证。*
相关工具
相关教程
OpenAI API 模式中的成本与吞吐量权衡——跨 openai 和 python 的批处理对比
AI 编程环境对比——深入比较 Anthropic 与 OpenAI 的开发者工具
Transformers.js 与 ONNX Runtime 浏览器端 AI 推理详细对比
两大领先LLM框架深度对比
LangChain与LlamaIndex构建检索增强生成应用的诚实技术对比,含基准测试、用例及迁移指南
2026年哪款AI编码助手能节省最多开发时间?真实基准测试、定价及500+工程师的开发者反馈