building-pydantic-ai-agents

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Building AI Agents with Pydantic AI

使用Pydantic AI构建AI Agent

Pydantic AI is a Python agent framework for building production-grade Generative AI applications. This skill provides patterns, architecture guidance, and tested code examples for building applications with Pydantic AI.
Pydantic AI是一款用于构建生产级生成式AI应用的Python Agent框架。本技能提供了使用Pydantic AI构建应用的模式、架构指导以及经过测试的代码示例。

When to Use This Skill

何时使用本技能

Invoke this skill when:
  • User asks to build an AI agent, create an LLM-powered app, or mentions Pydantic AI
  • User wants to add tools, capabilities (thinking, web search), or structured output to an agent
  • User asks to define agents from YAML/JSON specs or use template strings
  • User wants to stream agent events, delegate between agents, or test agent behavior
  • Code imports
    pydantic_ai
    or references Pydantic AI classes (
    Agent
    ,
    RunContext
    ,
    Tool
    )
  • User asks about hooks, lifecycle interception, or agent observability with Logfire
Do not use this skill for:
  • The Pydantic validation library alone (
    pydantic
    /
    BaseModel
    without agents)
  • Other AI frameworks (LangChain, LlamaIndex, CrewAI, AutoGen)
  • General Python development unrelated to AI agents
