Mastering Pydantic AI: A Comprehensive Guide to Type-Safe LLM Agents
Introduction
Building LLM agents that produce structured, reliable outputs is a game-changer for Python developers. With Pydantic AI, you can enforce type safety, automate validation retries, wire in dependency injection, and create customizable tools—all while keeping production costs in check. This step-by-step guide will walk you through constructing a type-safe LLM agent from scratch, leveraging the same principles tested in the original quiz: structured outputs, validation retries, tool calling, RunContext for dependencies, and real-world trade-offs. By the end, you’ll have a production-ready template for your own agents.

What You Need
- Python 3.10+ installed
- Pydantic AI library (
pip install pydantic-ai) - An LLM API key (OpenAI, Anthropic, or any supported provider)
- A code editor (VS Code, PyCharm, etc.)
- Basic familiarity with Pydantic models and async Python
Step-by-Step Guide
Step 1: Define Your Structured Output Schema
The foundation of type-safe agents is a Pydantic model that describes exactly what the LLM should return. Create a file schemas.py and define your output class with typed fields and optional validators.
from pydantic import BaseModel, Field
class MovieReview(BaseModel):
title: str = Field(..., description="Movie title")
rating: float = Field(..., ge=0, le=10, description="Rating out of 10")
summary: str = Field(..., max_length=500)
This schema forces the LLM to output data that matches these constraints. The structured output is automatically parsed and validated—no manual JSON wrangling.
Step 2: Configure the LLM Agent with Your Schema
Now instantiate an agent using pydantic_ai.Agent, passing your model and system prompt. The agent will use the schema to request type-safe responses from the LLM.
from pydantic_ai import Agent
agent = Agent(
model='openai:gpt-4o',
result_type=MovieReview,
system_prompt="You are a movie critic. Always return a structured review."
)
The result_type parameter tells Pydantic AI to enforce the schema on every model response. If the LLM returns anything malformed, the agent will automatically retry with validation (more on that in Step 3).
Step 3: Implement Validation Retries for Reliability
LLMs occasionally produce incorrect JSON or violate constraints. Pydantic AI lets you set a maximum number of retries when validation fails. The agent will resend the prompt with the validation error, helping the LLM correct itself.
agent = Agent(
...
max_retries=3, # Retry up to 3 times on validation failure
)
This dramatically improves reliability. In production, you might combine retries with exponential backoff. The validation retry mechanism ensures your agent never silently returns broken data.
Step 4: Build Custom Tools and Enable Function Calling
Tools allow your agent to interact with external APIs or perform computations. Defining a tool is as simple as creating a Pydantic model for the input, then decorating a function with @agent.tool.
from pydantic import BaseModel
class SearchInput(BaseModel):
query: str = Field(..., description="Search term")
max_results: int = Field(default=5, ge=1, le=20)
@agent.tool
async def search_movie_db(ctx: RunContext, input: SearchInput) -> str:
"""Search a movie database for a given query."""
# API call logic here
return "Results: ..."
The function calling integration means the LLM decides when to invoke tools based on the conversation. Pydantic AI ensures the input arguments match the schema, so you get type safety for free.

Step 5: Manage Dependencies with RunContext
Real agents often need access to databases, API clients, or user state. RunContext is a dependency injection container that flows through every tool and result handler. First, define your dependencies:
from pydantic_ai import RunContext
from dataclasses import dataclass
@dataclass
class MyDeps:
user_id: int
db_session: DatabaseSession
Then pass dependencies when running the agent:
deps = MyDeps(user_id=42, db_session=session)
result = await agent.run("What's the best movie for me?", deps=deps)
Inside a tool, you can access ctx.deps to get the injected dependencies. This keeps your agent clean, testable, and decoupled from global state.
Step 6: Handle Production Trade-Offs
Running agents at scale introduces trade-offs. Here’s what to consider:
- Cost vs. retries: More retries improve accuracy but increase API costs. Set
max_retriescarefully based on your tolerance for latency and expense. - Tool execution time: Tools that call external APIs can stall the agent. Use timeouts and
asynciosafeguards. - Rate limiting: Wrap LLM calls with rate limiters to avoid throttling.
- Error handling: Always wrap agent runs in try/except blocks. Pydantic AI raises
ModelRetryor validation errors that you can catch and log.
A common pattern is to combine Step 3’s retries with a fallback output (e.g., a default review) when all retries fail.
Tips for Success
- Start simple—define a single output model before adding tools or dependencies.
- Test your schema with dummy LLM responses to ensure validation works correctly.
- Use
agent.run_sync()for synchronous contexts (e.g., scripts) andagent.run()for async apps. - Log all retries and tool calls to monitor agent behavior in production.
- When dependency injection grows complex, consider using
pydantic_ai.Dependsfor type-safe injection into tool functions. - Review the official Pydantic AI documentation for advanced features like streaming, multi-turn conversations, and model versioning.
By following these steps, you’ve built a type-safe LLM agent that outputs structured data, retries on validation failures, uses tools with function calling, and manages dependencies cleanly. The same principles that made the original quiz challenging now empower you to ship robust, production-grade agents with confidence.
Related Articles
- 10 Critical Concerns Behind OpenAI's Failure to Report Threats of Violence from ChatGPT
- How Here’s how the new Microsoft and OpenAI deal breaks down
- GPT-5.5 on Microsoft Foundry: Enterprise-Ready AI with Advanced Agentic Capabilities
- Anthropic Deploys Claude Opus 4.7 on Amazon Bedrock – Promises Breakthrough in Agentic Coding and Long‑Running Tasks
- OpenAI Enhances ChatGPT Account Security with Multi-Factor Authentication and Session Controls
- Breakthrough Algorithm SPEX Unlocks Hidden Interactions in Large Language Models at Scale
- How to Identify Critical Interactions in Large Language Models at Scale
- What You Need to Know About Live updates from Elon Musk and Sam Altman’s co...