pydantic-ai-common-pitfalls
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePydanticAI Common Pitfalls and Debugging
PydanticAI常见陷阱与调试
Tool Decorator Errors
工具装饰器错误
Wrong: RunContext in tool_plain
错误示例:tool_plain中使用RunContext
python
undefinedpython
undefinedERROR: RunContext not allowed in tool_plain
ERROR: RunContext not allowed in tool_plain
@agent.tool_plain
async def bad_tool(ctx: RunContext[MyDeps]) -> str:
return "oops"
@agent.tool_plain
async def bad_tool(ctx: RunContext[MyDeps]) -> str:
return "oops"
UserError: RunContext annotations can only be used with tools that take context
UserError: RunContext annotations can only be used with tools that take context
**Fix**: Use `@agent.tool` if you need context:
```python
@agent.tool
async def good_tool(ctx: RunContext[MyDeps]) -> str:
return "works"
**修复方案**:如果需要上下文,请使用`@agent.tool`:
```python
@agent.tool
async def good_tool(ctx: RunContext[MyDeps]) -> str:
return "works"Wrong: Missing RunContext in tool
错误示例:tool中缺少RunContext
python
undefinedpython
undefinedERROR: First param must be RunContext
ERROR: First param must be RunContext
@agent.tool
def bad_tool(user_id: int) -> str:
return "oops"
@agent.tool
def bad_tool(user_id: int) -> str:
return "oops"
UserError: First parameter of tools that take context must be annotated with RunContext[...]
UserError: First parameter of tools that take context must be annotated with RunContext[...]
**Fix**: Add RunContext as first parameter:
```python
@agent.tool
def good_tool(ctx: RunContext[MyDeps], user_id: int) -> str:
return "works"
**修复方案**:添加RunContext作为第一个参数:
```python
@agent.tool
def good_tool(ctx: RunContext[MyDeps], user_id: int) -> str:
return "works"Wrong: RunContext not first
错误示例:RunContext未作为第一个参数
python
undefinedpython
undefinedERROR: RunContext must be first parameter
ERROR: RunContext must be first parameter
@agent.tool
def bad_tool(user_id: int, ctx: RunContext[MyDeps]) -> str:
return "oops"
**Fix**: RunContext must always be the first parameter.@agent.tool
def bad_tool(user_id: int, ctx: RunContext[MyDeps]) -> str:
return "oops"
**修复方案**:RunContext必须始终作为第一个参数。Valid Patterns (Not Errors)
有效模式(非错误)
Raw Function Tool Registration
原始函数工具注册
The following pattern IS valid and supported by pydantic-ai:
python
from pydantic_ai import Agent, RunContext
async def search_db(ctx: RunContext[MyDeps], query: str) -> list[dict]:
"""Search the database."""
return await ctx.deps.db.search(query)
async def get_user(ctx: RunContext[MyDeps], user_id: int) -> dict:
"""Get user by ID."""
return await ctx.deps.db.get_user(user_id)以下模式是有效的,且受pydantic-ai支持:
python
from pydantic_ai import Agent, RunContext
async def search_db(ctx: RunContext[MyDeps], query: str) -> list[dict]:
"""Search the database."""
return await ctx.deps.db.search(query)
async def get_user(ctx: RunContext[MyDeps], user_id: int) -> dict:
"""Get user by ID."""
return await ctx.deps.db.get_user(user_id)Valid: Pass raw functions to Agent(tools=[...])
Valid: Pass raw functions to Agent(tools=[...])
agent = Agent(
'openai:gpt-4o',
deps_type=MyDeps,
tools=[search_db, get_user] # RunContext detected from signature
)
**Why this works:** PydanticAI inspects function signatures. If the first parameter is `RunContext[T]`, it's treated as a context-aware tool. No decorator required.
**Reference:** https://ai.pydantic.dev/agents/#registering-tools-via-the-tools-argument
**Do NOT flag** code that passes functions with `RunContext` signatures to `Agent(tools=[...])`. This is equivalent to using `@agent.tool` and is explicitly documented.agent = Agent(
'openai:gpt-4o',
deps_type=MyDeps,
tools=[search_db, get_user] # RunContext detected from signature
)
**为什么有效**:PydanticAI会检查函数签名。如果第一个参数是`RunContext[T]`,它会被视为支持上下文的工具,无需装饰器。
**参考文档**:https://ai.pydantic.dev/agents/#registering-tools-via-the-tools-argument
**请勿标记**将带有`RunContext`签名的函数传入`Agent(tools=[...])`的代码。这与使用`@agent.tool`等效,且是官方文档明确说明的用法。Dependency Type Mismatches
依赖类型不匹配
Wrong: Missing deps at runtime
错误示例:运行时缺少依赖
python
agent = Agent('openai:gpt-4o', deps_type=MyDeps)python
agent = Agent('openai:gpt-4o', deps_type=MyDeps)ERROR: deps required but not provided
ERROR: deps required but not provided
result = agent.run_sync('Hello') # Missing deps!
**Fix**: Always provide deps when deps_type is set:
```python
result = agent.run_sync('Hello', deps=MyDeps(...))result = agent.run_sync('Hello') # Missing deps!
**修复方案**:当设置了deps_type时,务必提供依赖:
```python
result = agent.run_sync('Hello', deps=MyDeps(...))Wrong: Wrong deps type
错误示例:依赖类型错误
python
@dataclass
class AppDeps:
db: Database
@dataclass
class WrongDeps:
api: ApiClient
agent = Agent('openai:gpt-4o', deps_type=AppDeps)python
@dataclass
class AppDeps:
db: Database
@dataclass
class WrongDeps:
api: ApiClient
agent = Agent('openai:gpt-4o', deps_type=AppDeps)Type error: WrongDeps != AppDeps
Type error: WrongDeps != AppDeps
result = agent.run_sync('Hello', deps=WrongDeps(...))
undefinedresult = agent.run_sync('Hello', deps=WrongDeps(...))
undefinedOutput Type Issues
输出类型问题
Pydantic validation fails
Pydantic验证失败
python
class Response(BaseModel):
count: int
items: list[str]
agent = Agent('openai:gpt-4o', output_type=Response)
result = agent.run_sync('List items')python
class Response(BaseModel):
count: int
items: list[str]
agent = Agent('openai:gpt-4o', output_type=Response)
result = agent.run_sync('List items')May fail if LLM returns wrong structure
May fail if LLM returns wrong structure
**Fix**: Increase retries or improve prompt:
```python
agent = Agent(
'openai:gpt-4o',
output_type=Response,
retries=3, # More attempts
instructions='Return JSON with count (int) and items (list of strings).'
)
**修复方案**:增加重试次数或优化提示词:
```python
agent = Agent(
'openai:gpt-4o',
output_type=Response,
retries=3, # 更多尝试次数
instructions='Return JSON with count (int) and items (list of strings).'
)Complex nested types
复杂嵌套类型
python
undefinedpython
undefinedMay cause schema issues with some models
May cause schema issues with some models
class Complex(BaseModel):
nested: dict[str, list[tuple[int, str]]]
**Fix**: Simplify or use intermediate models:
```python
class Item(BaseModel):
id: int
name: str
class Simple(BaseModel):
items: list[Item]class Complex(BaseModel):
nested: dict[str, list[tuple[int, str]]]
**修复方案**:简化类型或使用中间模型:
```python
class Item(BaseModel):
id: int
name: str
class Simple(BaseModel):
items: list[Item]Async vs Sync Mistakes
异步与同步使用错误
Wrong: Calling async in sync context
错误示例:在同步上下文调用异步方法
python
undefinedpython
undefinedERROR: Can't await in sync function
ERROR: Can't await in sync function
def handler():
result = await agent.run('Hello') # SyntaxError!
**Fix**: Use run_sync or make handler async:
```python
def handler():
result = agent.run_sync('Hello')def handler():
result = await agent.run('Hello') # SyntaxError!
**修复方案**:使用run_sync或将handler改为异步函数:
```python
def handler():
result = agent.run_sync('Hello')Or
或者
async def handler():
result = await agent.run('Hello')
undefinedasync def handler():
result = await agent.run('Hello')
undefinedWrong: Blocking in async tools
错误示例:在异步工具中使用阻塞操作
python
@agent.tool
async def slow_tool(ctx: RunContext[Deps]) -> str:
time.sleep(5) # WRONG: Blocks event loop!
return "done"Fix: Use async I/O:
python
@agent.tool
async def slow_tool(ctx: RunContext[Deps]) -> str:
await asyncio.sleep(5) # Correct
return "done"python
@agent.tool
async def slow_tool(ctx: RunContext[Deps]) -> str:
time.sleep(5) # WRONG: Blocks event loop!
return "done"修复方案:使用异步I/O:
python
@agent.tool
async def slow_tool(ctx: RunContext[Deps]) -> str:
await asyncio.sleep(5) # Correct
return "done"Model Configuration Errors
模型配置错误
Missing API key
缺少API密钥
python
undefinedpython
undefinedERROR: OPENAI_API_KEY not set
ERROR: OPENAI_API_KEY not set
agent = Agent('openai:gpt-4o')
result = agent.run_sync('Hello')
agent = Agent('openai:gpt-4o')
result = agent.run_sync('Hello')
ModelAPIError: Authentication failed
ModelAPIError: Authentication failed
**Fix**: Set environment variable or use defer_model_check:
```python
**修复方案**:设置环境变量或使用defer_model_check:
```pythonFor testing
用于测试
agent = Agent('openai:gpt-4o', defer_model_check=True)
with agent.override(model=TestModel()):
result = agent.run_sync('Hello')
undefinedagent = Agent('openai:gpt-4o', defer_model_check=True)
with agent.override(model=TestModel()):
result = agent.run_sync('Hello')
undefinedInvalid model string
无效的模型字符串
python
undefinedpython
undefinedERROR: Unknown provider
ERROR: Unknown provider
agent = Agent('unknown:model')
agent = Agent('unknown:model')
ValueError: Unknown model provider
ValueError: Unknown model provider
**Fix**: Use valid provider:model format.
**修复方案**:使用有效的provider:model格式。Streaming Issues
流式输出问题
Wrong: Using result before stream completes
错误示例:在流完成前访问结果
python
async with agent.run_stream('Hello') as response:
# DON'T access .output before streaming completes
print(response.output) # May be incomplete!python
async with agent.run_stream('Hello') as response:
# DON'T access .output before streaming completes
print(response.output) # May be incomplete!Correct: access after context manager
Correct: access after context manager
print(response.output) # Complete result
undefinedprint(response.output) # Complete result
undefinedWrong: Not iterating stream
错误示例:未迭代流内容
python
async with agent.run_stream('Hello') as response:
pass # Never consumed!python
async with agent.run_stream('Hello') as response:
pass # Never consumed!Stream was never read - output may be incomplete
Stream was never read - output may be incomplete
**Fix**: Always consume the stream:
```python
async with agent.run_stream('Hello') as response:
async for chunk in response.stream_output():
print(chunk, end='')
**修复方案**:务必消费流内容:
```python
async with agent.run_stream('Hello') as response:
async for chunk in response.stream_output():
print(chunk, end='')Tool Return Issues
工具返回值问题
Wrong: Returning non-serializable
错误示例:返回不可序列化的对象
python
@agent.tool_plain
def bad_return() -> object:
return CustomObject() # Can't serialize!Fix: Return serializable types (str, dict, Pydantic model):
python
@agent.tool_plain
def good_return() -> dict:
return {"key": "value"}python
@agent.tool_plain
def bad_return() -> object:
return CustomObject() # Can't serialize!修复方案:返回可序列化类型(字符串、字典、Pydantic模型):
python
@agent.tool_plain
def good_return() -> dict:
return {"key": "value"}Debugging Tips
调试技巧
Enable tracing
启用追踪
python
import logfire
logfire.configure()
logfire.instrument_pydantic_ai()python
import logfire
logfire.configure()
logfire.instrument_pydantic_ai()Or per-agent
或针对单个Agent
agent = Agent('openai:gpt-4o', instrument=True)
undefinedagent = Agent('openai:gpt-4o', instrument=True)
undefinedCapture messages
捕获消息
python
from pydantic_ai import capture_run_messages
with capture_run_messages() as messages:
result = agent.run_sync('Hello')
for msg in messages:
print(type(msg).__name__, msg)python
from pydantic_ai import capture_run_messages
with capture_run_messages() as messages:
result = agent.run_sync('Hello')
for msg in messages:
print(type(msg).__name__, msg)Check model responses
检查模型响应
python
result = agent.run_sync('Hello')
print(result.all_messages()) # Full message history
print(result.response) # Last model response
print(result.usage()) # Token usagepython
result = agent.run_sync('Hello')
print(result.all_messages()) # 完整消息历史
print(result.response) # 最后一次模型响应
print(result.usage()) # Token使用情况Common Error Messages
常见错误信息
| Error | Cause | Fix |
|---|---|---|
| @agent.tool missing ctx | Add |
| @agent.tool_plain has ctx | Remove ctx or use @agent.tool |
| Invalid model string | Use valid |
| API auth/quota | Check API key, limits |
| Validation failed | Check output_type, increase retries |
| 错误信息 | 原因 | 修复方案 |
|---|---|---|
| @agent.tool 缺少ctx参数 | 添加 |
| @agent.tool_plain 中使用了ctx | 移除ctx或改用@agent.tool |
| 无效的模型字符串 | 使用有效的 |
| API 认证/配额问题 | 检查API密钥和使用限制 |
消息中出现 | 验证失败 | 检查output_type,增加重试次数 |