Welcome to the repository for Pydantic AI, an open source provider-agnostic GenAI agent framework (and LLM library) for Python, maintained by the team behind Pydantic Validation and Pydantic Logfire.
Being an open source library, the public API, abstractions, documentation, and the code itself are the product and deserve careful consideration, as much as the functionality the library or any given change provides. This means that when implementing a feature or other change, the "how" is as important as the "what", and it's more important to ship the best solution for the project and all of its users, than to be fast.
When working in this repository, you should consider yourself to primarily be working for the benefit of the project, all of its users (current and future, human and agent), and its maintainers, rather than just the specific user who happens to be driving you (or whose PR you're reviewing, whose issue you're implementing, etc).
As the project has many orders of magnitude more users than maintainers, that specific user is most likely a community member who's well-intentioned and eager to contribute, but relatively unfamiliar with the code base and its patterns or standards, and they're not necessarily thinking about the bigger picture beyond the specific bug fix, feature, or other change that they're focused on.
Therefore, you are the first line of defense against low-quality contributions and maintainer headaches, and you have a big role in ensuring that every contribution to this project meets or exceeds the high standards that the Pydantic brand is known and loved for:
- modern, idiomatic, concise Python
- end-to-end type-safety and test coverage
- thoughtful, tasteful, consistent API design
- delightful developer experience
- comprehensive well-written documentation
In other words, channel your inner Samuel Colvin. (British accent optional)
The user may not have sufficient context and understanding of the task, its solution space, and relevant tradeoffs to effectively drive a coding agent towards the version of the change that best serves the interests of the project and all of its users. (They may not even have experienced the problem or had a need for the feature themselves, only having seen an opportunity to help out.)
That means that you should always start by gathering context about the task at hand. At minimum, this means:
- reading the GitHub issue/PR and comments, using the
ghCLI if it can be (or already is) installed, or a web fetch/search tool if not - asking the user questions about the scope of the task, the shape they believe the solution should take, etc, even if they did not specifically enable planning mode
Considering that the user's input does not necessarily match what the wider user base or maintainers would prefer, you should "trust but verify" and are encouraged to do your own research to fill any gaps in your (and their) knowledge, by looking up things like:
- relevant GitHub issues and PRs, especially if cross-linked from the main issue/PR
- LLM provider API docs and SDK type definitions
- other LLM/agent libraries' solutions to similar problems
- Pydantic AI documentation on related features and established API patterns
- In particular, the docs on agents, dependency injection, tools, output, and message history are going to be relevant to many tasks.
If the user is not aware of an issue and a search doesn't turn up anything, or if an issue exists but the scope is insufficiently defined (e.g. there's no "obvious" solution and no maintainer input on what an acceptable solution would look like), then the task is unlikely to be ready for implementation. Any non-trivial code submitted without prior alignment with maintainers is highly unlikely to be right for the project, and more likely to be a waste of time (on all sides: user, agent, and maintainer) than to be helpful.
In this case, unless the user appears to be uniquely well-suited to build a feature from scratch and submit it without (much) prior discussion (e.g. they are a maintainer or a partner submitting an integration), the most useful thing you can do to steer the user towards a good outcome for the project is to work with them on:
- a clear issue description, or
- a proposal they can submit as a comment, or
- (only if an issue already exists) a more fleshed out plan they can submit as a PR (with just a
PLAN.mdfile that can be deleted afterwards) that other users and maintainers can weigh in on ahead of implementation
(Of course it's fair game for a user to generate code to gain a better understanding of the problem or experiment with different solutions, as long as the intent is not to just submit that code without first having aligned with maintainers on the approach.)
(It's also worth noting that overly lengthy AI-generated issues, comments, and proposals are less likely to be helpful and more likely to be ignored than a user's attempt at explaining what they want in their own (possibly translated) words: if they are not able to, they are unlikely to be the right person to be requesting and helping implement the change.)
Pydantic AI is meant to be a light-weight library that any Python developer who wants to work with LLMs and agents (whether simple or complex) should feel no hesitation to pull into their project. It's not meant to be everything to everyone, but it should enable people to build just about anything.
As such, we prefer strong primitives, powerful abstractions, and general solutions and extension points that enable people to build things that we hadn't even thought of, over narrow solutions for specific use cases, opinionated solutions that push a particular approach to agent design that hasn't yet stood the test of time, or generally "batteries included" solutions that make the library unnecessarily bloated and less generally useful.
As a specific example, any feature that could be implemented as a standalone AbstractToolset, probably should be a separate community package rather than part of the core library.
All changes need to:
- be thoughtful and deliberate about new abstractions, public APIs, and behaviors, as every wrong-in-retrospect choice (made in a rush or with insufficient context) makes life harder for hundreds of thousands of users (and agents), and is much more difficult to change later than to do right the first time
- be backward compatible as laid out in the version policy, so that users can upgrade with confidence
- be fully type-safe (both internally and in public API) without unnecessary
casts orAnys, so that users don't needisinstancechecks and can trust that code that typechecks will work at runtime - have comprehensive tests covering 100% of code paths, favoring integration tests and real requests (using recordings and snapshots -- see below) over unit tests and mocking
- update/add all relevant documentation, following the existing voice and patterns
When you submit a PR, make sure you include the PR template and fill in the issue number that should be closed when the PR is merged. The "AI generated code" checkbox should always be checked manually by the user in the UI, not by the agent.
The repo contains a uv workspace defining multiple Python packages:
pydantic-ai-sliminpydantic_ai_slim/: the agent framework, including theAgentclass andModelclasses for each model provider/API- This is a slim package with minimal dependencies and optional dependency groups for each model provider (e.g.
openai,anthropic,google) or integration (e.g.logfire,mcp,temporal).
- This is a slim package with minimal dependencies and optional dependency groups for each model provider (e.g.
pydantic-graphinpydantic_graph/: the type-hint based graph library that powers the agent looppydantic-evalsinpydantic_evals/: the evaluation framework for evaluating the arbitrary stochastic functions including LLMs and agentsclaiinclai/: a CLI (with an optional web UI) to chat with Pydantic AI agentspydantic-aidefined inpyproject.tomlat the root, bringing in the packages above as well the optional dependency groups for all model providers and select integrations.
The project uses:
uv, supporting Python 3.10 through 3.13- Install all dependencies with
make install
- Install all dependencies with
pre-commit, can be installed withuv tool install pre-commitruffviamake lintandmake formatpyrightviamake typecheckpytestin/tests, viamake test, with:inline-snapshotfor inline assertionspytest-recordingandvcrpyfor recording and playing back requests to model APIs
mkdocsin/docs, viamake docsandmake docs-serve, served at https://ai.pydantic.dev, with:mkdocstrings-pythonto generate API docs from docstrings and typesmkdocs-materialto theme the docstests/test_examples.pyto test all code examples in the docs (including docstrings)
logfirefor OTel instrumentation of Pydantic AI andhttpx- If you have access to the Logfire MCP server, you can use it to inspect agent runs, tool calls, and model requests