Model or dataset
pydantic/pydantic-ai avatar
pydantic/pydantic-ai

Pydantic AI: a typed agent loop for Python, from extraction to a terminal coder

AI Agent Framework, the Pydantic way. Yet despite virtually every Python agent framework and LLM library using Pydantic Validation, when we began to use LLMs in Pydantic Logfire, we couldn't find anything that gave us the same feeling.

20,174 stars2,784 forksPythonMIT

At a glance

What is it?
Pydantic AI wraps model calls in Pydantic validation so every run returns a typed object. It installs with uv, swaps models by string, and ships a separate Harness package for long-running agent work.
Who is it for?
Adopt Pydantic AI if your agent's output has to be a validated Python object and you want one agent to run in a terminal, a web backend, or a voice session without rewriting the loop. Skip it if you need a visual graph editor or non-Python runtimes; the repository is Python-only and requires 3.10 or newer.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem Pydantic AI solves: LLM output that your type checker can see

Most Python LLM code ends in a string that gets parsed by hand. The README states the motivation directly: the team was building LLM features into Pydantic Logfire and "couldn't find anything that gave us the same feeling" as Pydantic Validation. Pydantic AI is the answer to that gap. You declare an output type, and the framework guarantees the run returns it.

The README's extraction example makes the contract explicit. A `Sentiment` model with a `Literal` label and a `score` constrained to the range -1 to 1 becomes the agent's output type. The prose around the example says the rest of a tool function's signature and its docstring become the tool schema, arguments are validated before your code runs, and the run is guaranteed to return a `Sentiment`, so the IDE, the type checker and the model all agree on the returned type.

That is a narrower promise than "build any agent." It is aimed at Python developers who already use Pydantic models for API payloads and want the same discipline applied to what a model hands back. If your agent's result is a blob of prose you show to a human, the typed output buys you less.

How the agent loop and capabilities fit together

An `Agent` is constructed with a model string such as `'openai:gpt-5.6-sol'` or `'anthropic:claude-fable-5'`. The README describes this as "every model a string swap away," and the project separates the model layer from the loop so the same agent object can be pointed at a different provider by changing that string.

Tools attach in two ways. The `@agent.tool` decorator is for functions that need the run context, and the README shows a `RunContext[None]` parameter carrying dependencies into the function. `@agent.tool_plain` is for functions that do not need it, as in the voice example where `order_status` takes only an `order_id`. The docstring becomes part of the schema, which is why the README's examples all carry short docstrings.

Capabilities are the extension point. The README calls `Coder` a "regular combined capability, not a black box" and shows that the bundled version and the explicit list are equivalent: `FileSystem('.')`, `Shell(cwd='.')`, `RepoContext()`, `Planning()`, `SubAgents(...)`, `ClearToolResults()`, `WarnNearLimits()`, `ToolOutputLimits()`. That equivalence is the design claim worth checking against your own use case. If you need different shell permissions or a different filesystem root, you take the blocks instead of the bundle.

The same agent object also runs in more than one place. The README lists a web frontend, the terminal, a voice call, a durable background queue, and a plain `run()` call as the interfaces, with image generation and embeddings in the same package.

Installing Pydantic AI and running a first typed extraction

The README's install command for the core package is `uv add pydantic-ai`. The project also publishes `pydantic-ai` on PyPI, and the repository lists a `pydantic_ai_slim` directory alongside `pydantic_evals` and `pydantic_graph`, so the installable package and the source tree are not one and the same.

Start with the extraction example, because it exercises the typed-output path with the least setup. Create a file with the model, the agent, one tool, and a synchronous run.

python
from typing import Literal

from pydantic import BaseModel, Field

from pydantic_ai import Agent, RunContext

class Sentiment(BaseModel):
    label: Literal['positive', 'negative', 'neutral']
    score: float = Field(ge=-1, le=1)

agent = Agent('openai:gpt-5.6-sol', output_type=Sentiment)

@agent.tool
def recent_reviews(ctx: RunContext[None], product: str) -> list[str]:
    """Fetch recent review snippets for a product."""
    return ['The new release fixed everything I complained about!']

result = agent.run_sync('How are people feeling about the Extract app?')
print(result.output)

What you should see is a `Sentiment` instance rather than a string, with `label` restricted to the three literals and `score` inside the allowed range. The tool's `product` argument is validated before the function body executes, so a malformed argument surfaces as a validation error rather than a silent call.

If you would rather try the bundled coding agent before writing code, the README gives a one-liner that runs the exported `coder_agent` through the Pydantic AI CLI. It uses `uvx`, so nothing is added to your project environment.

bash
uvx --with pydantic-ai-harness clai -a pydantic_ai_harness.coder:coder_agent -m anthropic:claude-fable-5

The `-a` flag names the agent by module path and `-m` selects the model. The README says you then chat with the agent in your terminal. Note that this pulls `pydantic-ai-harness`, a separate package from `pydantic-ai` itself.

Where Pydantic AI is the wrong tool

The typed-output guarantee is only as strong as the model's ability to satisfy the schema. A constrained `float` and a three-value `Literal` are easy. A deeply nested output type with many optional branches gives the model more room to fail validation, and the README does not describe a retry or repair policy for that case. Treat schema complexity as a cost you are choosing.

