pydantic-ai-tool-system
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePydanticAI 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)undefinedCritical Rules
关键规则
- @agent.tool: First parameter MUST be
RunContext[DepsType] - @agent.tool_plain: MUST NOT have parameter
RunContext - Docstrings: Required for LLM to understand tool purpose
- Google-style docstrings: Used for parameter descriptions
- @agent.tool:第一个参数必须是
RunContext[DepsType] - @agent.tool_plain:绝对不能有参数
RunContext - 文档字符串:是LLM理解工具用途的必需项
- 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
undefinedString (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://...")])
undefinedfrom pydantic_ai import ToolReturn, ImageUrl
@agent.tool_plain
def get_image() -> ToolReturn:
return ToolReturn(content=[ImageUrl(url="https://...")])
undefinedAccessing 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, CombinedToolsetCreate 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])
undefinedall_tools = CombinedToolset([db_tools, api_tools])
undefinedCommon 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
undefinedAsync (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