pydantic-ai-tool-system

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

PydanticAI Tool System

PydanticAI 工具系统

Tool Registration

工具注册

Two decorators based on whether you need context:
python
from pydantic_ai import Agent, RunContext

agent = Agent('openai:gpt-4o')
根据是否需要上下文,提供两种装饰器:
python
from pydantic_ai import Agent, RunContext

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

@agent.tool - First param MUST be RunContext

@agent.tool - 第一个参数必须是RunContext

@agent.tool async def get_user_data(ctx: RunContext[MyDeps], user_id: int) -> str: """Get user data from database.
Args:
    ctx: The run context with dependencies.
    user_id: The user's ID.
"""
return await ctx.deps.db.get_user(user_id)
@agent.tool async def get_user_data(ctx: RunContext[MyDeps], user_id: int) -> str: """从数据库获取用户数据。
参数:
    ctx: 包含依赖项的运行上下文。
    user_id: 用户的ID。
"""
return await ctx.deps.db.get_user(user_id)

@agent.tool_plain - NO context parameter allowed

@agent.tool_plain - 不允许有context参数

@agent.tool_plain def calculate_total(prices: list[float]) -> float: """Calculate total price.
Args:
    prices: List of prices to sum.
"""
return sum(prices)
undefined
@agent.tool_plain def calculate_total(prices: list[float]) -> float: """计算总价。
参数:
    prices: 需要求和的价格列表。
"""
return sum(prices)
undefined

Critical Rules

关键规则

  1. @agent.tool: First parameter MUST be
    RunContext[DepsType]
  2. @agent.tool_plain: MUST NOT have
    RunContext
    parameter
  3. Docstrings: Required for LLM to understand tool purpose
  4. Google-style docstrings: Used for parameter descriptions
  1. @agent.tool:第一个参数必须是
    RunContext[DepsType]
  2. @agent.tool_plain:绝对不能有
    RunContext
    参数
  3. 文档字符串:是LLM理解工具用途的必需项
  4. Google风格文档字符串:用于参数描述

Docstring Formats

文档字符串格式

Google style (default):
python
@agent.tool_plain
async def search(query: str, limit: int = 10) -> list[str]:
    """Search for items.

    Args:
        query: The search query.
        limit: Maximum results to return.
    """
Sphinx style:
python
@agent.tool_plain(docstring_format='sphinx')
async def search(query: str) -> list[str]:
    """Search for items.

    :param query: The search query.
    """
Google风格(默认):
python
@agent.tool_plain
async def search(query: str, limit: int = 10) -> list[str]:
    """搜索项目。

    参数:
        query: 搜索关键词。
        limit: 返回的最大结果数。
    """
Sphinx风格:
python
@agent.tool_plain(docstring_format='sphinx')
async def search(query: str) -> list[str]:
    """搜索项目。

    :param query: 搜索关键词。
    """

Tool Return Types

工具返回类型

Tools can return various types:
python
undefined
工具可以返回多种类型:
python
undefined

String (direct)

字符串(直接返回)

@agent.tool_plain def get_info() -> str: return "Some information"
@agent.tool_plain def get_info() -> str: return "Some information"

Pydantic model (serialized to JSON)

Pydantic模型(序列化为JSON)

@agent.tool_plain def get_user() -> User: return User(name="John", age=30)
@agent.tool_plain def get_user() -> User: return User(name="John", age=30)

Dict (serialized to JSON)

字典(序列化为JSON)

@agent.tool_plain def get_data() -> dict[str, Any]: return {"key": "value"}
@agent.tool_plain def get_data() -> dict[str, Any]: return {"key": "value"}

ToolReturn for custom content types

使用ToolReturn返回自定义内容类型

from pydantic_ai import ToolReturn, ImageUrl
@agent.tool_plain def get_image() -> ToolReturn: return ToolReturn(content=[ImageUrl(url="https://...")])
undefined
from pydantic_ai import ToolReturn, ImageUrl
@agent.tool_plain def get_image() -> ToolReturn: return ToolReturn(content=[ImageUrl(url="https://...")])
undefined

Accessing Context

访问上下文

RunContext provides:
python
@agent.tool
async def my_tool(ctx: RunContext[MyDeps]) -> str:
    # Dependencies
    db = ctx.deps.db
    api = ctx.deps.api_client

    # Model info
    model_name = ctx.model.model_name

    # Usage tracking
    tokens_used = ctx.usage.total_tokens

    # Retry info
    attempt = ctx.retry  # Current retry attempt (0-based)
    max_retries = ctx.max_retries

    # Message history
    messages = ctx.messages

    return "result"
