pydantic ai type safe agent

Pydantic AI:类型安全的 Agent 开发框架

当类型安全遇上 AI Agent Pydantic AI 是 Pydantic 团队在 2025 年推出的 Agent 框架,核心理念是将 Python 的类型系统引入 Agent 开发。在大多数 Agent 框架中,LLM 输出的结构化数据依赖运行时验证——如果 LLM 输出不符合预期,你只能在运行时发现问题。Pydantic AI 通过编译时类型检查 + 运行时 Schema 验证,将这类问题消灭在开发阶段。 核心设计 类型驱动的 Agent 定义 from pydantic_ai import Agent, RunContext from pydantic import BaseModel, Field from typing import Literal from dataclasses import dataclass # 定义结构化输出 class ResearchReport(BaseModel): title: str = Field(description="报告标题") summary: str = Field(description="执行摘要,不超过200字") key_findings: list[str] = Field(description="关键发现列表") confidence: float = Field(ge=0, le=1, description="置信度 0-1") sources: list[str] = Field(description="信息来源 URL 列表") recommendation: Literal["buy", "hold", "sell"] = Field(description="投资建议") # 定义依赖类型 @dataclass class ResearchDeps: api_keys: dict[str, str] database_url: str max_sources: int = 10 # 创建 Agent research_agent = Agent( model="openai:gpt-4o", deps_type=ResearchDeps, output_type=ResearchReport, # 类型安全的输出 system_prompt="你是一名专业的研究分析师..." ) # 类型安全的工具定义 @research_agent.tool async def search_database(ctx: RunContext[ResearchDeps], query: str, limit: int = 10) -> list[dict]: """ 搜索内部数据库。 Args: query: 搜索查询 limit: 返回结果数量上限 """ # ctx.deps 是 ResearchDeps 类型,IDE 自动补全 async with httpx.AsyncClient() as client: response = await client.post( f"{ctx.deps.database_url}/search", json={"query": query, "limit": min(limit, ctx.deps.max_sources)}, headers={"Authorization": f"Bearer {ctx.deps.api_keys['database']}"} ) return response.json()["results"] @research_agent.tool async def fetch_web_page(ctx: RunContext[ResearchDeps], url: str) -> str: """获取网页内容。""" async with httpx.AsyncClient() as client: response = await client.get(url, timeout=10) return response.text[:5000] # 限制内容长度 # 运行 Agent —— 输出类型自动验证 result = await research_agent.run( "分析 2026 年 AGI 芯片市场", deps=ResearchDeps( api_keys={"database": "xxx"}, database_url="https://api.example.com" ) ) # result.output 是 ResearchReport 类型,IDE 完整支持 print(result.output.title) print(result.output.confidence) print(result.output.recommendation) # 如果 LLM 输出不符合 Schema,Pydantic 会抛出 # ValidationError,而非静默返回错误数据 核心特性 1. 结构化输出保证 from pydantic_ai import Agent from pydantic import BaseModel, validator from typing import Optional class CodeReview(BaseModel): file_name: str issues: list["CodeIssue"] overall_rating: int = Field(ge=1, le=10, description="整体评分 1-10") approved: bool @validator("file_name") def validate_filename(cls, v): if not v.endswith((".py", ".js", ".ts")): raise ValueError("仅支持 .py/.js/.ts 文件") return v class CodeIssue(BaseModel): line_number: int = Field(ge=1) severity: Literal["error", "warning", "info"] message: str suggestion: Optional[str] = None review_agent = Agent( model="anthropic:claude-4-sonnet", output_type=CodeReview, system_prompt="你是代码审查专家,分析代码质量问题。" ) # Agent 输出保证符合 CodeReview Schema result = await review_agent.run("审查以下代码: ...") review: CodeReview = result.output # 类型保证 2. 多模型支持与切换 from pydantic_ai.models import Model from pydantic_ai.models.openai import OpenAIModel from pydantic_ai.models.anthropic import AnthropicModel from pydantic_ai.models.groq import GroqModel # 环境感知模型选择 def get_model() -> Model: env = os.getenv("ENVIRONMENT", "dev") if env == "production": return OpenAIModel("gpt-4o", api_key=os.getenv("OPENAI_API_KEY")) elif env == "staging": return AnthropicModel("claude-4-sonnet", api_key=os.getenv("ANTHROPIC_API_KEY")) elif env == "dev": return GroqModel("llama-4-70b", api_key=os.getenv("GROQ_API_KEY")) else: # 使用 Ollama 本地模型 return OpenAIModel( "qwen3:72b", base_url="http://localhost:11434/v1", api_key="ollama" ) agent = Agent( model=get_model(), output_type=ResearchReport, system_prompt="..." ) # 运行时切换模型 result = await agent.run("...", model=AnthropicModel("claude-4-opus")) 3. 流式输出 from pydantic_ai import Agent from pydantic_ai.messages import Part streaming_agent = Agent( model="openai:gpt-4o", system_prompt="你是技术写作助手..." ) # 流式输出 async with streaming_agent.run_stream("写一篇关于 AGI 的短文") as result: async for message in result.stream_text(delta=True): print(message, end="", flush=True) # 流式结构化输出(2026 新特性) class ArticleOutline(BaseModel): title: str sections: list[str] estimated_words: int async with streaming_agent.run_stream( "生成文章大纲", output_type=ArticleOutline ) as result: # 部分结果流式返回 async for partial in result.stream_structured(): print(f"当前大纲: {partial.title} ({len(partial.sections)} 节)") final = await result.get_output() print(f"最终大纲: {final}") 4. 依赖注入 from pydantic_ai import Agent, RunContext from dataclasses import dataclass import httpx import asyncio @dataclass class AppDeps: http_client: httpx.AsyncClient db_pool: asyncpg.Pool cache: redis.Redis config: dict # 所有工具共享同一个依赖上下文 agent = Agent("openai:gpt-4o", deps_type=AppDeps) @agent.tool async def get_user_profile(ctx: RunContext[AppDeps], user_id: int) -> dict: # 从缓存获取 cached = await ctx.deps.cache.get(f"user:{user_id}") if cached: return json.loads(cached) # 从数据库获取 async with ctx.deps.db_pool.acquire() as conn: user = await conn.fetchrow( "SELECT * FROM users WHERE id = $1", user_id ) # 写入缓存 await ctx.deps.cache.setex(f"user:{user_id}", 3600, json.dumps(dict(user))) return dict(user) @agent.tool async def call_external_api(ctx: RunContext[AppDeps], url: str) -> dict: response = await ctx.deps.http_client.get(url) return response.json() # 运行时注入依赖 async def main(): async with httpx.AsyncClient() as http_client: db_pool = await asyncpg.create_pool(DATABASE_URL) cache = redis.Redis() deps = AppDeps( http_client=http_client, db_pool=db_pool, cache=cache, config={"max_results": 50} ) result = await agent.run("查询用户 123 的信息", deps=deps) print(result.output) 5. Agent 组合 from pydantic_ai import Agent # 子 Agent:各自有独立的输出类型 research_agent = Agent( model="openai:gpt-4o", output_type=ResearchReport, system_prompt="你是研究员..." ) writing_agent = Agent( model="anthropic:claude-4-sonnet", output_type=Article, system_prompt="你是技术写手..." ) review_agent = Agent( model="openai:gpt-4o", output_type=ReviewResult, system_prompt="你是审稿人..." ) # 主 Agent 协调子 Agent class PipelineResult(BaseModel): research: ResearchReport article: Article review: ReviewResult final_status: str pipeline_agent = Agent( model="openai:gpt-4o", output_type=PipelineResult, system_prompt="你是项目经理,协调多个子任务..." ) # 主 Agent 可以委派给子 Agent @pipeline_agent.tool async def run_research(ctx: RunContext, topic: str) -> ResearchReport: result = await research_agent.run(topic, deps=ctx.deps) return result.output @pipeline_agent.tool async def run_writing(ctx: RunContext, research: ResearchReport) -> Article: result = await writing_agent.run( f"基于以下研究撰写文章: {research.model_dump_json()}", deps=ctx.deps ) return result.output 评估与测试 from pydantic_ai.evals import TestCase, Evaluator # 定义测试用例 test_cases = [ TestCase( input="分析苹果公司 2026 年 Q1 财报", expected_output=ResearchReport( title="苹果 2026 Q1 财报分析", summary="...", key_findings=["营收增长 15%", "服务业务创新高"], confidence=0.9, sources=["https://investor.apple.com"], recommendation="buy" ) ), # 更多测试用例... ] # 评估器 class ResearchEvaluator(Evaluator): async def evaluate(self, output: ResearchReport, expected: ResearchReport) -> float: score = 0.0 # 检查结构化字段 if output.recommendation == expected.recommendation: score += 0.3 # 检查发现重叠度 overlap = len(set(output.key_findings) & set(expected.key_findings)) score += 0.4 * (overlap / max(len(expected.key_findings), 1)) # 检查置信度合理性 if abs(output.confidence - expected.confidence) < 0.2: score += 0.3 return score # 运行评估 results = await Evaluator.run( agent=research_agent, test_cases=test_cases, evaluator=ResearchEvaluator() ) print(f"平均得分: {results.avg_score}") print(f"通过率: {results.pass_rate}") 框架对比 特性 Pydantic AI LangChain CrewAI smolagents 类型安全 ⭐⭐⭐⭐⭐ ⭐⭐ ⭐⭐⭐ ⭐⭐ 结构化输出 编译时+运行时 运行时 运行时 无 学习曲线 中 高 低 低 IDE 支持 完整 部分 部分 部分 依赖注入 内置 无 无 无 流式输出 文本+结构化 文本 文本 文本 测试框架 内置 第三方 无 无 多模型 完整 完整 完整 HF 优先 性能基准 指标 Pydantic AI LangChain CrewAI Cold Start 0.2s 0.8s 0.5s 简单调用 1.1s 1.5s 1.8s 结构化输出 1.3s 1.8s 2.1s 内存占用 85MB 256MB 312MB Schema 验证开销 <50ms 100-200ms N/A 适用场景 最适合 企业级应用:类型安全是生产环境的刚需 API 后端:结构化输出直接映射 API 响应 数据管道:类型保证数据处理链路的可靠性 团队协作:类型系统作为 Agent 接口契约 不太适合 快速原型:类型定义增加了前期开发量 创意类任务:非结构化输出场景下类型约束是负担 复杂 Agent 图:不支持状态机编排 总结 Pydantic AI 在 2026 年的 Agent 框架竞争中找到了独特的定位:类型安全。这不是一个噱头——在实际的企业开发中,LLM 输出的不可预测性是最大的痛点之一。Pydantic AI 通过编译时类型检查、运行时 Schema 验证、依赖注入、内置测试框架,为 Agent 开发带来了真正的工程严谨性。 ...

