pydantic-ai

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Pydantic AI Expert Skill

Pydantic AI 专家技能指南

You are an expert on Pydantic AI — the production-grade Python agent framework by the Pydantic team. Always write idiomatic Pydantic AI code with full type annotations, dataclass deps, and Pydantic output models.
您是Pydantic AI的专家——这是由Pydantic团队开发的生产级Python Agent框架。 请始终编写符合Pydantic AI风格的代码,包含完整的类型注解、数据类依赖项和Pydantic输出模型。

Core Mental Model

核心思维模型

Pydantic AI = Agent container + Tools (functions LLM may call) + Dependencies (injected context) + Structured Output (validated Pydantic models).
Agent[DepType, OutputType]
  ├── instructions / system_prompt
  ├── @agent.tool / @agent.tool_plain  →  functions LLM calls
  ├── deps_type  →  injected via RunContext[DepType]
  └── output_type  →  validated Pydantic model or primitive

Pydantic AI = Agent 容器 + 工具(LLM可调用的函数) + 依赖项(注入的上下文) + 结构化输出(经过验证的Pydantic模型)。
Agent[DepType, OutputType]
  ├── instructions / system_prompt
  ├── @agent.tool / @agent.tool_plain  →  LLM调用的函数
  ├── deps_type  → 通过RunContext[DepType]注入
  └── output_type  → 经过验证的Pydantic模型或原始类型

Installation

安装

bash
pip install pydantic-ai                # base install
pip install 'pydantic-ai[openai]'      # with OpenAI support
pip install 'pydantic-ai[anthropic]'   # with Anthropic support
pip install 'pydantic-ai[logfire]'     # with observability
Set your API key:
bash
export OPENAI_API_KEY=sk-...
export ANTHROPIC_API_KEY=sk-ant-...

bash
pip install pydantic-ai                # 基础安装
pip install 'pydantic-ai[openai]'      # 包含OpenAI支持
pip install 'pydantic-ai[anthropic]'   # 包含Anthropic支持
pip install 'pydantic-ai[logfire]'     # 包含可观测性支持
设置您的API密钥:
bash
export OPENAI_API_KEY=sk-...
export ANTHROPIC_API_KEY=sk-ant-...

1. Agents — The Core Building Block

1. Agent — 核心构建块

python
from pydantic_ai import Agent
python
from pydantic_ai import Agent

Minimal agent (text output)

最简Agent(文本输出)

agent = Agent('openai:gpt-4o', instructions='Be concise.') result = agent.run_sync('What is 2+2?') print(result.output) # "4"
undefined
agent = Agent('openai:gpt-4o', instructions='请简洁回答。') result = agent.run_sync('2+2等于多少?') print(result.output) # "4"
undefined

Agent Constructor Key Parameters

Agent构造函数关键参数

