I use Pydantic v2 across my project to enforce strict type checking, automatic runtime validation, and structured data handling for LLM inputs and outputs.
- Performance & Core Engine: Built on Rust for extremely fast parsing and validation.
- Modern API: Utilizes standard V2 idioms like
model_validate()andmodel_dump()rather than deprecated V1 methods (parse_obj(),.dict()). - Python 3.9+ Type Hints: Integrates seamlessly with standard generic hints (
list[str],dict[str, Any]) without requiring legacytyping.Listortyping.Dictwrappers.
I define structured BaseModel classes to represent standard API request payloads, system tool definitions, and parsed LLM responses:
from typing import Any
from pydantic import BaseModel
class Message(BaseModel):
role: str
content: str
class FunctionParameter(BaseModel):
type: str
properties: dict[str, Any]
required: list[str]
class Function(BaseModel):
name: str
description: str
parameters: FunctionParameter
class Tool(BaseModel):
type: str
function: Function
class RequestData(BaseModel):
model: str
messages: list[Message]
tools: list[Tool]
stream: bool = False
think: bool = False- Guaranteed Schema Adherence: Every JSON response generated by the LLM is validated against models like
SelectedFunction. - Runtime Error Boundary: If the model outputs invalid parameters or missing required fields, Pydantic triggers a
ValidationError. My parsing logic captures this failure cleanly, returning a default null object instead of allowing unhandled runtime exceptions to crash the application. - Serialization: Simplifies conversions between Python dictionaries, raw JSON strings, and typed objects via
.model_dump()and.model_dump_json().