Pydantic AI: Typed Python Agents for Production

What Pydantic AI gives Python builders: typed tools, validated outputs, provider choice and clear rules for choosing an agent framework.

Published

Pydantic AI: Typed Python Agents for Production

Choose Pydantic AI when your Python feature needs an agent to call application functions and return a validated object. Its 3 structured-output modes make the data boundary explicit; they do not prove the answer is true. Prefer a direct model call for simple extraction, and consider LangGraph when the surrounding business process is the harder problem.

Verified against the maker's documentation and repository license on 17 October 2026. The decision below turns on output validation, access to application services, workflow ownership and recovery, rather than a performance ranking.

What Is Pydantic AI?

Pydantic AI is the Python agent SDK from the Pydantic team. It combines a model, instructions, callable Python functions and an optional output type into an Agent, the object your application runs. A model is the system that generates responses; the SDK manages the interaction around it. The current overview describes a broader SDK, but this is the core you need for a product feature.

Think of it as giving an unpredictable collaborator a function contract. Your application supplies context and permitted operations, then requires a result with named fields. That is useful when a support feature must produce a category and next step that ordinary Python code can consume.

Pydantic AI documentation showing its Python SDK and agent examples
Pydantic AI

Pydantic AI Agents: The Reusable Unit

An Agent holds the configuration for a job. A run is a particular attempt to do that job with a prompt and runtime dependencies. You can call run_sync() from a synchronous script or await agent.run() from asynchronous application code; the completed result exposes its final value through .output. These are documented Agent APIs.

The typing has two distinct jobs. Static typing helps your editor or type checker catch mismatches in your Python code. Runtime output validation checks the data returned by the model against the declared schema. Neither makes an ambiguous support request unambiguous.

Pydantic AI Tools: Functions With Application Context

Function tools let the model request something your code can do, such as looking up a subscription. Register a context-aware function with @agent.tool, or use @agent.tool_plain when it needs no run context. Type hints describe the arguments, and docstrings help describe the tool to the model. The function-tools documentation explains how these become tool schemas.

Dependency injection means passing the services a run needs into that run. With deps_type=CustomerContext, you declare the expected Python type; with deps=customer_context, you pass the actual instance. A tool receives RunContext[CustomerContext] and reads it through ctx.deps. That context can carry an authenticated customer, a database connection or an API client. The dependency guide explicitly notes that deps_type supports type checking rather than runtime validation of the dependency object.

For a SaaS builder, the payoff is concrete: the server can choose the customer's account before the model requests a lookup. Keep authorization in the lookup code. Passing a database client through a typed context does not restrict which rows that client can read.

Architectural cutaway connecting the agent to its model, Python tools, runtime dependencies and output boundary
Dependencies supply your Python code; the agent coordinates model and tool calls before returning its final output.

Pydantic AI Structured Output: What Gets Validated

output_type defines the result your application expects to receive. Supply a Pydantic BaseModel, a Python class with typed fields, and Pydantic AI derives a schema and validates the generated data. The output documentation also supports other types, including dataclasses, lists and unions.

The three output modes change how the model is asked to produce that data:

ModeHow the result arrivesWhat to check
Tool Output, the defaultThe model calls a special output tool with structured argumentsThe selected model supports the required tool behavior
Native OutputThe provider constrains the response using a JSON schemaThe model and API support that schema and combination of features
Prompted OutputInstructions describe the schema, then the response is parsed and validatedThe model can follow the format; failures still need handling

These are the SDK's three documented output modes, not three accuracy levels. Choose the mechanism your model supports, then evaluate the result on your task.

A validation failure can be sent back to the model for another attempt. Retry budgets are bounded, and exhausted output retries can raise UnexpectedModelBehavior. Your application needs a failure path, such as asking for missing information or handing the request to a person. See the retry behavior.

Pydantic AI Tutorial: Return a Validated Support Decision

Start with a read-only decision object before giving the agent permission to change anything. This example adapts the documented Agent, RunContext and output_type patterns into a small support-triage task.

The current installation guide requires Python 3.11 or later. In a virtual environment, install the library:

Bash
python -m pip install pydantic-ai

Set OPENAI_API_KEY in your environment for an account with access to the model. Save the following as triage.py and run python triage.py. The model identifier follows the current Agent documentation; you can replace it with a supported model available to your account.

