pydantic/pydantic-ai

▲ 24 stars today★ 20,295⑂ 2,834

How Python does AI. Agents, realtime voice, image generation, embeddings. Every model, every interface, typed end to end.

About pydantic/pydantic-ai

pydantic/pydantic-ai is an open-source project on GitHub, mainly written in Python. How Python does AI. Agents, realtime voice, image generation, embeddings. Every model, every interface, typed end to end. It currently holds 20,295 stars and 2,834 forks with 0 open issues, and was last pushed on an unknown date (repository created unknown).

Project Overview

AI Homed tracks it on the Today's Trending board, currently at rank #52 with 24 new stars today.

GitHub Repository Details

Repository pydantic/pydantic-ai · default branch - · size 0 KB · watchers 0 · source: GitHub REST API and repository README

README

https://github.com/pydantic/pydantic-ai/blob/HEAD/Pydantic AI

How Python does AI

https://github.com/pydantic/pydantic-ai/blob/HEAD/CI https://github.com/pydantic/pydantic-ai/blob/HEAD/Coverage https://github.com/pydantic/pydantic-ai/blob/HEAD/PyPI https://github.com/pydantic/pydantic-ai/blob/HEAD/versions https://github.com/pydantic/pydantic-ai/blob/HEAD/license https://github.com/pydantic/pydantic-ai/blob/HEAD/Join Slack

Agents, realtime voice, image generation, embeddings. Every model, every interface, typed end to end.

---

Pydantic AI is the Python AI SDK: a typed, extensible agent loop with every model a string swap away. The same agent runs everywhere you need it: behind a web frontend, in the terminal, on a voice call, on a durable background queue, in GitHub Actions, or as a plain object you call run() on. Image generation and embeddings come in the same box; Pydantic Graph and Pydantic Evals are separate packages, for typed control flow and for testing agent behavior the way pytest tests code.

Pydantic AI Harness has everything an agent needs for complex, long-running work, snapped on as capabilities, from memory, guardrails, and sub-agents to planning, context management, and persistence, up to a complete coding agent.

Pydantic Logfire is the AI observability platform that sees your whole app, not just the LLM calls, and the Pydantic AI Gateway is one key for every model with real-time cost monitoring and budget control; the Gateway self-hosts if you would rather, and our instrumentation is plain OpenTelemetry, so any backend you already run works. Underneath both, genai-prices keeps model pricing current, and Monty is the sandboxed Python interpreter that runs model-written code.

View the complete documentation at pydantic.dev/docs/ai.

What are you building?

From simple typed data extraction to complex, long-running multi-agent collaboration, Pydantic AI and Pydantic AI Harness have got you covered.

Coding agent

A complete coding agent in your terminal: workspace-rooted file access, allowlisted shell, repo orientation, planning, and context management that survives long sessions. Here with web search and a second-opinion advisor snapped on alongside:

uv add pydantic-ai pydantic-ai-harness
from pydantic_ai import Agent
from pydantic_ai.capabilities import WebSearch
from pydantic_ai_harness import Advisor, Coder