RunContext提供以下功能:
python
@agent.tool
async def my_tool(ctx: RunContext[MyDeps]) -> str:
    # 依赖项
    db = ctx.deps.db
    api = ctx.deps.api_client

    # 模型信息
    model_name = ctx.model.model_name

    # 使用跟踪
    tokens_used = ctx.usage.total_tokens

    # 重试信息
    attempt = ctx.retry  # 当前重试次数(从0开始)
    max_retries = ctx.max_retries

    # 消息历史
    messages = ctx.messages

    return "result"

Tool Prepare Functions

工具准备函数

Dynamically modify tools per-request:
python
from pydantic_ai.tools import ToolDefinition

async def prepare_tools(
    ctx: RunContext[MyDeps],
    tool_defs: list[ToolDefinition]
) -> list[ToolDefinition]:
    """Filter or modify tools based on context."""
    if ctx.deps.user_role != 'admin':
        # Hide admin tools from non-admins
        return [t for t in tool_defs if not t.name.startswith('admin_')]
    return tool_defs

agent = Agent('openai:gpt-4o', prepare_tools=prepare_tools)
可根据请求动态修改工具:
python
from pydantic_ai.tools import ToolDefinition

async def prepare_tools(
    ctx: RunContext[MyDeps],
    tool_defs: list[ToolDefinition]
) -> list[ToolDefinition]:
    """根据上下文过滤或修改工具。"""
    if ctx.deps.user_role != 'admin':
        # 对非管理员隐藏管理员工具
        return [t for t in tool_defs if not t.name.startswith('admin_')]
    return tool_defs

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

Toolsets

工具集

Group and compose tools:
python
from pydantic_ai import FunctionToolset, CombinedToolset
对工具进行分组和组合:
python
from pydantic_ai import FunctionToolset, CombinedToolset

Create a toolset

创建工具集

db_tools = FunctionToolset()
@db_tools.tool def query_users(name: str) -> list[dict]: """Query users by name.""" ...
@db_tools.tool def update_user(id: int, data: dict) -> bool: """Update user data.""" ...
db_tools = FunctionToolset()
@db_tools.tool def query_users(name: str) -> list[dict]: """根据名称查询用户。""" ...
@db_tools.tool def update_user(id: int, data: dict) -> bool: """更新用户数据。""" ...

Use in agent

在Agent中使用

agent = Agent('openai:gpt-4o', toolsets=[db_tools])
agent = Agent('openai:gpt-4o', toolsets=[db_tools])

Combine toolsets

组合工具集

all_tools = CombinedToolset([db_tools, api_tools])
undefined
all_tools = CombinedToolset([db_tools, api_tools])
undefined

Common Mistakes

常见错误

Wrong: Context in tool_plain

错误示例:tool_plain中使用上下文

python
@agent.tool_plain
async def bad_tool(ctx: RunContext[MyDeps]) -> str:  # ERROR!
    ...
python
@agent.tool_plain
async def bad_tool(ctx: RunContext[MyDeps]) -> str:  # 错误!
    ...

Wrong: Missing context in tool

错误示例:tool中缺少上下文

python
@agent.tool
def bad_tool(user_id: int) -> str:  # ERROR!
    ...
python
@agent.tool
def bad_tool(user_id: int) -> str:  # 错误!
    ...

Wrong: Context not first parameter

错误示例:上下文不是第一个参数

python
@agent.tool
def bad_tool(user_id: int, ctx: RunContext[MyDeps]) -> str:  # ERROR!
    ...
python
@agent.tool
def bad_tool(user_id: int, ctx: RunContext[MyDeps]) -> str:  # 错误!
    ...

Async vs Sync

异步与同步

Both work, but async is preferred for I/O:
python
undefined
两种方式都支持,但异步更适合I/O操作:
python
undefined

Async (preferred for I/O operations)

异步(推荐用于I/O操作)

@agent.tool async def fetch_data(ctx: RunContext[Deps]) -> str: return await ctx.deps.client.get('/data')
@agent.tool async def fetch_data(ctx: RunContext[Deps]) -> str: return await ctx.deps.client.get('/data')

Sync (fine for CPU-bound operations)

同步(适用于CPU密集型操作)

@agent.tool_plain def compute(x: int, y: int) -> int: return x * y
undefined
@agent.tool_plain def compute(x: int, y: int) -> int: return x * y
undefined