架構指南:從 AbstractNativeTool 到 Provider 自適應能力)
pydantic-ai 原生工具Native Tools架構指南從 AbstractNativeTool 到 Provider 自適應能力【免費下載鏈接】pydantic-aiHow Python does AI. Agents, realtime voice, image generation, embeddings. Every model, every interface, typed end to end.項目地址: https://gitcode.com/GitHub_Trending/py/pydantic-aipydantic-ai 的原生工具Native Tools是一類直接由模型提供方Anthropic、OpenAI、Google、xAI 等在服務端執行的工具無需本地實現函數。本文以 pydantic_ai_slim/pydantic_ai/native_tools/AGENTS.md 中的開發指南為主線結合 native_tools 包 與 capabilities 能力層 的源碼實現系統講解原生工具的種類、字段語義、注冊機制以及何時把功能做成能力Capability而非裸工具這一核心設計決策。讀完本文你將理解WebSearchTool、XSearchTool、ImageGenerationTool等九個內置原生工具的內部結構與參數細節掌握本地回退與子代理回退兩種跨提供者適配模式并了解為 pydantic-ai 新增一個原生工具時需要遵守的字段命名、校驗與文檔規范。一、什么是原生工具AbstractNativeTool基類原生工具在 pydantic-ai 中被建模為AbstractNativeTool抽象基類定義于 native_tools/init.py。它是一個kw_onlydataclass所有具體工具類如WebSearchTool都繼承它?;愄峁┤齻€核心成員kind: str unknown_native_tool原生工具標識符作為判別器discriminator區分所有工具類型。每個具體工具都重寫它例如web_search、x_search、code_execution、image_generation、mcp_server等。optional: bool False標記該實例是盡力而為的升級還是硬性要求。當為True時如果模型不支持該原生工具且沒有本地回退實例會被靜默丟棄而非報錯為False默認時模型無法兌現該原生工具就會顯式報錯——用戶明確要求了它就應該大聲失敗而不是悄悄替換成不同行為。unique_id與label屬性前者給出唯一標識當同一類原生工具可能被傳入多個實例時子類應重寫以區分彼此如MCPServerTool返回mcp_server:id后者提供 UI 展示用的人類可讀標簽。自動注冊機制源碼中NATIVE_TOOL_TYPES是一個以kind字符串為鍵、工具類為值的注冊表。它并非手工維護而是通過__init_subclass__在類定義時自動填充見 native_tools/init.py。同時基類實現了__get_pydantic_core_schema__把AbstractNativeTool本身變成一個按kind判別的 pydantic 聯合類型因此可以直接用于配置文件的校驗。包底部還導出了兩個對用戶有意義的集合SUPPORTED_NATIVE_TOOLS所有原生工具類型的集合frozenset由注冊表派生。NATIVE_TOOLS_REQUIRING_CONFIG需要額外配置才能使用的工具集合包含FileSearchTool、MCPServerTool、MemoryTool、AdvisorTool以及內部工具ToolSearchTool見 native_tools/init.py。這類工具不能只靠kind就可用必須由用戶顯式提供 ID、URL 或模型名等參數。二、核心設計決策跨提供者功能優先做成 Capabilitynative_tools/AGENTS.md的第一條準則即全包的靈魂凡是代表跨提供者cross-provider特性的原生工具都應該有對應的能力Capability繼承capabilities/中的NativeOrLocalTool。因為能力Capability才是用戶向 agent 啟用提供者自適應工具功能的首要公開 API。能力層的設計動機記錄在 capabilities/AGENTS.md當行為涉及指令、設置、工具、原生工具、包裝器、生命周期鉤子或事件/歷史處理時優先用 Capability 而不是給Agent構造函數新增 kwarg。能力是可組合的橫切行為容器。NativeOrLocalTool原生工具 本地回退的配對基類NativeOrLocalTool定義于 capabilities/native_or_local.py其工作方式一目了然當模型支持該原生工具移除本地回退使用原生工具當模型不支持該原生工具移除原生工具保留本地工具。它暴露兩個關鍵配置字段nativeTrue默認使用子類默認的原生工具實例、False禁用原生工具始終走本地工具、一個AbstractNativeTool實例使用該具體配置、或一個可調用對象每次運行通過RunContext動態創建原生工具返回None表示省略。localNone自動檢測本地回退、True選擇默認本地回退、False禁用本地回退只用原生工具、命名策略字符串如duckduckgo、一個Tool/AbstractToolset實例或一個裸可調用對象自動包裝成Tool。__post_init__負責把聲明解析為具體對象并做三類快速失敗檢查native_or_local.pynativeFalse且localFalse同時成立 → 報UserErrornativeFalse但約束字段要求原生工具如allowed_domains→ 報UserErrornativeFalse卻沒有顯式本地回退 → 報UserError否則會靜默變成一個什么都不做的空能力。內置的WebSearch、WebFetch、ImageGeneration能力都是該基類的子類分別通過重寫_default_native()、_default_local()、_resolve_local_strategy()、_requires_native()等鉤子定義各自行為。本地回退Local FallbackWebSearch與WebFetch文檔明確舉出的第一類回退是本地函數工具回退在提供者沒有原生支持時能力自動回退到本地 function tool。以 capabilities/web_search.py 的WebSearch為例默認情況下它使用模型的原生 web search在原生不支持的模型上拋UserError。傳入localduckduckgo或localTrue即可啟用本地 DuckDuckGo 回退但需要安裝可選依賴組pip install pydantic-ai-slim[duckduckgo]_resolve_local_strategy的實現web_search.py展示了命名策略的解析方式localTrue歸一化為duckduckgo然后延遲導入pydantic_ai.common_tools.duckduckgo.duckduckgo_search_tool如果依賴缺失會拋出帶安裝提示的UserError。local同樣接受任何可調用對象、Tool或AbstractToolset作為自定義回退。值得注意的細節是_requires_native()web_search.py當設置了blocked_domains、allowed_domains、max_uses或external_web_accessFalse時能力強制要求原生工具——因為這些約束只有原生工具能兌現此時本地回退被抑制模型不支持就會報錯從而防止約束被靜默違反。類似地capabilities/web_fetch.py 的WebFetch通過localTrue啟用本地抓取回退需要pip install pydantic-ai-slim[web-fetch]其allowed_domains/blocked_domains在原生不可用時由本地強制。本地回退的實現細節體現在get_toolset()native_or_local.py當原生工具存在時本地工具集被包裝進PreparedToolset其 prepare 函數給本地工具定義打上unless_nativenative 工具的 unique_id標記——這正是模型支持原生工具時移除本地工具的運行時機制。子代理回退Subagent FallbackXSearch與ImageGeneration文檔指出的第二類回退是子代理回退通過fallback_subagent_model把任務委托給一個運行其他提供者模型的子代理。這類能力包括ImageGeneration和XSearch。以 capabilities/x_search.py 的XSearch為例在 xAI 模型上直接使用原生 X 搜索無需額外配置在非 xAI 模型上必須顯式設置fallback_subagent_model為一個支持XSearchTool原生工具的 xAI 模型例如xai:grok-4.3否則使用XSearch會直接報錯——沒有默認的子代理模型。該能力還展示了互斥校驗的實踐__post_init__檢查fallback_subagent_model與local不能同時指定x_search.py因為二者都是非 xAI 模型下的回退路徑同時設置會讓其中一個被靜默忽略。_default_local()在設置fallback_subagent_model后從pydantic_ai.common_tools.x_search構建x_search_tool(model..., native_tool...)子代理內部依然運行原生XSearchTool因此allowed_x_handles等句柄約束在兩條路徑上都得到遵守_requires_native()在設置了fallback_subagent_model時返回False理由正是子代理也運行原生工具。ImageGeneration能力capabilities/image_generation.py更進一步提供三種互斥的回退實現同時指定多個會拋UserErrorlocal接受ImageGenerator走直接圖像生成 API、自定義Tool、工具集或可調用對象fallback_image_model接受ImageGenerationModel或provider:model字符串如openai:gpt-image-2直接調用圖像生成 API 而不是跑第二個 agentfallback_subagent_model運行一個具備圖像生成能力的會話模型子代理如openai-responses:gpt-5.4、google:gemini-3-pro-image圖像來自該模型的原生ImageGenerationTool。源碼中還區分了兩類幾何/輸出設置的去向dimensions與超出原生詞匯表的aspect_ratio只能由直接生成器兌現原生工具無法表達nativeFalse才能保證生效否則對應路徑會發出警告而background、input_fidelity、moderation、output_compression、output_format、quality、size等是原生工具專屬設置直接生成器會忽略并警告。這些細節體現了能力層必須精確說明每個設置在哪條路徑上生效的設計紀律。三、沒有可靠跨提供者抽象的工具保持純NativeTool指南第二條給出了反向的邊界對于沒有可靠跨提供者抽象、純提供者專屬的工具就作為包裹在NativeTool中的原生工具存在不要強行添加一層薄薄的 provider-agnostic 能力——除非該特性在多個提供者上有支持或有有意義的回退語義。NativeTool定義于 capabilities/native_tool.py它是一個簡單能力把單個AgentNativeTool靜態AbstractNativeTool實例或動態可調用對象注冊到 agent 上等價于Agent(capabilities[NativeTool(my_tool)])。它還提供from_spec類方法支持兩種 YAML 配置形式# 扁平形式 NativeTool: kind: web_search search_context_size: high # 顯式形式 NativeTool: tool: kind: web_searchfrom_spec內部通過pydantic.TypeAdapter(AbstractNativeTool)校驗配置得益于基類的判別聯合 schema任何內置工具類型都能被正確解析。四、請求級參數暴露在工具類字段而非只放在 Model Settings指南的第三條針對提供者 API 中有控制原始工具輸出是否包含的請求級參數例如 xAI 的include、OpenAI 的include這類參數應作為工具類的字段暴露而不是只放在 model settings 里。用戶配置XSearchTool(...)時應該能發現所有相關選項model settings 保留為向后兼容的替代方案。一個教科書式的例子是XSearchTool.include_outputnative_tools/init.py默認False時模型只在內部使用搜索結果、返回文字摘要設為True后原始搜索結果會以NativeToolReturnPart形式出現在響應中程序可以訪問搜到的帖子、來源與元數據。它同時也可以在XaiModelSettings.xai_include_x_search_output中設置——工具字段為主 APImodel settings 是向后兼容的備選二者并存。五、提供者支持的文檔三處維護指南要求提供者支持情況必須記錄在三個地方任何一處遺漏都視為違規工具類 docstring 中的 Supported by 列表每個工具類與每個提供者專屬字段都帶一個 Supported by: 小節。例如WebSearchTool類級列表寫明 Anthropic、OpenAI Responses、Groq、Google、xAI、OpenRouter 六家而user_location字段級列表則進一步細分到 Anthropic、OpenAI Responses、xAI、OpenRouter還附上各提供者官方文檔鏈接。docs/native-tools.md的提供者支持表格倉庫根目錄下的 docs/native-tools.md 集中維護一張工具 × 提供者支持矩陣供用戶快速橫向對比。字段級 docstring 中的提供者專屬語義例如WebSearchTool.external_web_access明確說明OpenAI 的 legacyweb_search_preview工具會忽略此參數ImageGenerationTool.output_compression區分 OpenAI僅 jpeg/webp默認 100與 Google Vertex AI僅 jpeg默認 75。這套三處文檔紀律保證了同一事實在不同入口類內省、API 參考、橫向對比表保持同步。六、字段命名優先直通提供者 API 字段名指南進一步要求當工具字段直接映射提供者 API 的字段名時優先使用那個名字——用戶可能正開著提供者的官方文檔對照使用 pydantic-ai 文檔。從 native_tools/init.py 的實現可以清晰看到這一原則WebSearchTool.search_context_size、user_location、blocked_domains、allowed_domains、max_uses、external_web_access均與 OpenAI Responses / Anthropic 等提供者的參數同名XSearchTool.allowed_x_handles、excluded_x_handles、from_date、to_date與 xAI X-search 的參數一致AdvisorTool.model、max_tokens、caching與 Anthropic advisor 工具定義的字段一一對應。FileSearchTool.file_store_ids則針對三家映射到不同概念OpenAI 的 vector store ID、Google 的 file search store 名、xAI 的 collection ID也在字段 docstring 中逐一說明。七、快速失敗__post_init__校驗互斥與上限指南要求在__post_init__中校驗互斥性與數量上限用清晰的錯誤消息快速失敗。源碼中有兩個典型實現XSearchTool.__post_init__native_tools/init.pydef __post_init__(self) - None: if self.allowed_x_handles is not None and self.excluded_x_handles is not None: raise ValueError(Cannot specify both allowed_x_handles and excluded_x_handles) if self.allowed_x_handles and len(self.allowed_x_handles) 20: raise ValueError(allowed_x_handles cannot contain more than 20 handles) if self.excluded_x_handles and len(self.excluded_x_handles) 20: raise ValueError(excluded_x_handles cannot contain more than 20 handles)AdvisorTool.__post_init__native_tools/init.pydef __post_init__(self) - None: if self.max_tokens is not None and self.max_tokens 1024: raise ValueError(AdvisorTool.max_tokens must be at least 1024)這種構造期即失敗fail fast at construction的哲學還延伸到能力層ImageGeneration在__post_init__中同時拒絕dimensions與aspect_ratio并存、拒絕把裸ImageGenerationModel傳給local、拒絕無 provider 前綴的fallback_image_model字符串錯誤消息都具體指明應該改用哪個字段。八、名稱往返Round-Trip原生工具名的歷史一致性最后一條準則最隱蔽也最關鍵pydantic-ai 中的原生工具名必須能在提供者 API 中往返round-trip。如果提供者 API 使用不同的函數名——例如 xAI 在線上發送的是x_keyword_search而不是 pydantic-ai 里的x_search——那么在回放歷史replaying history時必須保留原始名稱否則舊對話中的工具調用無法與新的工具定義對上。這一要求對應倉庫中的歷史回放與線纜契約wire contract測試體系例如 tests/test_ref_sibling_wire_contract.py 與 tests/test_thinking_wire_contract.py 所覆蓋的場景agent 運行、暫停、恢復或導入歷史消息時工具引用的命名必須與首次調用時一致。為新增工具設計時務必確認提供者是否會對工具名做改寫并保證適配器在回放路徑上保留提供者側的真實名稱。九、九個內置原生工具速查表當前倉庫 native_tools/init.py 導出的原生工具及其要點如下工具類kind主要提供者關鍵字段WebSearchToolweb_searchAnthropic、OpenAI Responses、Groq、Google、xAI、OpenRoutersearch_context_sizelow/medium/high默認 medium、user_location、blocked_domains、allowed_domains、max_uses、external_web_accessXSearchToolx_searchxAIallowed_x_handles/excluded_x_handles互斥各限 20、from_date/to_datenaive 時間按 UTC 解釋、enable_image_understanding、enable_video_understanding、include_outputCodeExecutionToolcode_executionAnthropic、OpenAI Responses、Google、Bedrock (Nova2.0)、xAIfiles上傳文件僅匹配提供者的文件被使用WebFetchToolweb_fetchAnthropic、Googlemax_uses、allowed_domains/blocked_domains互斥、enable_citations、max_content_tokensImageGenerationToolimage_generationOpenAI Responses、Googleaction、background、input_fidelity、moderation、model如gpt-image-2、output_compression、output_format、partial_images0–3、quality、size、aspect_ratioMemoryToolmemoryAnthropic無參MCPServerToolmcp_serverOpenAI Responses、Anthropic、xAIid、urlOpenAI 支持x-openai-connector:connector_id、authorization_token、description、allowed_tools、headersFileSearchToolfile_searchOpenAI Responses、Google (Gemini)、xAIfile_store_ids、max_num_results、instructions、retrieval_modehybrid/semantic/keywordAdvisorTooladvisorAnthropic、OpenRoutermodelexecutor 咨詢的更強模型、max_uses每請求上限、max_tokens≥1024、caching5m/1h臨時緩存 TTL其中FileSearchTool是完全托管的 RAG由提供者處理文件存儲、分塊、嵌入生成與上下文注入pydantic-ai 側只需傳入 store ID。AdvisorTool的字段與 Anthropic advisor 工具定義 1:1 映射OpenRouter 作為網關 server tool 只接受model與max_tokens子集并忽略其余字段——這些差異都在字段級 docstring 中標注。此外_tool_search.py中還有框架內部的ToolSearchToolkindtool_search它不直接導出給用戶而是由ToolSearch能力按提供者選擇三種模式之一驅動原生服務端搜索Anthropic 的bm25/regex、OpenAI 的服務端執行tool_search、原生客戶端執行Anthropic 的 tool-reference 塊、OpenAI 的executionclient調用本地可調用對象、以及本地search_tools函數工具回退見 native_tools/_tool_search.py。十、新增原生工具八條檢查清單綜合 native_tools/AGENTS.md 與源碼實現為 pydantic-ai 新增一個原生工具時應依次確認跨提供者判定該特性在多個提供者上有支持或合理回退語義嗎是 → 創建繼承NativeOrLocalTool的能力否 → 保持NativeTool包裹的純原生工具。回退路徑本地回退function tool還是子代理回退fallback_subagent_model無回退時不支持的模型必須顯式報錯optionalFalse語義。請求級參數提供者 API 的請求級參數如include要在工具類上暴露字段model settings 只作向后兼容備選。三處文檔類 docstring 的 Supported by、docs/native-tools.md 提供者表格、字段級 docstring缺一不可。字段命名直通提供者 API 字段名方便用戶對照提供者文檔??焖偈⌒r炘赺_post_init__中用清晰消息校驗互斥與上限。名稱往返確認提供者是否改寫工具函數名保證歷史回放時保留提供者側原始名稱。配置需求需要用戶提供額外參數的工具FileSearch、MCP、Memory、Advisor、ToolSearch要進入NATIVE_TOOLS_REQUIRING_CONFIG集合避免用戶以為只傳kind即可用。遵循這八條既能保證用戶通過能力層獲得提供者自適應的統一體驗又能讓提供者專屬細節在工具類與文檔中透明可見——這正是 pydantic-ai 原生工具體系typed end to end設計哲學在工具層的落地。【免費下載鏈接】pydantic-aiHow Python does AI. Agents, realtime voice, image generation, embeddings. Every model, every interface, typed end to end.項目地址: https://gitcode.com/GitHub_Trending/py/pydantic-ai創作聲明:本文部分內容由AI輔助生成(AIGC),僅供參考