Skip to content

Type Safe AI Agent with Pydantic AI v1.104 Install Guide

Install Pydantic AI v1.104.0 and run your first type safe AI agent in under 10 minutes - with the slim vs full trade-offs nobody explains.

7 min readIntermediate

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_typeoutput_type, result_retriesoutput_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.