Pydantic AI 教學:用型別安全的方式打造 LLM Agent,從第一支程式到上線
2026年6月12日
做過 LLM 應用的人都知道,最痛的不是接 API,而是模型回傳的東西每次都長得不一樣。Pydantic AI 把 Pydantic 的型別驗證搬進 Agent 開發,讓輸出有結構、工具能被靜態檢查。這篇帶你從安裝寫到進階,附上我自己踩過的坑。
前言:模型回傳的東西,為什麼每次都不一樣
如果你接過 LLM 的 API,大概對這個畫面不陌生:你叫模型「回傳一個 JSON,裡面要有 name 跟 score」,前九次都好好的,第十次它在 JSON 前面加了一句「好的,以下是結果:」,你的 json.loads() 當場炸掉。然後你開始寫一堆正規表達式去清字串,再寫一堆 if 去檢查欄位在不在——最後你的「AI 應用」有七成程式碼是在跟模型的不穩定輸出搏鬥。
我自己維護過一個內部分類服務,光是處理模型偶爾少給一個欄位這件事,就讓我加了三天班。後來換成 Pydantic AI,那段防禦性程式碼幾乎全刪掉了,因為驗證這件事框架直接幫你扛。這篇就講清楚它怎麼用。
Pydantic AI 是什麼
Pydantic AI 是 Pydantic 團隊出的 Python Agent 框架。Pydantic 這個名字你可能在別的地方看過——OpenAI、Anthropic、Google 的官方 SDK,還有 LangChain、LlamaIndex,底層的資料驗證很多都靠它。換句話說,做驗證這件事,他們是這個生態系裡最有資格的人。
它的設計哲學很像 FastAPI:用 Python 原生的型別註記(type hints)把行為定義清楚,剩下的交給框架。核心只有幾個概念——Agent(代理)、Tools(工具)、Dependencies(依賴注入)、Structured Output(結構化輸出)。你不需要去背一堆它自己發明的抽象類別,寫起來就是普通 Python,但 IDE 會給你自動補全,型別檢查器(像 Pyright、mypy)能在你還沒跑程式前就抓到錯。
它是 model-agnostic 的,也就是不綁特定模型廠商。OpenAI、Anthropic、Google、Groq、Cohere、Mistral、Ollama 等十幾家都支援,要換模型通常只改一個字串。想搞懂 Agent 跟一般 API 呼叫差在哪,可以先看什麼是 AI Agent。
能拿來做什麼
講白話,凡是「需要模型回傳可信賴結果」的場景它都合適:
- 結構化抽取:把一封客訴信丟進去,要它吐出
情緒、類別、急迫度三個欄位,而且保證型別正確。 - 分類與標註:大量文件要打標籤,輸出限定在你定義的 Enum 裡,模型亂回答會被擋下來。
- 工具型 Agent:讓模型能呼叫你的函式——查資料庫、打天氣 API、算數學,框架負責把函式的型別轉成模型看得懂的工具描述。
- RAG 問答:搭配向量檢索,做出有依據的問答系統,這部分可以參考我們的 RAG 實作指南。
比起 LangChain 那種什麼都包的大框架,Pydantic AI 刻意做得很薄。如果你只是要把模型輸出變可靠,不想為了一個小功能背一整套生態系,它的學習曲線會友善很多。
怎麼用:第一次上手
1. 安裝
pip install pydantic-ai
建議開一個虛擬環境。Python 版本用 3.9 以上比較安全。
2. 設定 API 金鑰
以 Anthropic 為例,設個環境變數:
export ANTHROPIC_API_KEY=你的金鑰
用 OpenAI 就設 OPENAI_API_KEY,以此類推。
3. 寫第一支 Agent
from pydantic_ai import Agent
agent = Agent('anthropic:claude-sonnet-4-6')
result = agent.run_sync('用一句話解釋什麼是向量資料庫')
print(result.output)
第一個參數就是模型名稱,格式是 廠商:模型。要換成 OpenAI 就改成 'openai:gpt-4o' 之類,其他程式不用動——這就是 model-agnostic 的好處。
4. 讓輸出有結構
這才是重點。你定義一個 Pydantic 模型當輸出格式:
from pydantic import BaseModel
from pydantic_ai import Agent
class Review(BaseModel):
sentiment: str # positive / negative / neutral
score: int # 1 到 5
summary: str
agent = Agent('anthropic:claude-sonnet-4-6', output_type=Review)
result = agent.run_sync('這家店東西好吃但等了快一小時,有點誇張')
print(result.output.score) # 直接拿到整數,不用自己 parse
print(result.output.sentiment) # 直接拿到字串
模型回的東西如果不符合 Review 的型別,框架會自動把錯誤訊息丟回去叫模型重試。你拿到 result.output 時,它已經是一個驗證過的 Python 物件,IDE 還會幫你補全欄位。
5. 給 Agent 一個工具
from pydantic_ai import Agent
agent = Agent('anthropic:claude-sonnet-4-6')
@agent.tool_plain
def get_weather(city: str) -> str:
"""查詢指定城市目前的天氣"""
return f'{city} 現在 28 度,晴'
result = agent.run_sync('台北現在天氣如何?')
print(result.output)
那個 docstring 不是寫好看的——它會變成模型看到的工具說明。函式的型別註記(city: str)也會被轉成模型理解的參數規格,參數同樣經過 Pydantic 驗證。
進階技巧
依賴注入是它最被低估的功能。你可以透過 RunContext 把資料庫連線、使用者身分、API client 這些東西型別安全地傳進 Agent 跟工具裡:
from dataclasses import dataclass
from pydantic_ai import Agent, RunContext
@dataclass
class Deps:
user_id: int
db: object # 你的資料庫連線
agent = Agent('anthropic:claude-sonnet-4-6', deps_type=Deps)
@agent.tool
def get_orders(ctx: RunContext[Deps]) -> str:
return f'查詢使用者 {ctx.deps.user_id} 的訂單'
寫測試時,把 db 換成假的物件就行,不用碰真資料庫,這對寫單元測試太重要了。
串流(streaming):要做即時打字效果,用 agent.run_stream(),它會邊產生邊驗證結構化輸出,使用者體驗好很多。
觀測性:Pydantic AI 跟同團隊的 Logfire 整合得很順。接上去之後,每一次模型呼叫、每一個工具觸發、花了多少 token、跑了幾秒,全都看得到。LLM 應用最難 debug 的就是「模型到底為什麼這樣回」,有了這個就不用瞎猜。想把 Agent 規劃得更完整,搭配我們的 Agent 開發指南 一起看。
常見錯誤與注意事項
- 以為加了 output_type 就 100% 安全:框架會在驗證失敗時叫模型重試,但重試是有上限的。一直失敗它會丟例外,你還是得 try/except。型別驗證減少的是「髒資料溜進系統」,不是「模型永遠不出錯」。
- 工具的 docstring 隨便寫:模型完全靠 docstring 判斷什麼時候該呼叫工具。寫得含糊,模型就亂呼叫或不呼叫。把它當成寫給模型看的使用說明書。
- 在工具裡塞太多邏輯卻不處理例外:工具裡的程式碼出錯,訊息會被回傳給模型,模型可能繞著錯誤打轉燒掉一堆 token。該擋的例外自己擋好。
- 忽略成本:結構化輸出重試、工具多輪呼叫,token 消耗比你想的快。上線前一定要接觀測,看清楚實際花費。
- 把它當大框架用:它刻意做得薄。如果你需要複雜的多步驟編排、現成的一堆連接器,可能 LlamaIndex 或別的方案更省事,別硬湊。
TheAI學院 評語
老實說,市面上 Agent 框架多到讓人選擇障礙,但 Pydantic AI 解決的是一個非常具體、每個 LLM 開發者都中過招的痛:輸出不可靠。它沒有想做「全宇宙最強框架」,就是把「型別安全」這件 Python 圈本來就在乎的事,乾淨地搬進 AI 開發。對已經習慣 FastAPI、Pydantic 寫法的人,幾乎沒有學習成本。
它不會讓你的模型變聰明,但會讓你的程式碼變可靠——而後者才是上線後真正救你的東西。
如果你是要做 demo、玩玩看,可能感受不深;但只要你的東西要真的上線、要被人用、要長期維護,型別安全跟可觀測這兩件事的價值會一天比一天明顯。
資料來源
常見問題
Pydantic AI 跟 LangChain 差在哪,該選哪個?
最大差別是「重量」。LangChain 是大型生態系,連接器、整合、抽象層都很多,適合需要複雜編排的大型專案,但學習曲線陡。Pydantic AI 刻意做得薄,核心只有 Agent、工具、依賴注入、結構化輸出幾個概念,主打型別安全。如果你的需求是「讓模型輸出變可靠、寫法貼近原生 Python」,Pydantic AI 上手快很多;如果你需要大量現成整合,LangChain 比較省事。兩者不衝突,看專案規模選。
一定要用 OpenAI 的模型嗎?可以接本地模型嗎?
不用。Pydantic AI 是 model-agnostic,支援 OpenAI、Anthropic、Google、Groq、Mistral、Cohere、Ollama 等十幾家,換模型通常只改建立 Agent 時那一個字串。要跑本地模型可以透過 Ollama,把模型字串指向本地服務即可,程式其他部分不用動。
結構化輸出真的能保證模型不亂回嗎?
不能保證模型本身不出錯,但能保證「不符合你定義型別的資料不會溜進系統」。當模型回的東西通不過 Pydantic 驗證,框架會自動把錯誤訊息丟回去要它重試。不過重試有次數上限,持續失敗會丟例外,所以你還是要用 try/except 處理最壞情況。它降低的是髒資料風險,不是模型的智商問題。
新手沒寫過 Pydantic,學這個會很難嗎?
如果你會基本 Python 跟型別註記(type hints),門檻不高。Pydantic 的核心就是「用 class 定義資料長什麼樣」,寫法很直覺。建議先花十分鐘看一下 Pydantic 怎麼定義 BaseModel,再回來寫 Agent,會順很多。真正的觀念門檻反而是 Agent 跟工具的設計思路,可以搭配我們的 Agent 開發指南一起學。
資料來源:theai