Key Features
- Type safety — Full IDE auto-completion and static type checking for agents, tools, and outputs
- Model-agnostic — OpenAI, Anthropic, Gemini, DeepSeek, Grok, Ollama, and custom models
- Structured outputs — Define output schemas with Pydantic models, validated automatically
- Dependency injection — Clean separation of business logic and AI configuration
- MCP support — Native Model Context Protocol integration
- Streaming — Continuous structured output with immediate validation
- Human-in-the-loop — Flag tool calls for approval before execution
- Observability — Built-in Pydantic Logfire integration for debugging and cost tracking
Example: Bank Support Agent
from dataclasses import dataclass
from pydantic import BaseModel, Field
from pydantic_ai import Agent, RunContext
@dataclass
class SupportDeps:
customer_id: int
db: DatabaseConn
class SupportOutput(BaseModel):
support_advice: str = Field(description='Advice for the customer')
block_card: bool = Field(description='Whether to block the card')
risk: int = Field(description='Risk level 0-10', ge=0, le=10)
support_agent = Agent(
'openai:gpt-4o',
deps_type=SupportDeps,
output_type=SupportOutput,
instructions='You are a bank support agent.',
)
@support_agent.tool
async def customer_balance(
ctx: RunContext[SupportDeps], include_pending: bool
) -> float:
return await ctx.deps.db.customer_balance(
id=ctx.deps.customer_id,
include_pending=include_pending,
)
With Thinking & Web Search
from pydantic_ai.capabilities import Thinking, WebSearch
agent = Agent(
'anthropic:claude-sonnet-4-6',
capabilities=[Thinking(), WebSearch()],
)
result = agent.run_sync('What was the largest meteorite found this year?')