📦 Pydantic Ai Common Pitfalls — PydanticAI 避坑指南

v1.0.0

避免 PydanticAI agent 开发中的常见错误和问题排查。适用于遇到错误、异常行为或审查 agent 实现时使用。

0· 106·1 当前·1 累计
anderskev 头像by @anderskev (Kevin Anderson)·MIT-0
下载技能包
License
MIT-0
最后更新
2026/3/20
0
安全扫描
VirusTotal
无害
查看报告
OpenClaw
安全
high confidence
该技能是一个仅提供指令的 PydanticAI agent 故障排查指南;其内容、缺少安装包以及未请求凭据与所述目的相符。
评估建议
这是一个只读的故障排查指南,似乎内部一致。安装前:请尽可能验证技能来源,自己查看 SKILL.md(包含示例但无可执行文件),除非完全理解为何需要,否则不要向技能提供敏感凭据。由于其涉及模型 API 密钥作为调试的一部分,仅向可信系统提供最低权限的 API 密钥。如需额外保证,请向技能作者/来源请求或选择有可验证主页或仓库的技能。...
详细分析 ▾
用途与能力
名称和描述(调试 PydanticAI agent)与 SKILL.md 内容匹配:包含 RunContext、deps、sync/async、流式传输、输出类型和模型配置的示例、常见错误和修复方法。
指令范围
SKILL.md 包含的代码示例和指导仅限于 PydanticAI 调试。它引用了典型的项目如 OPENAI_API_KEY 作为缺少 API 密钥的示例,但不指导读取无关文件、扫描系统状态或向意外端点发送数据。
安装机制
无安装规范或代码文件;这是纯指令式的,不会向磁盘写入代码或下载外部工件。
凭证需求
该技能声明不需要环境变量或凭据。对 OPENAI_API_KEY 的示例引用适合用于模型身份验证故障排查,而不是请求无关的密钥。
持久化与权限
always 为 false,没有安装逻辑或配置修改。该技能不请求持久存在或提升权限。
安全有层次,运行前请审查代码。

License

MIT-0

可自由使用、修改和再分发,无需署名。

运行时依赖

无特殊依赖

版本

latestv1.0.02026/3/20

初始版本:PydanticAI agent 开发常见错误和解决方案参考指南。- 记录了 @agent.tool 和 @agent.tool_plain 装饰器错误,展示了正确和错误的 RunContext 使用方式。- 解释了工具注册的正确和错误模式,特别是在 Agent(tools=[...]) 中使用原始函数时。- 强调了依赖类型不匹配、输出类型验证问题、async/sync 错误和流式传输陷阱。- 概述了常见的模型配置错误(例如 API 密钥问题、无效的模型字符串)。- 提供了调试技巧,包括追踪、捕获消息和检查响应。- 包含常见错误消息表,附带原因和修复方法。

无害

安装命令

点击复制
官方npx clawhub@latest install pydantic-ai-common-pitfalls
镜像加速npx clawhub@latest install pydantic-ai-common-pitfalls --registry https://cn.longxiaskill.com

技能文档

工具装饰器错误

错误:在 tool_plain 中使用 RunContext

# 错误:tool_plain 中不允许使用 RunContext
@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

修复:如果需要上下文,请使用 @agent.tool

@agent.tool
async def good_tool(ctx: RunContext[MyDeps]) -> str:
    return "works"

错误:tool 中缺少 RunContext

# 错误:第一个参数必须是 RunContext
@agent.tool
def bad_tool(user_id: int) -> str:
    return "oops"
# UserError: First parameter of tools that take context must be annotated with RunContext[...]

修复:添加 RunContext 作为第一个参数:

@agent.tool
def good_tool(ctx: RunContext[MyDeps], user_id: int) -> str:
    return "works"

错误:RunContext 不是第一个参数

# 错误:RunContext 必须是第一个参数
@agent.tool
def bad_tool(user_id: int, ctx: RunContext[MyDeps]) -> str:
    return "oops"

修复:RunContext 必须始终是第一个参数。

有效模式(不是错误)

原始函数工具注册

以下模式是有效的,并且受 pydantic-ai 支持:

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)

# 有效:将原始函数传递给 Agent(tools=[...]) agent = Agent( 'openai:gpt-4o', deps_type=MyDeps, tools=[search_db, get_user] # RunContext 从签名中检测 )

为什么这样有效: PydanticAI 检查函数签名。如果第一个参数是 RunContext[T],它被视为上下文感知工具。不需要装饰器。

参考: https://ai.pydantic.dev/agents/#registering-tools-via-the-tools-argument

