EN

Zod vs Pydantic 用于 AI 验证:并排对比

AI 输出的模式验证对比——比较 Zod 和 Pydantic 的类型安全性

返回教程列表🌐 Read in English
进阶10 分钟

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 代码块中。你的验证层是“模型说了什么”和“我的代码可以安全使用它”之间的边界。

概览

ZodPydantic

语言TypeScriptPython 验证时机运行时,类型静态推断运行时,类型通过注解 核心实现纯 TSRust 核心(pydantic-core,v2) AI 生态系统Vercel AI SDK, LangChain.js, OpenAI SDK (zodResponseFormat)OpenAI/Anthropic SDKs, Instructor, PydanticAI, LangChain JSON Schema 导出内置(z.toJSONSchema, Zod 4+)内置(model_json_schema) 强制转换/修复z.coerce, transform, catch宽松模式强制转换,字段/模型验证器

两者完成相同任务

从 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 Literal

class 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 OpenAI

client = 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_validator

class 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.issuesValidationError.errors())。Pydantic 的错误消息往往稍微冗长一些,模型实际上能更好地从中修复。

流式传输呢? Vercel AI SDK 的 streamObject 根据 Zod 模式逐步验证;在 Python 中,部分验证是 Instructor 的 create_partial / PydanticAI 流式传输所处理的。


*最后更新:2026 年 6 月。API 变化很快——请对照 Zod、Pydantic 和提供商 SDK 文档进行验证。*

相关工具

zodpython