Python
from dataclasses import dataclass
from typing import Literal

from pydantic import BaseModel
from pydantic_ai import Agent, RunContext

@dataclass
class Customer:
    plan: str

class Triage(BaseModel):
    category: Literal['billing', 'technical']
    priority: Literal['normal', 'urgent']
    summary: str

agent = Agent(
    'openai:gpt-6.1-sol',
    deps_type=Customer,
    output_type=Triage,
    instructions=(
        'Triage the support message. Use customer_plan for context. '
        'Summarize the issue without inventing account facts.'
    ),
)

@agent.tool
def customer_plan(ctx: RunContext[Customer]) -> str:
    """Return the authenticated customer's plan."""
    return ctx.deps.plan

if __name__ == '__main__':
    result = agent.run_sync(
        'I was charged twice for my subscription.',
        deps=Customer(plan='business'),
    )
    print(result.output.model_dump())

On a successful run, result.output is a Triage object. Its category and priority must satisfy the declared choices, and model_dump() converts that object to a dictionary. The example's context tool, typed result and rejection of an invalid category were checked offline with TestModel. Model-generated wording and triage accuracy still need evaluation on your own cases.

The customer context is illustrative. In a product, construct it from the authenticated request and your account records. Also define what makes a case urgent: the schema lists valid labels but contains no urgency policy. That missing business rule matters more than adding another agent.

Pydantic AI Models: Swapping Providers Without Assuming Parity

Pydantic AI reduces provider-specific wiring, but a model swap still changes behavior. Many routes use a <provider>:<model> identifier. Some require an explicit model or client, appropriate credentials and installation extras. Feature support depends on the chosen model and API, as the provider directory makes clear.

The directory includes OpenAI, Anthropic, Google/Gemini, AWS Bedrock, Groq, Mistral, xAI and Ollama. Its other documented routes cover:

  • Model and inference services: Alibaba Cloud/Qwen, Cerebras, Cohere, Crusoe, DeepSeek, Fireworks AI, Heroku AI, Hugging Face, Meta, Moonshot AI/Kimi, Nebius AI Studio, OVHcloud AI Endpoints, SambaNova, Snowflake Cortex, Together AI and Z.AI.
  • Cloud, gateway and self-hosted options: Google Cloud/Vertex AI, Microsoft Azure/Foundry, Pydantic AI Gateway, LiteLLM, OpenRouter, Vercel AI Gateway and vLLM.
  • Additional access and decision-model routes: GitHub Copilot, OpenAI Codex, OpenAI Decisions API, System One API and TypeSafe (Jev).

These names describe different ways to reach models, not interchangeable feature sets. A local model can have different tool behavior from a hosted frontier model; a compatible API can still impose different schema restrictions.

For a founder, portability buys an exit path and room to experiment. For the builder implementing it, the acceptance test stays the same: does the replacement select the right tools, respect the output schema and produce acceptable decisions on the same cases? Keep that evidence before changing the production default.

MCP and Durable Execution: Connect Tools, Preserve Progress

MCP connects an agent to tool servers; durable execution helps a run survive interruption. They solve different problems.

Model Context Protocol, or MCP, standardizes how applications expose tools and context to AI clients. Pydantic AI's MCP capability accepts server URLs and client or toolset inputs, with provider-native MCP options where supported. It lets you reuse a tool server instead of writing a new integration for each agent. It does not decide which customer should be allowed to use that server's operations.

Durable execution means preserving progress so work can continue after a failure, restart or long wait. The current durability documentation names 9 solutions:

  • Co-maintained with the vendor teams: Temporal, DBOS, Prefect, Restate and AWS Lambda.
  • External SDK integrations: Kitaru, Apache Airflow, Absurd and pgtask.

There is also a backend builder for other engines. Choose a documented integration when an agent must outlive the request or process that started it. The existence of these integrations does not make a bare Agent invocation a durable deployment.

A library timeline shows saved progress bypassing an interruption to resume work
A durable engine preserves progress across an interruption. External writes still need a strategy for safe retries.

Consider a support job that prepares a refund recommendation, waits for approval, then applies it. A saved run can preserve the waiting work, but the payment operation still needs idempotency: repeating the request should not create another refund. Decide how to identify an operation that already happened, and how to reconcile an uncertain outcome. That is an application responsibility alongside the engine.