agent = Agent( 'anthropic:claude-fable-5-1', capabilities=[ Coder(), # files, shell, repo context, sub-agents, context management WebSearch(), # look up docs and error messages on the web Advisor('openai:gpt-6-sol'), # a second opinion from another model when stuck ], ) agent.to_cli_sync()

Coder is a regular combined capability, not a black box: use it whole, or use the blocks it bundles directly; the two are equivalent:

capabilities = [
    FileSystem('.'), Shell(cwd='.'), RepoContext(), SubAgents(...),
    ClearToolResults(), WarnNearLimits(), ToolOutputLimits(), RepairToolArguments(),
]

Run the file and you're chatting with the agent in your terminal. To try it before writing any code, run the exported coder_agent with clai (the Pydantic AI CLI), via uvx:

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

Build this → Coder, from the Harness

Run it on GitHub → GitHub Agentic Workflows, on issues, pull requests or a schedule

Data extraction

Give the agent an output type and tools, and every run comes back validated and typed:

uv add pydantic-ai
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-6-sol', output_type=Sentiment)

@agent.tool def recent_reviews(ctx: RunContext, 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)

> label='positive' score=0.9

The @agent.tool function receives a RunContext that carries your dependencies in; the rest of its 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 your IDE, type checker, and the LLM all agree on the returned type.

Build this → Agents, Function Tools, and Structured Output

Durable workflow

Attach TemporalDurability and the same agent runs inside a Temporal workflow under durable execution: every model and tool call becomes a durable activity, so a run working through a background queue survives restarts, failures, and long waits:

uv add "pydantic-ai[temporal]"
from temporalio import workflow

from pydantic_ai import Agent from pydantic_ai.capabilities import WebFetch, WebSearch from pydantic_ai.durable_exec.temporal import PydanticAIWorkflow, TemporalDurability

agent = Agent( 'openai:gpt-6-sol', instructions='Research the topic and write a structured brief.', name='researcher', capabilities=[WebSearch(), WebFetch(), TemporalDurability()], )

@workflow.defn class ResearchWorkflow(PydanticAIWorkflow): __pydantic_ai_agents__ = [agent]

@workflow.run async def run(self, topic: str) -> str: result = await agent.run(f'Write a brief on: {topic}') return result.output

DBOS and Prefect attach the same way, first-party and co-maintained, with Restate, AWS Lambda, Kitaru, Airflow, and Absurd integrations besides.

Build this → Durable Execution

Realtime voice

Put the same agent on a live voice session, tools and capabilities included:

uv add "pydantic-ai[openai-realtime]"
import asyncio

from pydantic_ai import Agent from pydantic_ai.capabilities import MCP

agent = Agent( instructions='You are a helpful voice assistant.', capabilities=[MCP('https://internal.example.com/mcp')], # capabilities work in voice too )

@agent.tool_plain def order_status(order_id: str) -> str: """Look up the status of an order.""" return f'Order {order_id}: shipped, arriving Thursday.'

async with agent.realtime('openai:gpt-realtime-2.1').session() as session: microphone = asyncio.create_task(session.send_audio(microphone_chunks())) # your microphone → the model speaker = asyncio.create_task(play_audio(session.stream_audio())) # model audio → your speaker async for part in session.stream_transcripts(): print(f'{part.speaker}: {part.transcript}')

The model calls your tools mid-conversation while it keeps talking, and every session is instrumented; voice is just another frontend, on OpenAI Realtime, Gemini Live, Azure, and xAI Grok Voice.

Build this → Realtime Voice

Image generation

Generate an image with a dedicated image model, no agent run required:

uv add pydantic-ai
from pathlib import Path

from pydantic_ai import ImageGenerator

generator = ImageGenerator('openai:gpt-image-2') result = generator.generate_sync('A minimalist logo for a coffee shop called Extract.') Path('logo.png').write_bytes(result.image.data)

That standalone image API is for when your application decides; when an agent run decides, there is provider-native generation with output_type=BinaryImage for a typed image output, and the ImageGeneration capability with its fallbacks for models that generate no images of their own.

Build this → Image Generation

See your first run in Logfire

Tip: Add two lines before any of these agents runs, and every model call and tool call shows up in Pydantic Logfire. Logfire has a free tier that needs no credit card, and you can sign up with just a GitHub account. Run uvx logfire auth and uvx logfire projects new once first, or point your coding agent at the Logfire setup skill to do it for you. The Logfire guide has the details, and any OpenTelemetry backend works instead.
>
> import logfire
> logfire.configure()
logfire.instrument_pydantic_ai()

Why Pydantic AI

Built by the Pydantic team: Pydantic Validation is the validation layer of the OpenAI SDK, the Anthropic SDK, the Google ADK, LangChain, and most of the AI ecosystem (and the foundation FastAPI was built on). Pydantic AI brings that same feeling to agents.

Putting it together: a bank support agent

A typed support agent showing several features working together: dependency injection, function tools, structured output, a reusable capability bundling the customer context, and an on-demand capability the model loads only when the conversation calls for it:

from dataclasses import dataclass

from pydantic import BaseModel, Field

from pydantic_ai import Agent, Capability, RunContext

from bank_database import DatabaseConn

@dataclass class SupportDependencies: # inject any client: DB pools, HTTP APIs, user info customer_id: int db: DatabaseConn

class SupportOutput(BaseModel): support_advice: str = Field(description='Advice returned to the customer') block_card: bool = Field(description="Whether to block the customer's card") risk: int = Field(description='Risk level of query', ge=0, le=10)

customer_context = Capability[SupportDependencies]( # a reusable unit of tools + instructions id='customer-context', description="Who the customer is and what's on their account.", )

@customer_context.instructions async def add_customer_name(ctx: RunContext[SupportDependencies]) -> str: customer_name = await ctx.deps.db.customer_name(id=ctx.deps.customer_id) return f"The customer's name is {customer_name!r}"

@customer_context.tool # signature and docstring become the tool schema the LLM sees async def customer_balance( ctx: RunContext[SupportDependencies], include_pending: bool ) -> float: """Returns the customer's current account balance.""" return await ctx.deps.db.customer_balance( id=ctx.deps.customer_id, include_pending=include_pending, )

refunds = Capability[SupportDependencies]( # deferred: loads on demand, like a skill id='refunds', description='Refund eligibility and refund status.', defer_loading=True, )

@refunds.tool async def refund_status(ctx: RunContext[SupportDependencies]) -> str: """Look up the refund status for the customer's most recent charge.""" return await ctx.deps.db.refund_status(id=ctx.deps.customer_id)

support_agent = Agent( 'openai:gpt-6-sol', deps_type=SupportDependencies, output_type=SupportOutput, # the run returns a validated SupportOutput, typed as such instructions=( 'You are a support agent in our bank, give the ' 'customer support and judge the risk level of their query.' ), capabilities=[customer_context, refunds], )

... # in a real use case: more tools, longer instructions

async def main(): deps = SupportDependencies(customer_id=123, db=DatabaseConn()) result = await support_agent.run('What is my balance?', deps=deps) print(result.output) """ support_advice='Hello John, your current account balance, including pending transactions, is $123.45.' block_card=False risk=1 """

result = await support_agent.run('I just lost my card!', deps=deps) print(result.output) """ support_advice="I'm sorry to hear that, John. We are temporarily blocking your card to prevent unauthorized transactions." block_card=True risk=8 """

result = await support_agent.run( # the model loads refunds on demand, then answers 'Was I refunded for the duplicate charge on my last statement?', deps=deps ) print(result.output) """ support_advice='Good news, John: the duplicate charge on your last statement was refunded on 2026-05-01.' block_card=False risk=1 """

For the annotated walkthrough and Logfire tracing, see the same example in the docs.

Next Steps

Part of the Pydantic Stack

Everything you need to ship production-grade AI agents:

GitHub Stars & Activity

20,295Stars
2,834Forks
0Open issues
PythonLanguage

GitHub Popularity

GitHub stars20,295
Forks2,834
Open issues0
Primary languagePython
License-
Stars gained today24
Created-
Last pushed-

Trending History

Daily boardrank #52 · ▲ 24 stars

Related AI Projects

1

harry0703 / MoneyPrinterTurbo

Python★ 127,452⑂ 19,939▲ 464 stars
→
2

ComposioHQ / awesome-claude-skills

Python★ 76,074⑂ 8,876▲ 118 stars
→
3

rohitg00 / ai-engineering-from-scratch

Python★ 62,081⑂ 10,609▲ 1,203 stars
→
4

bmad-code-org / BMAD-METHOD

Python★ 53,670⑂ 6,051▲ 45 stars
→
5

debpalash / VoiceStudio

Python★ 50,188⑂ 5,577▲ 3,481 stars
→
6

VectifyAI / PageIndex

Python★ 38,049⑂ 3,304▲ 1,095 stars
→
7

alirezarezvani / claude-skills

Python★ 27,031⑂ 3,822▲ 154 stars
→
8

AgriciDaniel / claude-seo

Python★ 18,035⑂ 2,651▲ 72 stars
→

More AI Rankings