不要标记 将带有 RunContext 签名的函数传递给 Agent(tools=[...]) 的代码。这等同于使用 @agent.tool,并且有明确文档说明。

依赖类型不匹配

错误:运行时缺少 deps

agent = Agent('openai:gpt-4o', deps_type=MyDeps)
# 错误:需要 deps 但未提供
result = agent.run_sync('Hello')  # 缺少 deps!

修复:设置 deps_type 时始终提供 deps:

result = agent.run_sync('Hello', deps=MyDeps(...))

错误的 deps 类型

@dataclass
class AppDeps:
    db: Database

@dataclass class WrongDeps: api: ApiClient

agent = Agent('openai:gpt-4o', deps_type=AppDeps) # 类型错误:WrongDeps != AppDeps result = agent.run_sync('Hello', deps=WrongDeps(...))

输出类型问题

Pydantic 验证失败

class Response(BaseModel):
    count: int
    items: list[str]

agent = Agent('openai:gpt-4o', output_type=Response) result = agent.run_sync('List items') # 如果 LLM 返回错误结构可能会失败

修复:增加重试次数或改进提示:

agent = Agent(
    'openai:gpt-4o',
    output_type=Response,
    retries=3,  # 更多尝试
    instructions='Return JSON with count (int) and items (list of strings).'
)

复杂的嵌套类型

# 可能会导致某些模型的 schema 问题
class Complex(BaseModel):
    nested: dict[str, list[tuple[int, str]]]

修复:简化或使用中间模型:

class Item(BaseModel):
    id: int
    name: str

class Simple(BaseModel): items: list[Item]

Async vs Sync 错误

错误:在同步上下文中调用 async

# 错误:无法在同步函数中 await
def handler():
    result = await agent.run('Hello')  # SyntaxError!

修复:使用 run_sync 或使 handler 变为 async:

def handler():
    result = agent.run_sync('Hello')

# 或 async def handler(): result = await agent.run('Hello')

错误:在 async 工具中阻塞

@agent.tool
async def slow_tool(ctx: RunContext[Deps]) -> str:
    time.sleep(5)  # 错误:阻塞事件循环!
    return "done"

修复:使用 async I/O:

@agent.tool
async def slow_tool(ctx: RunContext[Deps]) -> str:
    await asyncio.sleep(5)  # 正确
    return "done"

模型配置错误

缺少 API 密钥

# 错误:未设置 OPENAI_API_KEY
agent = Agent('openai:gpt-4o')
result = agent.run_sync('Hello')
# ModelAPIError: Authentication failed

修复:设置环境变量或使用 defer_model_check:

# 用于测试
agent = Agent('openai:gpt-4o', defer_model_check=True)
with agent.override(model=TestModel()):
    result = agent.run_sync('Hello')

无效的模型字符串

# 错误:未知提供者
agent = Agent('unknown:model')
# ValueError: Unknown model provider

修复:使用有效的 provider:model 格式。

流式传输问题

错误:在流完成前使用 result

async with agent.run_stream('Hello') as response:
    # 不要在流完成前访问 .output
    print(response.output)  # 可能不完整!
    # 正确:在上下文管理器后访问
    print(response.output)  # 完整结果

错误:不迭代流

async with agent.run_stream('Hello') as response:
    pass  # 从未使用!
    # 流从未被读取 - 输出可能不完整

修复:始终消费流:

async with agent.run_stream('Hello') as response:
    async for chunk in response.stream_output():
        print(chunk, end='')

工具返回问题

错误:返回不可序列化对象

@agent.tool_plain
def bad_return() -> object:
    return CustomObject()  # 无法序列化!

修复:返回可序列化类型(str、dict、Pydantic 模型):

@agent.tool_plain
def good_return() -> dict:
    return {"key": "value"}

调试技巧

启用追踪

import logfire

logfire.configure() logfire.instrument_pydantic_ai()

# 或按 agent agent = Agent('openai:gpt-4o', instrument=True)

捕获消息

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)

检查模型响应

result = agent.run_sync('Hello')
print(result.all_messages())  # 完整消息历史
print(result.response)        # 最后模型响应
print(result.usage())         # token 使用量

常见错误消息

错误原因修复
First parameter... RunContext@agent.tool 缺少 ctx添加 ctx: RunContext[...]
RunContext... only... context@agent.tool_plain 有 ctx移除 ctx 或使用 @agent.tool
Unknown model provider无效的模型字符串使用有效的 provider:model
ModelAPIErrorAPI 认证/配额检查 API 密钥、限额
RetryPromptPart in messages验证失败检查 output_type,增加重试次数
数据来源ClawHub ↗ · 中文优化:龙虾技能库