在以下场景调用本技能:
  • 用户要求构建AI Agent、创建基于LLM的应用,或提及Pydantic AI
  • 用户希望为Agent添加工具、功能(思考、网页搜索)或结构化输出
  • 用户要求通过YAML/JSON规范定义Agent或使用模板字符串
  • 用户希望流式传输Agent事件、在Agent间委派任务或测试Agent行为
  • 代码中导入
    pydantic_ai
    或引用Pydantic AI类(
    Agent
    RunContext
    Tool
  • 用户询问钩子、生命周期拦截或借助Logfire实现Agent可观测性
请勿在以下场景使用本技能:
  • 仅使用Pydantic验证库(
    pydantic
    /
    BaseModel
    ,未涉及Agent)
  • 其他AI框架(LangChain、LlamaIndex、CrewAI、AutoGen)
  • 与AI Agent无关的通用Python开发

Quick-Start Patterns

快速入门模式

Create a Basic Agent

创建基础Agent

python
from pydantic_ai import Agent

agent = Agent(
    'anthropic:claude-sonnet-4-6',
    instructions='Be concise, reply with one sentence.',
)

result = agent.run_sync('Where does "hello world" come from?')
print(result.output)
"""
The first known use of "hello, world" was in a 1974 textbook about the C programming language.
"""
python
from pydantic_ai import Agent

agent = Agent(
    'anthropic:claude-sonnet-4-6',
    instructions='Be concise, reply with one sentence.',
)

result = agent.run_sync('Where does "hello world" come from?')
print(result.output)
"""
The first known use of "hello, world" was in a 1974 textbook about the C programming language.
"""

Add Tools to an Agent

为Agent添加工具

python
import random

from pydantic_ai import Agent, RunContext

agent = Agent(
    'google-gla:gemini-3-flash-preview',
    deps_type=str,
    instructions=(
        "You're a dice game, you should roll the die and see if the number "
        "you get back matches the user's guess. If so, tell them they're a winner. "
        "Use the player's name in the response."
    ),
)


@agent.tool_plain
def roll_dice() -> str:
    """Roll a six-sided die and return the result."""
    return str(random.randint(1, 6))


@agent.tool
def get_player_name(ctx: RunContext[str]) -> str:
    """Get the player's name."""
    return ctx.deps


dice_result = agent.run_sync('My guess is 4', deps='Anne')
print(dice_result.output)
#> Congratulations Anne, you guessed correctly! You're a winner!
python
import random

from pydantic_ai import Agent, RunContext

agent = Agent(
    'google-gla:gemini-3-flash-preview',
    deps_type=str,
    instructions=(
        "You're a dice game, you should roll the die and see if the number "
        "you get back matches the user's guess. If so, tell them they're a winner. "
        "Use the player's name in the response."
    ),
)


@agent.tool_plain
def roll_dice() -> str:
    """Roll a six-sided die and return the result."""
    return str(random.randint(1, 6))


@agent.tool
def get_player_name(ctx: RunContext[str]) -> str:
    """Get the player's name."""
    return ctx.deps


dice_result = agent.run_sync('My guess is 4', deps='Anne')
print(dice_result.output)
#> Congratulations Anne, you guessed correctly! You're a winner!

Structured Output with Pydantic Models

结合Pydantic模型实现结构化输出

python
from pydantic import BaseModel

from pydantic_ai import Agent


class CityLocation(BaseModel):
    city: str
    country: str


agent = Agent('google-gla:gemini-3-flash-preview', output_type=CityLocation)
result = agent.run_sync('Where were the olympics held in 2012?')
print(result.output)
#> city='London' country='United Kingdom'
print(result.usage())
#> RunUsage(input_tokens=57, output_tokens=8, requests=1)
python
from pydantic import BaseModel

from pydantic_ai import Agent


class CityLocation(BaseModel):
    city: str
    country: str


agent = Agent('google-gla:gemini-3-flash-preview', output_type=CityLocation)
result = agent.run_sync('Where were the olympics held in 2012?')
print(result.output)
#> city='London' country='United Kingdom'
print(result.usage())
#> RunUsage(input_tokens=57, output_tokens=8, requests=1)

Dependency Injection

依赖注入

python
from datetime import date

from pydantic_ai import Agent, RunContext

agent = Agent(
    'openai:gpt-5.2',
    deps_type=str,
    instructions="Use the customer's name while replying to them.",
)


@agent.instructions
def add_the_users_name(ctx: RunContext[str]) -> str:
    return f"The user's name is {ctx.deps}."


@agent.instructions
def add_the_date() -> str:
    return f'The date is {date.today()}.'


result = agent.run_sync('What is the date?', deps='Frank')
print(result.output)
#> Hello Frank, the date today is 2032-01-02.
python
from datetime import date

from pydantic_ai import Agent, RunContext

agent = Agent(
    'openai:gpt-5.2',
    deps_type=str,
    instructions="Use the customer's name while replying to them.",
)


@agent.instructions
def add_the_users_name(ctx: RunContext[str]) -> str:
    return f"The user's name is {ctx.deps}."


@agent.instructions
def add_the_date() -> str:
    return f'The date is {date.today()}.'


result = agent.run_sync('What is the date?', deps='Frank')
print(result.output)
#> Hello Frank, the date today is 2032-01-02.

Testing with TestModel

使用TestModel进行测试

python
from pydantic_ai import Agent
from pydantic_ai.models.test import TestModel

my_agent = Agent('openai:gpt-5.2', instructions='...')


async def test_my_agent():
    """Unit test for my_agent, to be run by pytest."""
    m = TestModel()
    with my_agent.override(model=m):
        result = await my_agent.run('Testing my agent...')
        assert result.output == 'success (no tool calls)'
    assert m.last_model_request_parameters.function_tools == []
python
from pydantic_ai import Agent
from pydantic_ai.models.test import TestModel

my_agent = Agent('openai:gpt-5.2', instructions='...')


async def test_my_agent():
    """Unit test for my_agent, to be run by pytest."""
    m = TestModel()
    with my_agent.override(model=m):
        result = await my_agent.run('Testing my agent...')
        assert result.output == 'success (no tool calls)'
    assert m.last_model_request_parameters.function_tools == []

Use Capabilities

使用功能组件(Capabilities)

Capabilities are reusable, composable units of agent behavior — bundling tools, hooks, instructions, and model settings.
python
from pydantic_ai import Agent
from pydantic_ai.capabilities import Thinking, WebSearch

agent = Agent(
    'anthropic:claude-opus-4-6',
    instructions='You are a research assistant. Be thorough and cite sources.',
    capabilities=[
        Thinking(effort='high'),
        WebSearch(),
    ],
)
功能组件是可复用、可组合的Agent行为单元——整合了工具、钩子、指令和模型设置。
python
from pydantic_ai import Agent
from pydantic_ai.capabilities import Thinking, WebSearch

agent = Agent(
    'anthropic:claude-opus-4-6',
    instructions='You are a research assistant. Be thorough and cite sources.',
    capabilities=[
        Thinking(effort='high'),
        WebSearch(),
    ],
)

Add Lifecycle Hooks

添加生命周期钩子

Use
Hooks
to intercept model requests, tool calls, and runs with decorators — no subclassing needed.
python
from pydantic_ai import Agent, RunContext
from pydantic_ai.capabilities.hooks import Hooks
from pydantic_ai.models import ModelRequestContext

hooks = Hooks()


@hooks.on.before_model_request
async def log_request(ctx: RunContext[None], request_context: ModelRequestContext) -> ModelRequestContext:
    print(f'Sending {len(request_context.messages)} messages')
    return request_context


agent = Agent('openai:gpt-5.2', capabilities=[hooks])
使用
Hooks
通过装饰器拦截模型请求、工具调用和运行过程——无需子类化。
python
from pydantic_ai import Agent, RunContext
from pydantic_ai.capabilities.hooks import Hooks
from pydantic_ai.models import ModelRequestContext

hooks = Hooks()


@hooks.on.before_model_request
async def log_request(ctx: RunContext[None], request_context: ModelRequestContext) -> ModelRequestContext:
    print(f'Sending {len(request_context.messages)} messages')
    return request_context


agent = Agent('openai:gpt-5.2', capabilities=[hooks])

Define Agent from YAML Spec

通过YAML规范定义Agent

Use
Agent.from_file
to load agents from YAML or JSON — no Python agent construction code needed.
python
from pydantic_ai import Agent
使用
Agent.from_file
从YAML或JSON加载Agent——无需编写Python Agent构建代码。
python
from pydantic_ai import Agent

agent.yaml:

agent.yaml:

model: anthropic:claude-opus-4-6

model: anthropic:claude-opus-4-6

instructions: You are a helpful research assistant.

instructions: You are a helpful research assistant.

capabilities:

capabilities:

- WebSearch

- WebSearch

- Thinking:

- Thinking:

effort: high

effort: high

agent = Agent.from_file('agent.yaml')
undefined
agent = Agent.from_file('agent.yaml')
undefined

Task Routing Table

任务路由表

I want to...Documentation
Create or configure agentsAgents
Bundle reusable behavior (tools, hooks, instructions)Capabilities
Intercept model requests, tool calls, or runsHooks
Define agents in YAML/JSON without Python codeAgent Specs
Use template strings in agent instructionsTemplate Strings
Let my agent call external APIs or functionsTools
Organize or restrict which tools an agent can useToolsets
Give my agent web search with automatic provider fallbackWebSearch Capability
Give my agent URL fetching with automatic provider fallbackWebFetch Capability
Give my agent web search or code execution (builtin tools)Built-in Tools
Search with DuckDuckGo/Tavily/ExaCommon Tools
Ensure my agent returns data in a specific formatStructured Output
Pass database connections, API clients, or config to toolsDependencies
Access usage stats, message history, or retry count in toolsRunContext
Choose or configure modelsModels
Automatically switch to backup model when primary failsFallback Model
Show real-time progress as my agent worksStreaming Events and Final Output
Work with messages and multimediaMessage History
Reduce token costs by trimming or filtering conversation historyProcessing Message History
Keep long conversations manageable without losing contextSummarize Old Messages
Use MCP serversMCP
Build multi-step graphsGraph
Debug a failed agent run or see what went wrongModel Errors
Make my agent resilient to temporary failuresRetries
Understand why my agent made specific decisionsUsing Logfire
Write deterministic tests for my agentUnit testing with TestModel
Enable thinking/reasoning across any providerThinking · Thinking Capability
Systematically verify my agent works correctlyEvals
Use embeddings for RAGEmbeddings
Use durable executionDurable Execution
Have one agent delegate tasks to anotherAgent Delegation
Route requests to different agents based on intentProgrammatic Agent Hand-off
Require tool approval (human-in-the-loop)Deferred Tools
Use images, audio, video, or documentsInput
Use advanced tool featuresAdvanced Tools
Validate or require approval before tool executionAdvanced Tools
Call the model without using an agentDirect API
Expose agents as HTTP servers (A2A)A2A
Handle network errors and rate limiting automaticallyRetries
Use LangChain or ACI.dev toolsThird-Party Tools
Publish reusable agent extensions as packagesExtensibility
Build custom toolsets, models, or agentsExtensibility
Debug common issuesTroubleshooting
Migrate from deprecated APIsChangelog
See advanced real-world examplesExamples
Look up an import pathAPI Reference
我想要...文档链接
创建或配置AgentAgents
打包可复用行为(工具、钩子、指令)Capabilities
拦截模型请求、工具调用或运行过程Hooks
无需Python代码,通过YAML/JSON定义AgentAgent Specs
在Agent指令中使用模板字符串Template Strings
让Agent调用外部API或函数Tools
组织或限制Agent可使用的工具Toolsets
为Agent提供带有自动提供商降级的网页搜索功能WebSearch Capability
为Agent提供带有自动提供商降级的URL获取功能WebFetch Capability
为Agent提供网页搜索或代码执行功能(内置工具)Built-in Tools
使用DuckDuckGo/Tavily/Exa进行搜索Common Tools
确保Agent以特定格式返回数据Structured Output
将数据库连接、API客户端或配置传递给工具Dependencies
在工具中访问使用统计、消息历史或重试次数RunContext
选择或配置模型Models
主模型故障时自动切换到备用模型Fallback Model
显示Agent工作时的实时进度Streaming Events and Final Output
处理消息和多媒体内容Message History
通过修剪或过滤对话历史降低Token成本Processing Message History
在不丢失上下文的情况下管理长对话Summarize Old Messages
使用MCP服务器MCP
构建多步骤图Graph
调试失败的Agent运行或排查问题原因Model Errors
让Agent能够抵御临时故障Retries
理解Agent做出特定决策的原因Using Logfire
为Agent编写确定性测试Unit testing with TestModel
在任意提供商中启用思考/推理功能Thinking · Thinking Capability
系统地验证Agent是否正常工作Evals
使用嵌入技术实现RAGEmbeddings
使用持久化执行Durable Execution
让一个Agent将任务委派给另一个AgentAgent Delegation
根据意图将请求路由到不同AgentProgrammatic Agent Hand-off
要求工具执行前需人工审批(人在回路中)Deferred Tools
使用图片、音频、视频或文档Input
使用高级工具功能Advanced Tools
在工具执行前进行验证或要求审批Advanced Tools
不使用Agent直接调用模型Direct API
将Agent暴露为HTTP服务器(A2A)A2A
自动处理网络错误和速率限制Retries
使用LangChain或ACI.dev工具Third-Party Tools
将可复用的Agent扩展发布为包Extensibility
构建自定义工具集、模型或AgentExtensibility
调试常见问题Troubleshooting
从已弃用的API迁移Changelog
查看高级真实世界示例Examples
查找导入路径API Reference

Architecture and Decisions

架构与决策

Load Architecture and Decision Guide for detailed decision trees, comparison tables, and architecture overview:
TopicWhat it covers
Decision TreesTool registration, output modes, multi-agent patterns, capabilities, testing approaches, extensibility
Comparison TablesOutput modes, model provider prefixes, tool decorators, built-in capabilities, agent methods
Architecture OverviewExecution flow, generic types, construction patterns, lifecycle hooks, model string format
Quick reference — model string format:
"provider:model-name"
(e.g.,
"openai:gpt-5.2"
,
"anthropic:claude-sonnet-4-6"
,
"google-gla:gemini-3-pro-preview"
)
Quick reference — key agent methods:
run()
,
run_sync()
,
run_stream()
,
run_stream_sync()
,
run_stream_events()
,
iter()
加载架构与决策指南获取详细的决策树、对比表和架构概述:
主题涵盖内容
决策树工具注册、输出模式、多Agent模式、功能组件、测试方法、可扩展性
对比表输出模式、模型提供商前缀、工具装饰器、内置功能组件、Agent方法
架构概述执行流程、泛型类型、构建模式、生命周期钩子、模型字符串格式
快速参考——模型字符串格式:
"provider:model-name"
(例如:
"openai:gpt-5.2"
"anthropic:claude-sonnet-4-6"
"google-gla:gemini-3-pro-preview"
快速参考——核心Agent方法:
run()
run_sync()
run_stream()
run_stream_sync()
run_stream_events()
iter()

Key Practices

关键实践

  • Python 3.10+ compatibility required
  • Observability: Pydantic AI has first-class integration with Logfire for tracing agent runs, tool calls, and model requests. Add it with
    logfire.instrument_pydantic_ai()
    . For deeper HTTP-level visibility,
    logfire.instrument_httpx(capture_all=True)
    captures the exact payloads sent to model providers.
  • Testing: Use
    TestModel
    for deterministic tests,
    FunctionModel
    for custom logic
  • 要求兼容Python 3.10+
  • 可观测性:Pydantic AI与Logfire深度集成,可追踪Agent运行、工具调用和模型请求。通过
    logfire.instrument_pydantic_ai()
    启用。如需更深入的HTTP级可见性,
    logfire.instrument_httpx(capture_all=True)
    可捕获发送给模型提供商的完整负载。
  • 测试:使用
    TestModel
    进行确定性测试,使用
    FunctionModel
    实现自定义逻辑

Common Gotchas

常见误区

These are mistakes agents commonly make with Pydantic AI. Getting these wrong produces silent failures or confusing errors.
  • @agent.tool
    requires
    RunContext
    as first param
    ;
    @agent.tool_plain
    must not have it. Mixing these up causes runtime errors. Use
    tool_plain
    when you don't need deps, usage, or messages.
  • Model strings need the provider prefix:
    'openai:gpt-5.2'
    not
    'gpt-5.2'
    . Without the prefix, Pydantic AI can't resolve the provider.
  • TestModel
    requires
    agent.override()
    : Don't set
    agent.model
    directly. Always use the context manager:
    with agent.override(model=TestModel()):
    .
  • str
    in output_type allows plain text to end the run
    : If your union includes
    str
    (or no
    output_type
    is set), the model can return plain text instead of structured output. Omit
    str
    from the union to force tool-based output.
  • Hook decorator names on
    .on
    don't repeat
    on_
    : Use
    hooks.on.run_error
    and
    hooks.on.model_request_error
    — not
    hooks.on.on_run_error
    .
  • history_processors
    is plural
    : The Agent parameter is
    history_processors=[...]
    , not
    history_processor=
    .
这些是使用Pydantic AI时常见的错误,会导致静默失败或令人困惑的错误。
  • @agent.tool
    要求第一个参数为
    RunContext
    @agent.tool_plain
    不能包含该参数。混淆两者会导致运行时错误。当不需要依赖项、使用统计或消息时,使用
    tool_plain
  • 模型字符串需要提供商前缀:应使用
    'openai:gpt-5.2'
    而非
    'gpt-5.2'
    。没有前缀的话,Pydantic AI无法解析提供商。
  • TestModel
    需要使用
    agent.override()
    :不要直接设置
    agent.model
    。请始终使用上下文管理器:
    with agent.override(model=TestModel()):
  • output_type
    中的
    str
    允许纯文本结束运行
    :如果你的联合类型包含
    str
    (或未设置
    output_type
    ),模型可以返回纯文本而非结构化输出。从联合类型中移除
    str
    以强制返回基于工具的输出。
  • 钩子装饰器名称在
    .on
    后不要重复
    on_
    :使用
    hooks.on.run_error
    hooks.on.model_request_error
    ——而非
    hooks.on.on_run_error
  • history_processors
    是复数形式
    :Agent的参数是
    history_processors=[...]
    ,而非
    history_processor=

Common Tasks

常见任务

Load Common Tasks Reference for detailed implementation guidance with code examples:
TaskSection
Add capabilities (Thinking, WebSearch, etc.)Add Capabilities to an Agent
Intercept model requests and tool callsIntercept Agent Lifecycle with Hooks
Define agents from YAML/JSON config filesDefine Agents Declaratively with Specs
Enable thinking/reasoning across providersEnable Thinking Across Providers
Trim or filter conversation historyManage Context Size
Stream events and show real-time progressShow Real-Time Progress
Auto-switch providers on failureHandle Provider Failures
Write deterministic testsTest Agent Behavior
Delegate tasks between agentsCoordinate Multiple Agents
Instrument with Logfire for debuggingDebug and Validate Agent Behavior
加载常见任务参考获取详细的实现指导和代码示例:
任务章节
添加功能组件(Thinking、WebSearch等)为Agent添加功能组件
拦截模型请求和工具调用使用钩子拦截Agent生命周期
通过YAML/JSON配置文件定义Agent通过声明式规范定义Agent
在不同提供商中启用思考/推理功能在多提供商中启用思考功能
修剪或过滤对话历史管理上下文长度
流式传输事件并显示实时进度显示实时进度
提供商故障时自动切换处理提供商故障
编写确定性测试测试Agent行为
在Agent间委派任务协调多个Agent
使用Logfire进行调试调试与验证Agent行为