Pydantic AI Evals: Check the Decision Behind the Object

Pydantic Evals tests whether the agent did an acceptable job, beyond whether its output can be parsed. It is a separate, code-first evaluation package that does not require Pydantic AI. You define cases and evaluators, run the task against them, and inspect a report; the documentation covers grading both final outputs and tool-call trajectories, the sequence of actions taken during a run.

Pydantic Evals documentation describing cases, evaluators and experiment reports
Pydantic Evals

For the triage example, build cases for duplicate billing, a failed login, missing account context and a message that asks the assistant to ignore its instructions. Check the category, the escalation decision and whether the required account lookup occurred. Include cases where the acceptable answer is to ask a question.

For an operator, a trace explains one run; an evaluation measures behavior across cases. Pydantic AI uses OpenTelemetry, a standard for application telemetry, and supports other observability backends through its instrumentation. Inspect the model request and tool calls when a case fails, then keep that case in the evaluation set.

Optional Pydantic Logfire provides agent/model/tool tracing; its Personal plan is free and Team starts at $49/month, with additional usage and seats billed separately, according to its pricing page.

When to Pick Pydantic AI Over Another Framework

Choose the abstraction that matches the difficult part of your feature. A Python builder with existing domain models and services should shortlist Pydantic AI when typed inputs, tools and outputs are the main integration problem. A technical founder should ask which choice leaves the smallest operational system the business can explain and maintain.

Pydantic AI vs LangGraph

LangGraph is the stronger starting point when you want to design the surrounding workflow explicitly. Its documentation centers on long-running stateful agents, durable execution and human intervention. Think of an application with mandatory stages: collect evidence, obtain approval, execute an authorized action and reconcile the outcome.

LangGraph documentation describing its stateful agent workflow runtime
LangGraph

Pydantic AI is attractive when a typed agent is a component inside a process your application already controls. It can also participate in durable workflows, so persistence alone does not settle the choice. The deciding question is whether you want to model the business process around the agent or primarily configure the agent's own behavior. LangGraph's wall is the workflow design and state you must own; Pydantic AI's wall is that its convenient agent contract does not design the whole process for you.

Pydantic AI vs LangChain

LangChain makes sense when its existing model/tool integrations and agent architecture already fit your application. LangChain agents are built on LangGraph, according to the LangChain overview, so choosing its higher-level agent API does not discard that runtime foundation.

LangChain documentation showing its agent creation interface
LangChain

Pick Pydantic AI for a Python service where its dependency and output contracts fit how you already write code. Keep a working LangChain feature unless you can name a concrete source of complexity that a migration removes. LangChain's abstraction still needs to be understood when behavior crosses agent and workflow layers; changing libraries merely relocates that work. The deeper relationship belongs in LangChain vs LangGraph.

OpenAI Agents SDK or Plain API Calls

OpenAI Agents SDK fits an application-owned agent loop with tools, handoffs and tracing. The SDK runs in your application, and it supports structured outputs; its provider interfaces also accommodate non-OpenAI models. It is not accurate to treat typed output or provider choice as exclusive to Pydantic AI.

OpenAI documentation for its application-owned Agents SDK
OpenAI Agents SDK

Choose that SDK when its agent and handoff model matches the surrounding OpenAI integration you intend to maintain. Choose Pydantic AI when its Python dependency model and provider configuration are the better fit. Both leave deployment, tool authorization and application correctness with you.

Use plain API calls when the job is a model request with a small amount of deterministic code around it. Direct APIs can already return schema-constrained outputs. A receipt extractor does not need an agent framework solely because the result is a Pydantic object. The wall arrives when you are repeatedly rebuilding tool loops, validation retries and instrumentation across features.

For the broader selection, use the existing AI agent frameworks guide. If the unresolved question is explicit workflow control versus specialist agent roles, continue with LangGraph vs CrewAI.

What's Overhyped About Typed Agents

The overstatement is that a typed agent is automatically a correct production system. There are several boundaries the library cannot erase:

  • Type safety is not factual accuracy. A well-formed answer can misread the user's request. Decide what to verify against authoritative records.
  • Model portability is not quality parity. A new provider configuration needs the same task evaluation as a new prompt.
  • Durability is not automatic deployment. Select and operate the engine, storage and recovery path your feature needs.
  • A retry is additional work. Another model request adds latency and usage. Give exhausted retries an explicit application outcome.

