pydantic-ai-common-pitfalls

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

PydanticAI Common Pitfalls and Debugging

PydanticAI常见陷阱与调试

Tool Decorator Errors

工具装饰器错误

Wrong: RunContext in tool_plain

错误示例:tool_plain中使用RunContext

python
undefined
python
undefined

ERROR: 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
undefined
python
undefined

ERROR: 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
undefined
python
undefined

ERROR: 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(...))
undefined
result = agent.run_sync('Hello', deps=WrongDeps(...))
undefined

Output 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
undefined
python
undefined

May 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
undefined
python
undefined

ERROR: 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')
undefined
async def handler(): result = await agent.run('Hello')
undefined

Wrong: 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
undefined
python
undefined

ERROR: 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:
```python

For testing

用于测试

agent = Agent('openai:gpt-4o', defer_model_check=True) with agent.override(model=TestModel()): result = agent.run_sync('Hello')
undefined
agent = Agent('openai:gpt-4o', defer_model_check=True) with agent.override(model=TestModel()): result = agent.run_sync('Hello')
undefined

Invalid model string

无效的模型字符串

python
undefined
python
undefined

ERROR: 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
undefined
print(response.output) # Complete result
undefined

Wrong: 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)
undefined
agent = Agent('openai:gpt-4o', instrument=True)
undefined

Capture 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 usage
python
result = agent.run_sync('Hello')
print(result.all_messages())  # 完整消息历史
print(result.response)  # 最后一次模型响应
print(result.usage())  # Token使用情况

Common Error Messages

常见错误信息

ErrorCauseFix
First parameter... RunContext
@agent.tool missing ctxAdd
ctx: RunContext[...]
RunContext... only... context
@agent.tool_plain has ctxRemove ctx or use @agent.tool
Unknown model provider
Invalid model stringUse valid
provider:model
ModelAPIError
API auth/quotaCheck API key, limits
RetryPromptPart
in messages
Validation failedCheck output_type, increase retries
错误信息原因修复方案
First parameter... RunContext
@agent.tool 缺少ctx参数添加
ctx: RunContext[...]
RunContext... only... context
@agent.tool_plain 中使用了ctx移除ctx或改用@agent.tool
Unknown model provider
无效的模型字符串使用有效的
provider:model
格式
ModelAPIError
API 认证/配额问题检查API密钥和使用限制
消息中出现
RetryPromptPart
验证失败检查output_type,增加重试次数