ParameterPurpose
model
Model string:
'openai:gpt-4o'
,
'anthropic:claude-sonnet-4-6'
, etc.
instructions
Static system prompt string (preferred over
system_prompt
)
deps_type
Type of dependency object injected at runtime
output_type
Pydantic model or primitive for structured output
model_settings
Default
ModelSettings
(temperature, max_tokens, etc.)
retries
Number of output validation retries (default: 1)
参数用途
model
模型字符串:
'openai:gpt-4o'
'anthropic:claude-sonnet-4-6'
instructions
静态系统提示字符串(优先于
system_prompt
deps_type
运行时注入的依赖对象类型
output_type
用于结构化输出的Pydantic模型或原始类型
model_settings
默认
ModelSettings
(温度、最大tokens等)
retries
输出验证重试次数(默认:1)

Running Agents — 5 Ways

运行Agent的5种方式

python
undefined
python
undefined

1. Sync (simplest, for scripts/notebooks)

1. 同步方式(最简单,适用于脚本/笔记本)

result = agent.run_sync('prompt') print(result.output)
result = agent.run_sync('提示词') print(result.output)

2. Async (for production async apps)

2. 异步方式(适用于生产级异步应用)

result = await agent.run('prompt')
result = await agent.run('提示词')

3. Streaming text

3. 流式文本输出

async with agent.run_stream('prompt') as resp: async for chunk in resp.stream_text(): print(chunk, end='')
async with agent.run_stream('提示词') as resp: async for chunk in resp.stream_text(): print(chunk, end='')

4. Streaming events (tool calls visible)

4. 流式事件输出(可查看工具调用)

async for event in agent.run_stream_events('prompt'): ...
async for event in agent.run_stream_events('提示词'): ...

5. Iter (full graph control)

5. 迭代方式(完全控制执行图)

async with agent.iter('prompt') as run: async for node in run: ...

---
async with agent.iter('提示词') as run: async for node in run: ...

---

2. Tools — Giving the LLM Capabilities

2. 工具 — 为LLM赋予能力

python
from pydantic_ai import Agent, RunContext

agent = Agent('openai:gpt-4o', deps_type=str)

@agent.tool                          # has RunContext access (for deps)
async def search_db(ctx: RunContext[str], query: str) -> list[str]:
    """Search the database for records matching the query."""
    db_conn = ctx.deps  # access injected dependency
    return await db_conn.search(query)

@agent.tool_plain                    # no RunContext needed
def get_current_time() -> str:
    """Return the current UTC time."""
    from datetime import datetime, UTC
    return datetime.now(UTC).isoformat()
python
from pydantic_ai import Agent, RunContext

agent = Agent('openai:gpt-4o', deps_type=str)

@agent.tool                          # 可访问RunContext(用于依赖项)
async def search_db(ctx: RunContext[str], query: str) -> list[str]:
    """在数据库中搜索与查询匹配的记录。"""
    db_conn = ctx.deps  # 访问注入的依赖项
    return await db_conn.search(query)

@agent.tool_plain                    # 无需RunContext
def get_current_time() -> str:
    """返回当前UTC时间。"""
    from datetime import datetime, UTC
    return datetime.now(UTC).isoformat()

Tool Best Practices

工具最佳实践

  • Docstring = LLM description: Write clear docstrings — they become the tool's description sent to the model.
  • Parameter types = schema: Type annotations generate the JSON schema for the LLM.
  • Return type: Return strings, dicts, Pydantic models, or any JSON-serializable value.
  • Errors: Raise
    ModelRetry
    to tell the LLM to retry with better args.
python
from pydantic_ai.exceptions import ModelRetry

@agent.tool_plain
def divide(a: float, b: float) -> float:
    """Divide a by b."""
    if b == 0:
        raise ModelRetry('Cannot divide by zero — provide a non-zero b.')
    return a / b

  • 文档字符串 = LLM的描述:编写清晰的文档字符串——它们会成为发送给模型的工具描述。
  • 参数类型 = 模式:类型注解会为LLM生成JSON模式。
  • 返回类型:返回字符串、字典、Pydantic模型或任何可JSON序列化的值。
  • 错误处理:抛出
    ModelRetry
    以告知LLM使用更合适的参数重试。
python
from pydantic_ai.exceptions import ModelRetry

@agent.tool_plain
def divide(a: float, b: float) -> float:
    """计算a除以b的结果。"""
    if b == 0:
        raise ModelRetry('不能除以零,请提供非零的b值。')
    return a / b

3. Dependencies — Type-Safe Context Injection

3. 依赖项 — 类型安全的上下文注入

Dependencies are the Pydantic AI way to pass DB connections, config, HTTP clients, etc. into tools and instructions without globals.
python
from dataclasses import dataclass
from pydantic_ai import Agent, RunContext
import httpx

@dataclass
class AppDeps:
    http_client: httpx.AsyncClient
    user_id: int
    api_key: str

agent = Agent('openai:gpt-4o', deps_type=AppDeps)

@agent.tool
async def fetch_user_data(ctx: RunContext[AppDeps]) -> dict:
    """Fetch the current user's profile."""
    resp = await ctx.deps.http_client.get(
        f'/users/{ctx.deps.user_id}',
        headers={'Authorization': f'Bearer {ctx.deps.api_key}'}
    )
    return resp.json()
依赖项是Pydantic AI中传递数据库连接、配置、HTTP客户端等的方式,无需使用全局变量即可将其传入工具和指令。
python
from dataclasses import dataclass
from pydantic_ai import Agent, RunContext
import httpx

@dataclass
class AppDeps:
    http_client: httpx.AsyncClient
    user_id: int
    api_key: str

agent = Agent('openai:gpt-4o', deps_type=AppDeps)

@agent.tool
async def fetch_user_data(ctx: RunContext[AppDeps]) -> dict:
    """获取当前用户的个人资料。"""
    resp = await ctx.deps.http_client.get(
        f'/users/{ctx.deps.user_id}',
        headers={'Authorization': f'Bearer {ctx.deps.api_key}'}
    )
    return resp.json()

Pass deps at runtime:

运行时传入依赖项:

async with httpx.AsyncClient(base_url='https://api.example.com') as client: deps = AppDeps(http_client=client, user_id=42, api_key='secret') result = await agent.run('Get my profile', deps=deps)
undefined
async with httpx.AsyncClient(base_url='https://api.example.com') as client: deps = AppDeps(http_client=client, user_id=42, api_key='secret') result = await agent.run('获取我的个人资料', deps=deps)
undefined

Dynamic Instructions with Dependencies

结合依赖项的动态指令

python
@agent.instructions
async def personalized_instructions(ctx: RunContext[AppDeps]) -> str:
    user = await ctx.deps.db.get_user(ctx.deps.user_id)
    return f"The user's name is {user.name!r}. Personalize all responses."

python
@agent.instructions
async def personalized_instructions(ctx: RunContext[AppDeps]) -> str:
    user = await ctx.deps.db.get_user(ctx.deps.user_id)
    return f"用户姓名为{user.name!r}。请根据用户情况个性化所有回复。"

4. Structured Output

4. 结构化输出

python
from pydantic import BaseModel, Field
from pydantic_ai import Agent

class MovieReview(BaseModel):
    title: str
    rating: int = Field(ge=1, le=10, description='Rating from 1-10')
    summary: str
    recommend: bool

agent = Agent('openai:gpt-4o', output_type=MovieReview)
result = agent.run_sync('Review the movie Inception')
review = result.output  # typed as MovieReview
print(review.rating)    # int, validated by Pydantic
python
from pydantic import BaseModel, Field
from pydantic_ai import Agent

class MovieReview(BaseModel):
    title: str
    rating: int = Field(ge=1, le=10, description='评分范围1-10')
    summary: str
    recommend: bool

agent = Agent('openai:gpt-4o', output_type=MovieReview)
result = agent.run_sync('评价电影《盗梦空间》')
review = result.output  # 类型为MovieReview
print(review.rating)    # 经过Pydantic验证的整数

Union Output (Multiple Possible Types)

联合输出(多种可能类型)

python
from typing import Union

class SuccessResult(BaseModel):
    data: dict

class ErrorResult(BaseModel):
    error_message: str
    retry_after: int

agent = Agent('openai:gpt-4o', output_type=Union[SuccessResult, ErrorResult])

python
from typing import Union

class SuccessResult(BaseModel):
    data: dict

class ErrorResult(BaseModel):
    error_message: str
    retry_after: int

agent = Agent('openai:gpt-4o', output_type=Union[SuccessResult, ErrorResult])

5. Multi-Agent Patterns

5. 多Agent模式

Simple Delegation

简单委托

python
summarizer = Agent('openai:gpt-4o-mini', instructions='Summarize text concisely.')
analyst = Agent('openai:gpt-4o', instructions='Analyze data and provide insights.')

@analyst.tool_plain
async def summarize(text: str) -> str:
    """Summarize a long piece of text before analysis."""
    result = await summarizer.run(text)
    return result.output
python
summarizer = Agent('openai:gpt-4o-mini', instructions='简洁总结文本内容。')
analyst = Agent('openai:gpt-4o', instructions='分析数据并提供见解。')

@analyst.tool_plain
async def summarize(text: str) -> str:
    """分析前先总结长文本内容。"""
    result = await summarizer.run(text)
    return result.output

Passing Message History (Conversation)

传递消息历史(多轮对话)

python
from pydantic_ai.messages import ModelMessagesTypeAdapter

result1 = await agent.run('Hello, my name is Alice.')
result2 = await agent.run('What is my name?', message_history=result1.new_messages())
print(result2.output)  # "Your name is Alice."

python
from pydantic_ai.messages import ModelMessagesTypeAdapter

result1 = await agent.run('你好,我叫Alice。')
result2 = await agent.run('我叫什么名字?', message_history=result1.new_messages())
print(result2.output)  # "你的名字是Alice。"

6. Streaming Structured Output

6. 流式结构化输出

python
from pydantic import BaseModel

class Analysis(BaseModel):
    summary: str
    key_points: list[str]
    confidence: float

agent = Agent('openai:gpt-4o', output_type=Analysis)

async with agent.run_stream('Analyze quantum computing trends') as resp:
    async for partial in resp.stream():
        print(partial)  # partial Analysis objects as they arrive
    final = await resp.get_output()

python
from pydantic import BaseModel

class Analysis(BaseModel):
    summary: str
    key_points: list[str]
    confidence: float

agent = Agent('openai:gpt-4o', output_type=Analysis)

async with agent.run_stream('分析量子计算发展趋势') as resp:
    async for partial in resp.stream():
        print(partial)  # 输出逐步生成的部分Analysis对象
    final = await resp.get_output()

7. MCP Integration

7. MCP集成

python
from pydantic_ai import Agent
from pydantic_ai.mcp import MCPServerStdio
python
from pydantic_ai import Agent
from pydantic_ai.mcp import MCPServerStdio

Connect to an MCP server

连接到MCP服务器

server = MCPServerStdio('npx', ['-y', '@modelcontextprotocol/server-filesystem', '/tmp'])
agent = Agent('openai:gpt-4o', mcp_servers=[server])
async with agent.run_mcp_servers(): result = await agent.run('List the files in /tmp') print(result.output)

---
server = MCPServerStdio('npx', ['-y', '@modelcontextprotocol/server-filesystem', '/tmp'])
agent = Agent('openai:gpt-4o', mcp_servers=[server])
async with agent.run_mcp_servers(): result = await agent.run('列出/tmp目录下的文件') print(result.output)

---

8. Testing

8. 测试

Use
TestModel
to test agents without real API calls:
python
from pydantic_ai import Agent
from pydantic_ai.models.test import TestModel

agent = Agent('openai:gpt-4o', output_type=bool)

def test_agent_response():
    with agent.override(model=TestModel(custom_output_text='true')):
        result = agent.run_sync('Is Paris the capital of France?')
    assert result.output is True
Use
FunctionModel
for fine-grained control:
python
from pydantic_ai.models.function import FunctionModel, ModelRequest

def my_model(messages: list[ModelRequest], info) -> str:
    last = messages[-1].parts[-1].content
    return f'Echo: {last}'

with agent.override(model=FunctionModel(my_model)):
    result = agent.run_sync('test')

使用
TestModel
在不调用真实API的情况下测试Agent:
python
from pydantic_ai import Agent
from pydantic_ai.models.test import TestModel

agent = Agent('openai:gpt-4o', output_type=bool)

def test_agent_response():
    with agent.override(model=TestModel(custom_output_text='true')):
        result = agent.run_sync('巴黎是法国的首都吗?')
    assert result.output is True
使用
FunctionModel
实现更精细的控制:
python
from pydantic_ai.models.function import FunctionModel, ModelRequest

def my_model(messages: list[ModelRequest], info) -> str:
    last = messages[-1].parts[-1].content
    return f'Echo: {last}'

with agent.override(model=FunctionModel(my_model)):
    result = agent.run_sync('test')

9. Retries & Error Handling

9. 重试与错误处理

python
from pydantic_ai import Agent
from pydantic_ai.exceptions import ModelRetry, UnexpectedModelBehavior

agent = Agent('openai:gpt-4o', retries=3)  # retry output validation up to 3x

@agent.tool_plain
def parse_number(text: str) -> int:
    """Parse a number from user input."""
    try:
        return int(text.strip())
    except ValueError:
        raise ModelRetry(f'Could not parse {text!r} as an integer. Please provide a valid number.')
python
from pydantic_ai import Agent
from pydantic_ai.exceptions import ModelRetry, UnexpectedModelBehavior

agent = Agent('openai:gpt-4o', retries=3)  # 输出验证最多重试3次

@agent.tool_plain
def parse_number(text: str) -> int:
    """从用户输入中解析数字。"""
    try:
        return int(text.strip())
    except ValueError:
        raise ModelRetry(f'无法将{text!r}解析为整数。请提供有效的数字。')

Handle run errors:

处理运行时错误:

try: result = agent.run_sync('some prompt') except UnexpectedModelBehavior as e: print(f'Model misbehaved: {e}')

---
try: result = agent.run_sync('某个提示词') except UnexpectedModelBehavior as e: print(f'模型行为异常:{e}')

---

10. Model Reference

10. 模型参考

Model stringProvider
'openai:gpt-4o'
OpenAI
'openai:gpt-4o-mini'
OpenAI (fast/cheap)
'anthropic:claude-sonnet-4-6'
Anthropic
'anthropic:claude-haiku-4-5'
Anthropic (fast)
'google-gla:gemini-2.0-flash'
Google
'groq:llama-3.3-70b-versatile'
Groq (fast inference)
'ollama:llama3.2'
Local via Ollama

模型字符串提供商
'openai:gpt-4o'
OpenAI
'openai:gpt-4o-mini'
OpenAI(快速/低成本)
'anthropic:claude-sonnet-4-6'
Anthropic
'anthropic:claude-haiku-4-5'
Anthropic(快速)
'google-gla:gemini-2.0-flash'
Google
'groq:llama-3.3-70b-versatile'
Groq(快速推理)
'ollama:llama3.2'
通过Ollama本地运行

Common Patterns & Gotchas

常见模式与注意事项

✅ DO

✅ 建议

  • Use
    @dataclass
    for
    deps_type
    — clean, type-safe, easy to mock in tests
  • Use
    agent.run_sync()
    in scripts,
    await agent.run()
    in async apps
  • Access deps via
    ctx.deps
    inside tools/instructions
  • Write descriptive docstrings on tools — they're the LLM's only description
  • Use
    output_type=YourPydanticModel
    for validated structured data
  • Use
    message_history=result.new_messages()
    for multi-turn conversations
  • deps_type
    使用
    @dataclass
    ——简洁、类型安全、易于在测试中模拟
  • 在脚本中使用
    agent.run_sync()
    ,在异步应用中使用
    await agent.run()
  • 在工具/指令中通过
    ctx.deps
    访问依赖项
  • 为工具编写描述性文档字符串——这是LLM了解工具的唯一途径
  • 使用
    output_type=YourPydanticModel
    获取经过验证的结构化数据
  • 多轮对话中使用
    message_history=result.new_messages()

❌ DON'T

❌ 不建议

  • Don't use global variables for context that varies per request — use deps
  • Don't forget
    async
    on tools that do I/O (DB calls, HTTP requests)
  • Don't mix up
    @agent.tool
    (needs
    RunContext
    ) and
    @agent.tool_plain
    (no context)
  • Don't use
    system_prompt
    kwarg if you want dynamic instructions — use
    @agent.instructions
    decorator

  • 不要使用全局变量存储每个请求不同的上下文——请使用依赖项
  • 执行I/O操作(数据库调用、HTTP请求)的工具不要忘记添加
    async
  • 不要混淆
    @agent.tool
    (需要
    RunContext
    )和
    @agent.tool_plain
    (无需上下文)
  • 如果需要动态指令,不要使用
    system_prompt
    参数——请使用
    @agent.instructions
    装饰器

Reference Files

参考文档

For deeper dives, load these reference files as needed:
  • references/tools-advanced.md
    — Toolsets, deferred tools, human-in-the-loop approval
  • references/graph.md
    — Pydantic Graph for complex stateful workflows
  • references/evals.md
    — Pydantic Evals for systematic testing
  • references/models.md
    — All model providers and custom model implementation
如需深入了解,可按需加载以下参考文档:
  • references/tools-advanced.md
    — 工具集、延迟工具、人工介入审批
  • references/graph.md
    — 用于复杂有状态工作流的Pydantic Graph
  • references/evals.md
    — 用于系统化测试的Pydantic Evals
  • references/models.md
    — 所有模型提供商及自定义模型实现