Act now if your next Python feature already needs tools and structured decisions. Wait on a framework migration if the existing system works and the proposed benefit is only cleaner-looking demo code. You are largely unaffected if the feature is a straightforward extraction call with adequate validation and error handling.

Pydantic AI FAQ

What is the difference between Pydantic and Pydantic AI?

Pydantic is the Python data-validation library. Pydantic AI is the agent SDK that coordinates model calls and tools, using Pydantic to validate structured data. Installing Pydantic alone does not give you that agent loop.

How does Pydantic AI differ from LangChain?

Pydantic AI emphasizes a typed Python agent interface with runtime dependencies and validated outputs. LangChain provides an agent architecture and integrations built on LangGraph. Choose by how the interface fits your application, rather than assuming either framework guarantees better model answers.

Is Pydantic AI free to use?

Yes. The library uses the MIT license; model-provider usage is the inference bill, with hosting and optional services separate. The license permits commercial use and requires preserving its copyright and permission notice when distributing copies or substantial portions.

Which models does Pydantic AI support?

Its provider directory covers OpenAI, Anthropic, Google, AWS Bedrock, Groq, Mistral, xAI, Ollama and the additional cloud, gateway and inference routes listed above. Check the specific model's tool and output-mode support before treating it as a drop-in replacement.

What to Ship Next Week

Give a small read-only feature a clear acceptance boundary before expanding its autonomy. For a support product, start with the triage object from the example and keep the final account action in ordinary application code.

  1. Write the contract and the policy

    Choose the output fields your application will consume. Define category and urgency rules, including when the agent should ask for clarification. Pass authenticated context from the server.

  2. Exercise the failure paths

    Build evaluation cases for missing data, ambiguous requests and unauthorized requests. Check the tools used as well as the final object. Decide what happens when the model or validation fails.

  3. Add the runtime your feature needs

    If work must survive a restart or wait for approval, select a durable integration and verify recovery with your own operations. Otherwise, keep the deployment small. Review traces and evaluation results before adding a write-capable tool.

For practical notes on building AI features, join the newsletter.

Published
Category
Build
Related Articles
AI Guardrails: Checks, Tools, and a Minimal Starting Set

AI Guardrails: Checks, Tools, and a Minimal Starting Set

AI guardrails explained through one customer request, with a documented tool comparison, permission boundaries, and a small-team starting set.Oct 17, 2026Build
LLM Hallucination: Causes, Examples, and How to Reduce It

LLM Hallucination: Causes, Examples, and How to Reduce It

Why LLMs invent facts, numbers, citations, and tool arguments, plus the grounding, checks, and evals that catch errors before customers see them.Oct 17, 2026Build
System Prompt: What It Is, Examples and a Template

System Prompt: What It Is, Examples and a Template

Learn what a system prompt does, how Anthropic, OpenAI and Gemini name it, and what belongs in it. Includes examples and a copyable template.Oct 17, 2026Build
Function Calling Explained: How LLMs Use Your Tools

Function Calling Explained: How LLMs Use Your Tools

Learn function calling with a complete tool schema, call and result. Compare OpenAI, Anthropic and Gemini, and know when structured outputs are enough.Oct 17, 2026Build
MCP vs API: When to Ship One or Both

MCP vs API: When to Ship One or Both

MCP vs API: compare discovery, auth, versioning and deployment, follow the same action through both, and decide what your product should ship.Oct 17, 2026Build
Hermes Agent Review

Hermes Agent Review

Should you install Hermes Agent for business work? A practical review of memory, skills, models, setup and the limits that matter.Oct 17, 2026Build
Ollama vs llama.cpp

Ollama vs llama.cpp

Choose Ollama for easier model operations or llama.cpp for direct serving control. Compare GGUF, APIs, concurrency and GPU support.Oct 16, 2026Build
Devin Desktop

Devin Desktop

Devin Desktop reviewed: Agent Command Center, Spaces, Devin Local, Windsurf migration, current plans, and when to choose Cursor or Claude Code.Oct 16, 2026Build
Newsletter

One letter, every Sunday.Working systems, not hot takes.

Weekly. No spam. Unsubscribe anytime.