What Is Pydantic AI?
Pydantic AI is a Python framework for building AI agents with production-grade type safety. Created by Samuel Colvin and the Pydantic team, it extends the same validation-first philosophy that made Pydantic the standard for data validation in Python (used by FastAPI, SQLModel, and thousands of other projects) into the world of AI agent development.
The framework centers on three core ideas. First, structured outputs: instead of parsing raw LLM text, you define a Pydantic model and the framework ensures the response conforms to it, automatically retrying when validation fails. Second, type-safe tools: agent tools are regular Python functions with type hints, and the framework generates JSON schemas and validates call arguments at the boundary. Third, dependency injection: runtime context flows into tools through a typed Deps parameter, making agents testable and composable.
Pydantic AI supports all major LLM providers — OpenAI, Anthropic, Google Gemini, Groq, Mistral, and any OpenAI-compatible API including Ollama for local development. Switching models requires changing one line of configuration; the agent logic, tools, and output schemas remain identical. This provider-agnostic design is essential for production systems where you may need to switch models for cost, latency, or capability reasons.
The design philosophy is intentionally minimalist. Where other frameworks build towering abstractions over every concept, Pydantic AI stays close to Python idioms. This makes the learning curve gentle for anyone familiar with Pydantic, FastAPI, or modern Python typing — and makes debugging straightforward because there are fewer layers between your code and the LLM.
How to Calculate Better Results with pydantic ai agent framework python type-safe structured outputs dependency injection tool calling
Install Pydantic AI: pip install pydantic-ai. This pulls in Pydantic v2, httpx, and the core framework. For specific model providers, install extras like pip install pydantic-ai[openai] or pydantic-ai[anthropic]. Set your API key as an environment variable (OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.).
Create your first agent: from pydantic_ai import Agent; agent = Agent("openai:gpt-4o", system_prompt="You are a helpful coding assistant."). Run it synchronously with result = agent.run_sync("Explain dependency injection in 3 sentences"). The result object contains the validated output, usage stats, and message history.
Add structured outputs: define a Pydantic model for the response schema, pass it as result_type to the Agent constructor. For example, Agent("openai:gpt-4o", result_type=CodeReview) where CodeReview has fields like issues: list[Issue], overall_score: int, summary: str. The framework handles schema generation, validation, and retry.
Register tools: decorate a function with @agent.tool and give it typed parameters. The framework auto-generates the tool schema, sends it to the LLM, validates call arguments, executes the function, and returns results. Add dependencies by defining a Deps type and passing an instance to agent.run_sync(prompt, deps=my_deps).
Treat this page as a decision map. Build a shortlist fast, then run a focused second pass for security, ownership, and operational fit.
When a team keeps one shared selection rubric, tool adoption speeds up because evaluators stop debating criteria every time a new option appears.
Worked Examples
Building a code review agent with structured output
- Define a Pydantic model: class CodeReview(BaseModel): issues: list[Issue]; score: int; summary: str; suggestions: list[str]
- Create the agent: agent = Agent("anthropic:claude-sonnet-4-20250514", result_type=CodeReview, system_prompt="You are a senior code reviewer.")
- Register a tool that reads files: @agent.tool_plain def read_file(path: str) -> str that returns file contents
- Run: result = agent.run_sync("Review the authentication module in src/auth.py")
- The agent calls read_file, analyzes the code, and returns a validated CodeReview instance
- Access structured fields: result.data.score, result.data.issues[0].severity — fully typed, no parsing needed
Outcome: A code review agent that returns machine-readable, validated results. You can feed these into CI pipelines, dashboards, or other systems without parsing free-text output.
Multi-model agent with dependency injection for testing
- Define dependencies: @dataclass class Deps: db: Database; http: httpx.AsyncClient
- Create agent with deps type: agent = Agent("openai:gpt-4o", deps_type=Deps)
- Register tools that use deps: @agent.tool async def fetch_user(ctx: RunContext[Deps], user_id: int) -> User that calls ctx.deps.db.get_user(user_id)
- In production: result = await agent.run("Look up user 42", deps=Deps(db=real_db, http=real_client))
- In tests: result = await agent.run("Look up user 42", deps=Deps(db=mock_db, http=mock_client))
- Same agent logic, same tools, different runtime context — fully testable without mocking the LLM
Outcome: A production-grade agent where database connections, HTTP clients, and other dependencies are injected at runtime. Tests use mocks, production uses real services, and the agent code stays identical.
Frequently Asked Questions
What is Pydantic AI?
Pydantic AI is a Python agent framework built by the team behind Pydantic, the most popular data validation library in the Python ecosystem. It brings Pydantic's type-safety philosophy to AI agents: structured outputs validated by Pydantic models, dependency injection for testability, tool registration with type-checked parameters, and first-class support for multiple LLM providers including OpenAI, Anthropic, Google Gemini, Groq, Mistral, and Ollama.
How does Pydantic AI compare to LangChain?
Pydantic AI is more opinionated and lighter than LangChain. It focuses on type safety and validation rather than providing a massive abstraction layer. Where LangChain gives you chains, agents, memory modules, and dozens of integrations, Pydantic AI gives you a clean Agent class with typed tools, structured outputs, and dependency injection. If you value type safety and simplicity over breadth of integrations, Pydantic AI is the better choice.
What models does Pydantic AI support?
Pydantic AI supports OpenAI (GPT-4o, o1, o3), Anthropic (Claude 4 Opus, Sonnet, Haiku), Google Gemini (2.5 Pro, Flash), Groq (Llama, Mixtral), Mistral, and any OpenAI-compatible API including Ollama for local models. Switching models requires changing one line — the agent logic and tools remain identical.
What are structured outputs in Pydantic AI?
Structured outputs mean the agent returns a Pydantic model instance, not a raw string. You define a response schema (e.g., class WeatherReport(BaseModel): city: str; temp_c: float; summary: str) and Pydantic AI ensures the LLM response validates against it. Invalid responses are automatically retried with the validation error fed back to the model. This eliminates manual parsing and provides runtime type guarantees.
What is dependency injection in Pydantic AI?
Dependency injection lets you pass runtime context (database connections, HTTP clients, user sessions) to agent tools without hardcoding them. You define a Deps type, pass an instance when running the agent, and every tool function receives it as a parameter. This makes agents testable (swap real deps for mocks) and composable (same agent, different runtime contexts).
Can Pydantic AI agents use tools?
Yes. Tools are Python functions decorated with @agent.tool or @agent.tool_plain. Pydantic AI automatically generates the JSON schema from the function signature and type hints, sends it to the LLM, and validates the LLM's tool call arguments before executing. This means type errors in tool calls are caught before execution, not after.