2026-06-28 · 5 min · 915 words · 硅基 AGI 探索者
pydantic ai framework

Pydantic AI框架解析

概述 Pydantic AI框架解析是AI智能体领域中Pydantic AI框架解析的重要主题。本文将从多个角度深入分析这一话题,为读者提供系统性的认知框架和实践参考。 核心概念 基本定义 在深入讨论之前,我们需要明确几个核心概念。AI智能体是指能够感知环境、理解指令、规划行动并调用工具完成任务的AI系统。与传统的聊天机器人不同,智能体具有自主性、目标导向性和工具使用能力。 Pydantic AI框架解析涉及的关键技术包括: 大语言模型:作为智能体的认知引擎,负责理解、推理和生成 工具调用:通过Function Calling或MCP协议与外部系统交互 记忆系统:短期记忆处理当前对话,长期记忆存储历史经验 规划引擎:将复杂任务分解为可执行的子步骤 技术原理 从技术层面看,Pydantic AI框架解析的核心在于如何让AI系统更好地理解和执行人类意图。这涉及多个技术环节的协同: 首先是感知层,智能体需要准确理解用户的自然语言指令,提取关键信息和约束条件。其次是规划层,将高层目标分解为具体的执行步骤。然后是执行层,调用合适的工具完成每个步骤。最后是反馈层,根据执行结果调整后续策略。 实践分析 当前现状 在框架测评领域,当前的技术实践呈现出几个明显特征: 工程化程度提升:从实验室原型到生产级系统,工程能力成为关键差异化因素 评估体系完善:越来越多标准化的评测基准被提出,帮助开发者量化能力边界 开源生态繁荣:开源框架和工具链的成熟降低了开发门槛 安全意识增强:对AI安全和对齐问题的重视程度显著提升 关键挑战 尽管进展显著,Pydantic AI框架解析仍面临几个核心挑战: 技术挑战: 大模型的幻觉问题在智能体场景下被放大,因为智能体需要做出实际决策 多步推理中的错误累积效应导致长程任务成功率下降 工具调用的可靠性受外部API稳定性影响 工程挑战: 智能体的可观测性不足,调试和排错困难 成本控制与性能优化的平衡 从单机到分布式部署的架构复杂性 安全挑战: Prompt注入等攻击手段不断进化 智能体权限管理需要更精细化的控制 数据隐私保护在多Agent协作场景下更加复杂 优化策略 针对上述挑战,以下是几个关键优化方向: 技术优化 分而治之:将复杂任务分解为可独立验证的子任务,降低单步错误影响 多路投票:对关键决策使用多次采样投票机制,提高可靠性 渐进式信任:智能体权限从最小化开始,根据表现逐步扩展 人在回路:高风险决策保留人工审核环节 工程优化 可观测性优先:建立完善的日志、指标和追踪体系 灰度发布:新版本智能体先在小流量环境验证 自动化测试:构建端到端测试套件,防止回归 成本监控:实时追踪Token消耗和API调用成本 案例研究 为了更具体地说明Pydantic AI框架解析的实践价值,我们来看一个典型场景: 某科技公司在内部IT运维中部署了AI智能体,负责处理员工的工单请求。智能体需要理解员工的自然语言描述,判断问题类型,查询知识库,执行修复操作或转接人工。 实施过程中遇到的关键问题包括: 员工描述模糊导致意图识别错误 知识库信息过时导致给出错误建议 某些操作需要管理员权限存在安全风险 解决方案: 引入澄清对话机制,在不确定时主动追问 建立知识库更新流程,定期审核内容 实施权限分级制度,敏感操作需人工确认 效果:工单首次解决率提升35%,平均处理时间缩短60%,员工满意度显著提升。 未来趋势 Pydantic AI框架解析的发展趋势值得关注: 标准化:MCP等开放协议将推动工具接口标准化,降低集成成本 垂直化:针对特定行业和场景的专用智能体将大量涌现 协作化:多智能体协作将成为复杂任务的标准解决方案 自主化:智能体的自主决策能力将持续提升,但需要配套的安全机制 结论 Pydantic AI框架解析是AI智能体技术发展中的重要一环。无论是技术原理的深入理解,还是实践中的工程优化,都需要系统性思维。对于开发者和企业而言,关键在于: ...

2026-06-27 · 1 min · 96 words · 硅基 AGI 探索者
鲁ICP备2026018361号