Pydantic AI Function Tools 與內建工具
如果只有單純的文字對話能力,AI 代理人的用途其實相當受限。要讓代理人成為真正解決問題的得力助手,你必須賦予它「行動」的能力——也就是讓 AI 能夠呼叫我們預先寫好的 Python 函數 (Functions)。
在 Pydantic AI 中,這個機制被稱為 Function Tools。
什麼是 Function Tools?
Function Tools 允許你將任意的 Python 函數暴露給 AI 模型。運作原理如下:
- 你寫了一個 Python 函數,並加上了型別提示 (Type Hints) 與 Docstring (函數說明)。
- 透過 Pydantic AI 的裝飾器將這個函數註冊為代理人的工具。
- 框架會讀取該函數的名稱、說明以及參數型別,轉換成 JSON Schema 並傳遞給 AI。
- 當 AI 認為它需要這個函數的幫助來回答問題時,它會生成一組符合 Schema 的參數。
- 框架自動在本地端執行這個 Python 函數,並將回傳的結果再丟回給 AI。
- AI 根據函數的回傳結果,組合出最終的答案給你。
如何註冊工具
在 Pydantic AI 中,最簡單的註冊工具方式是使用 @agent.tool 或 @agent.tool_plain 裝飾器。
使用 @agent.tool_plain (無依賴注入)
如果你的工具函數不需要存取任何外部依賴或執行環境的狀態,可以使用 @agent.tool_plain:
from pydantic_ai import Agent
# 建立一個 Agent
agent = Agent('openai:gpt-4o-mini')
# 透過 @agent.tool_plain 裝飾器註冊一個純函數工具
# 強烈建議提供清晰的 Docstring,這會變成模型理解該工具用途的說明書
@agent.tool_plain
def calculate_bmi(height_cm: float, weight_kg: float) -> float:
"""
計算使用者的 BMI (身體質量指數)。
Args:
height_cm: 身高 (單位:公分)
weight_kg: 體重 (單位:公斤)
"""
height_m = height_cm / 100
bmi = weight_kg / (height_m ** 2)
# 簡化到小數點後兩位
return round(bmi, 2)
# 執行 Agent 時,如果它判斷需要計算 BMI,它就會自動呼叫這個函數
result = agent.run_sync("我身高 175 公分,體重 70 公斤,請問我的 BMI 是多少?健康嗎?")
print(result.data)
在上述過程中,你不需要手動處理字串解析或是呼叫函數,Pydantic AI 已經幫你處理好所有底層的繁瑣工作。模型會自動根據 height_cm 和 weight_kg 生成對應的數值並觸發函數。
使用 @agent.tool (結合依賴注入)
工具函數經常需要存取外部資源(例如資料庫連線或是 API Token)。這時候,我們可以使用 @agent.tool 並結合 RunContext 來獲取依賴項,同時保持工具函數介面的乾淨。
import httpx
from pydantic_ai import Agent, RunContext
# 定義 Agent 需要一個 httpx.Client 作為依賴
agent = Agent('gemini-1.5-flash', deps_type=httpx.Client)
# 工具函數的第一個參數必須是 RunContext,這不會暴露給 AI 模型
@agent.tool
def get_external_data(ctx: RunContext[httpx.Client], query: str) -> str:
"""根據使用者的 query 查詢外部資料庫。"""
# 透過 ctx.deps 拿到注入的 HTTP Client 並發送請求
client = ctx.deps
response = client.get(f"https://api.example.com/search?q={query}")
return response.text
框架聰明地知道 RunContext 是給本地程式碼使用的,它不會將這個參數列入提供給 AI 的 Schema 中。對 AI 來說,這個工具就只有一個 query 參數。
工具的錯誤處理與重試 (ModelRetry)
如果工具執行過程中發現參數不合法或遇到預期內的錯誤,你可以拋出 ModelRetry 異常。Pydantic AI 會捕捉這個異常,並將錯誤訊息傳回給模型,要求模型修正參數後再試一次。
from pydantic_ai import Agent, RunContext
from pydantic_ai.exceptions import ModelRetry
agent = Agent('gemini-1.5-flash')
@agent.tool_plain
def fetch_user_profile(user_id: str) -> str:
"""根據 user_id 查詢使用者資料。"""
if not user_id.startswith("USR-"):
# 拋出 ModelRetry,模型會收到這個訊息並嘗試修正 user_id 格式
raise ModelRetry("user_id 格式錯誤,必須以 'USR-' 開頭。請修正後重試。")
return f"使用者 {user_id} 的資料..."
內建工具與 Capabilities
為了減少重複開發,Pydantic AI 內建了許多常用的工具。在最新的版本中,這些工具通常透過 Capabilities 的形式掛載到 Agent 上。
例如,如果你需要讓 Agent 具備執行 Python 程式碼或是網路搜尋的能力,你可以直接從框架中匯入這些預先封裝好的工具集:
from pydantic_ai import Agent
from pydantic_ai.capabilities import WebSearch
from pydantic_ai.builtin_tools import CodeExecutionTool
agent = Agent(
'openai:gpt-4o',
capabilities=[
# 賦予網路搜尋能力
WebSearch(),
]
)
# 直接掛載內建的程式碼執行工具
@agent.tool_plain
def execute_python(code: str) -> str:
"""執行 Python 程式碼並回傳結果"""
# 實務上可使用 CodeExecutionTool 等內建工具來安全執行
pass
給予 Agent 適當的工具,是突破語言模型只能「紙上談兵」限制的關鍵,讓它真正成為具備執行力的 AI 助手。對於更複雜的工具管理與權限控制,請參考下一章節的進階工具教學。