The repository is Python-only, with `requires-python = ">=3.10"` in `pyproject.toml` and classifiers through Python 3.14. If your services are in TypeScript, Go or Java, nothing here helps you directly. If you need a visual graph editor where non-engineers wire nodes together, this is not that kind of framework; the agent is a Python object you construct in code.

There is also a packaging split that will bite people who install casually. The core package is `pydantic-ai`, the long-running agent features live in `pydantic-ai-harness`, and the Makefile installs that harness out-of-band with an explicit pin: `uv pip install --no-deps "pydantic-ai-harness==0.7.0"`. The comment in the Makefile explains why: the harness is kept out of the lock because its `pydantic-ai-slim` dependency collides with the workspace member under lowest-direct resolution. That is a development-time detail, but it tells you the two packages version independently and you should pin both.

Pydantic AI compared with LangGraph and LangChain

The comparison people search for is Pydantic AI against LangGraph. The honest difference visible in the README and repository is where the structure lives. Pydantic AI puts the contract in Python types: an `Agent` with an `output_type`, tools declared as decorated functions, and capabilities composed as a list. The README's framing is that the agent is "a plain object you call `run()` on," and that the same object runs across a web frontend, a terminal, a voice call, or a durable queue.

LangGraph's approach, as its name suggests, is to model the agent as a graph of nodes and edges. That is a different centre of gravity: the topology is the artifact, and you inspect and modify it as a graph. Pydantic AI has no such topology object in the documented API. Its composition story is the capability list, and the README is explicit that the combined capability and its constituent blocks are equivalent.

Against LangChain, the distinction is scope rather than shape. Pydantic AI is a single agent loop with typed outputs, model swapping, and a capability system, plus a separate Harness package for memory, sub-agents, context management and a coding agent. It is not a catalogue of retrievers, document loaders and chain abstractions. If your problem is mostly retrieval plumbing, you are looking at the wrong project; if your problem is getting a validated object out of a model call, the typed loop is the closer fit.

Maintenance, releases and the MIT licence

The repository is not archived, and the last push was on 2026-08-29. Releases are frequent and closely spaced: v2.36.0 on 2026-08-29, v2.35.3 on 2026-08-28, v2.35.1 on 2026-08-27. For a team deciding whether to build on it, that cadence cuts both ways. Fixes arrive quickly, and so do version bumps you may need to track.

Versioning is dynamic. `pyproject.toml` sets `source = "uv-dynamic-versioning"` with `vcs = "git"` and `style = "pep440"`, so the version is derived from git tags at build time rather than written into the file. If you build from a source checkout rather than installing the published wheel, the version you get depends on the tags present in your clone.

The licence is MIT, declared both in `pyproject.toml` (`license = "MIT"`) and via `license-files = ["LICENSE"]`. MIT is permissive and imposes no copyleft obligation on your own code. That is a factual statement about the licence identifier, not legal advice; if your organisation has rules about dependency licences, run it past whoever handles that.

The upgrade cost to budget for is the extras. The README shows optional installs such as `uv add "pydantic-ai[openai-realtime]"` for voice, and the Makefile deliberately excludes the `mcp-tasks` extra from its sync commands. Extras are where the surface area lives, and each one is a version you are tracking.

Editorial conclusion

Adopt Pydantic AI if your agent's output has to be a validated Python object and you want one agent to run in a terminal, a web backend, or a voice session without rewriting the loop. Skip it if you need a visual graph editor or non-Python runtimes; the repository is Python-only and requires 3.10 or newer. Before committing, verify that your chosen model string is supported, that the extras you need (for example openai-realtime) are published for your version, and that the Harness version pinned in the Makefile matches the one you install.

Frequently asked questions

What is Pydantic AI used for?

It is a Python agent framework for building agents whose runs return validated, typed objects. The README covers data extraction, realtime voice, image generation, embeddings, and a terminal coding agent, all from the same agent loop.

Is Pydantic AI better than LangGraph?

They structure agents differently rather than ranking on a single scale. Pydantic AI puts the contract in Python types and composes behaviour through a capability list, while LangGraph models the agent as a graph of nodes and edges. Pick based on whether you want the topology or the types to be the artifact you inspect.

Is Pydantic AI free to use?

The repository is licensed under MIT, declared in pyproject.toml with license = "MIT" and a LICENSE file. That covers the framework itself; any model provider you point it at has its own terms and pricing.

How do you install Pydantic AI?

The README gives `uv add pydantic-ai` for the core package, and extras such as `uv add "pydantic-ai[openai-realtime]"` for voice. The long-running agent features come from the separate `pydantic-ai-harness` package.

What is Pydantic AI slim?

The repository has a top-level `pydantic_ai_slim` directory, and the Makefile comment refers to its `pydantic-ai-slim` dependency colliding with the workspace member under lowest-direct resolution. That is the extent of what the README and repository files state about it.

What is RunContext in Pydantic AI?

RunContext is the parameter type that carries your dependencies into a tool function. The README's extraction example uses `RunContext[None]` on the `recent_reviews` tool, while tools that need no context use `@agent.tool_plain` instead.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/pydantic-pydantic-ai.svg)](https://hysenlabs.com/projects/pydantic-pydantic-ai)