Ten minutes. One terminal. One API key. That’s what it takes to have a type safe AI agent running on Pydantic AI v1.104.0 – one that hands back a typed Python object instead of a raw string, and raises a ValidationError the moment the model hallucinates a field with the wrong type. The setup is straightforward. The trap is in what you install – and when.
As of mid-2025, Pydantic AI is mid-transition. V2 (currently v2.0.0b3) is in public beta and rearchitects the whole framework around a ‘capabilities’ primitive – bundles of tools, lifecycle hooks, instructions, and model settings you pass as capabilities=[...]. Think of it as scaffolding still up on a building that’s otherwise open for business. The ground floor (v1.x) works fine. You just don’t want to accidentally walk into the construction zone.
Before You Install: Slim vs Full
The decision you make here determines your Docker image size and cold-start behavior for the life of the project. So make it consciously.
The meta-package pydantic-ai bundles every model provider in one shot – openai, vertexai, google, xai, groq, anthropic, mistral, cohere, bedrock, huggingface – plus cli, mcp, fastmcp, evals, ag-ui, retries, temporal, logfire, ui, and spec (per the official install docs). If your container only ever calls Anthropic, you’re shipping nine SDKs you’ll never import. The slim package skips all of that – you declare exactly the extras you need.
Quick reference:
| Package | Providers included | Use when |
|---|---|---|
pydantic-ai |
All of them | Local dev, tutorials, exploration |
pydantic-ai-slim[anthropic] |
Anthropic only | Production – single provider |
pydantic-ai-slim[anthropic,openai,mcp] |
Two providers + MCP | Production – multi-provider |
Install Pydantic AI v1.104.0
Pin to the 1.x line before anything else. A careless pip install -U pydantic-ai later can resolve to a v2 beta – and the v2 API is not backward compatible.
# Isolated env
python -m venv .venv
source .venv/bin/activate # Windows: .venvScriptsactivate
# Full meta-package, pinned
pip install "pydantic-ai>=1.104,=1.104,<2"
Pydantic AI requires Python 3.9+ (Pydantic docs). Python 3.12 or 3.13 is the better choice for new projects – 3.9 is approaching end-of-life and the typing ergonomics are noticeably better in recent releases.
Watch out: the a2a optional extra is deprecated as of v1.x and will be removed in v2. The official guidance (per ai.pydantic.dev/install) is to install fasta2a[pydantic-ai]>=0.6.1 directly and import from fasta2a.pydantic_ai instead. Wire new code to the replacement path – not the one that disappears in the next major release.
Using uv? The command is uv add "pydantic-ai-slim[anthropic]>=1.104,<2". Pydantic AI’s own monorepo uses uv for workspace dependency management, so resolution is clean.
Configuration
No config file. Two environment variables, one model identifier in code.
export ANTHROPIC_API_KEY="sk-ant-..."
export LOGFIRE_TOKEN="..." # only if you installed [logfire]
Model identifiers follow the format provider:model. The official README uses anthropic:claude-sonnet-4-6 as its example; OpenAI would be openai:gpt-4o; local Ollama is ollama:llama3.1. The full provider list – OpenAI, Anthropic, Gemini, DeepSeek, Grok, Cohere, Mistral, Ollama, Bedrock, and others – is in the GitHub README.
Smoke Test: Type Safety Actually Firing
Version check first:
python -c "import pydantic_ai; print(pydantic_ai.__version__)"
# Expected: 1.104.0
Now the real test – not just a print, but proof that validation fires. If the LLM returns malformed JSON, Pydantic raises before your code sees garbage:
from pydantic import BaseModel
from pydantic_ai import Agent
class CityFact(BaseModel):
city: str
country: str
population: int
agent = Agent(
'anthropic:claude-sonnet-4-6',
output_type=CityFact,
instructions='Return one real city. Population must be an integer.',
)
result = agent.run_sync('Tell me about Krakow.')
print(result.output)
print(type(result.output)) # <class '__main__.CityFact'>
Two parameters will trip you if this came from an older blog post. As of v1.0.0 (per the upgrade guide, issues #2441 and #2443): result_type, result_tool_name, result_tool_description, and result_retries were removed from the Agent class – the replacements are output_type and output_retries. The .data property on FinalResult is gone too – it’s .output now. Pre-v1 tutorials won’t warn you. They’ll just raise an AttributeError.
Errors You’ll Actually Hit
AttributeError: 'Agent' object has no attribute 'result_type' – pre-v1.0 tutorial. Rename: result_type → output_type, result_retries → output_retries, .data → .output.
ModuleNotFoundError: No module named 'anthropic' after installing slim – you forgot the extra group. Reinstall as pydantic-ai-slim[anthropic].
ValidationError on every run – the model isn’t returning JSON that matches your schema. Tighten instructions=; for stubborn models, pass output_retries=2 so Pydantic AI feeds the validation error back to the LLM and retries.
Surprise V2 beta install – happens if you ran pip install pydantic-ai without a version pin and pip resolved to 2.0.0b3. Rerun with the pinned <2 constraint.
Noticeable cold-start penalty in containerized deploys – that’s the meta-package importing every SDK at startup. Switch to slim + one explicit extra. Import time drops substantially (the exact gain depends on your runtime, but you’re eliminating nine SDK imports).
Actually, here’s a question worth sitting with: what happens when a local model just can’t reliably produce JSON that matches a strict schema? You can increase output_retries, soften your schema, or rewrite instructions – but there’s a floor below which no amount of retrying fixes a fundamentally underpowered model. Knowing where that floor is for your specific schema is something you only learn by running it.
Upgrading and Uninstalling
Within 1.x, safe:
pip install -U "pydantic-ai>=1.104,<2"
Crossing to V2 is not a drop-in upgrade. The capabilities-first redesign requires code changes – review the official changelog before flipping the major version. Not the morning of a deploy.
Full uninstall:
pip uninstall -y pydantic-ai pydantic-ai-slim pydantic-graph
pip uninstall -y pydantic-ai-examples # if installed
# Provider SDKs from the meta-package:
pip uninstall -y anthropic openai google-generativeai cohere mistralai groq
Don’t uninstall pydantic itself – it’s a transitive dependency of too many other things.
What to Build Next
Three options for the next hour: attach an @agent.tool function so your agent can call a real API; add Logfire tracing to see token costs per run; or stress-test output_retries by feeding it a deliberately ambiguous prompt and watching the validation feedback loop. The structured output pattern is the point – once you trust it, you stop writing defensive parsing code in every downstream function.
FAQ
Should I install pydantic-ai or pydantic-ai-slim?
Slim. Always in production. The meta-package is for tutorials and local exploration – it bundles every provider SDK whether you use them or not.
Can I run Pydantic AI fully offline with a local model?
Yes. Install pydantic-ai-slim without any cloud-provider extras, run Ollama locally, and point your Agent at ollama:<model-name>. No API key. The catch: smaller local models are noticeably worse at producing JSON that matches strict Pydantic schemas. Plan to set output_retries=2 or 3, and expect to spend more time tuning your instructions field than you would with Claude or GPT-4o. Whether that trade-off makes sense depends entirely on your data-privacy constraints and tolerance for occasional validation failures.
Is V2 production ready yet?
No – and ‘beta’ here doesn’t mean ‘almost done.’ As of mid-2025, v2.0.0b3 is the latest release, and the capabilities-first redesign represents a meaningful API break from v1.x. Read it for conceptual orientation. Don’t ship it. Pin <2 and check the changelog before you decide to migrate.