
Pydantic AI:生產環境實戰指南(超越 Hello World)
原始的 LLM 輸出會搞壞應用程式。你要求 JSON,它卻給你 Markdown。你要求一個 1 到 10 之間的數字,它卻回答「沒問題!這是一個數字:七。」如果你曾用 LLM API 建構過任何實際應用,你一定寫過那些讓你懷疑人生選擇的防禦性解析程式碼。Pydantic AI 解決了這個問題,它是來自 Pydantic 和 FastAPI 背後同一團隊打造的類型安全****Agent 框架。你可以把它想像成「AI Agent 版的 FastAPI」:你用 Python 型別提示(Type Hints)定義需求,框架則負責處理驗證、重試和工具呼叫。
這份 Pydantic AI 指南 是為已經跑過第一次 LLM 呼叫、並希望掌握生產環境模式的開發者所寫:不會崩潰的結構化輸出、可測試 Agent 的依賴注入,以及超越天氣 API 的真實世界工具。讀完本文,你將擁有具備工具整合、依賴注入、串流功能和測試覆蓋的可用 Agent。
<!-- IMAGE: Pydantic AI agent architecture, Agent receives prompt, calls tools via RunContext, validates output through Pydantic model -->Pydantic AI 快速概覽
| 屬性 | 詳情 |
|---|---|
| 是什麼 | Python 的類型安全 AI Agent 框架 |
| 開發團隊 | Pydantic 團隊(Samuel Colvin 等人) |
| 設計哲學 | 「AI Agent 版的 FastAPI」,一切由型別提示驅動 |
| 授權條款 | MIT(開源) |
| 當前版本 | v1.74.0(2026 年 3 月) |
| Python 版本 | 3.9+ |
| 支援模型 | OpenAI、Anthropic、Google Gemini、Groq、Mistral、Ollama 等 |
| 核心功能 | 結構化輸出、工具呼叫、依賴注入、串流、TestModel |
| GitHub Stars | 16,000+ |
| 生產就緒 | 是的,v1.0 已於 2025 年 9 月發布 |
| 可觀測性 | 原生整合 Logfire(基於 OpenTelemetry) |
| 學習曲線 | 若熟悉 Pydantic/FastAPI 則低;否則中等 |
其突出功能包括結構化輸出(使用 Pydantic 模型驗證)、依賴注入(類似 FastAPI 的 Depends),以及 TestModel(用於測試的模擬 LLM,無需呼叫 API)。如果你來自 LangChain 並心想「有沒有更乾淨的方案?」,這很可能就是答案。
安裝與第一個 Agent
# Install with OpenAI support (swap openai for anthropic, google, etc.)
pip install "pydantic-ai[openai]"
# Set your API key
export OPENAI_API_KEY="sk-..."只需 5 行程式碼即可建立你的第一個 Agent:
from pydantic_ai import Agent
agent = Agent("openai:gpt-4o", system_prompt="You are a helpful assistant.")
result = agent.run_sync("What's the capital of France?")
print(result.output) # "Paris"就這樣。Agent 封裝了模型,run_sync 發送提示並返回結果。此處的 result.output 是一個普通字串,但情況即將改變。
結構化輸出:Pydantic AI 存在的理由
這是核心功能。與其從 LLM 取得字串並祈禱它是有效的 JSON,不如定義一個 Pydantic 模型,讓 Agent 返回經過驗證的 Python 物件。
之前:原始 LLM 輸出
# The old way -- hope for the best
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Review the movie Inception. Return JSON with title, rating (1-10), summary."}]
)
# response.choices[0].message.content is a string
# Maybe it's JSON. Maybe it has markdown code fences. Maybe rating is "eight".
# You're on your own.之後:使用 Pydantic AI 的結構化輸出
from pydantic import BaseModel
from pydantic_ai import Agent
class MovieReview(BaseModel):
title: str
rating: int # Guaranteed to be an int, not "eight"
summary: str
recommended: bool
agent = Agent("openai:gpt-4o", result_type=MovieReview)
result = agent.run_sync("Review the movie Inception")
review = result.output # This is a MovieReview instance, not a string
print(f"{review.title}: {review.rating}/10")
print(f"Recommended: {review.recommended}")
print(review.summary)差異有天壤之別。result.output 是一個真正的 MovieReview 物件。如果 LLM 返回 rating: "eight" 而非 rating: 8,Pydantic 的驗證機制會捕捉到此錯誤。若想深入了解這在不同供應商間的運作方式,請參閱我們關於跨 LLM 供應商的結構化輸出的指南。
當驗證失敗時會發生什麼事
這裡有個其他教學很少展示的部分:當 LLM 出錯時會發生什麼事?
from pydantic import BaseModel, Field
from pydantic_ai import Agent
class StrictReview(BaseModel):
title: str
rating: int = Field(ge=1, le=10) # Must be 1-10
pros: list[str] = Field(min_length=2) # At least 2 pros
agent = Agent("openai:gpt-4o", result_type=StrictReview)
# If the LLM returns rating=15 or only 1 pro:
# 1. Pydantic validation fails
# 2. The error message is sent BACK to the LLM
# 3. The LLM tries again with the corrected output
# 4. This repeats up to the retry limit
result = agent.run_sync("Review the movie Inception")這種「重試並提供回饋」的循環是 Pydantic AI 的殺手鐧。LLM 會從自身的驗證錯誤中學習。你無需編寫重試邏輯,框架會自動處理。
結論:結構化輸出是使用 Pydantic AI 而非原始 API 呼叫的最佳理由。 如果你還在手動解析 LLM 的 JSON,請停止這樣做。
工具與函式呼叫
工具讓你的 Agent 能夠呼叫 Python 函式以獲取真實資料。與其讓 LLM 胡編亂造事實,不如讓它查詢你的資料庫、搜尋文件或呼叫 API。
註冊工具
from pydantic_ai import Agent
agent = Agent("openai:gpt-4o")
@agent.tool
async def search_docs(query: str) -> str:
"""Search the documentation for relevant articles."""
# Your actual search logic here
results = await doc_search_engine.search(query, limit=5)
return "\n".join(r.title + ": " + r.snippet for r in results)@agent.tool 裝飾器會註冊該函式。Pydantic AI 會讀取函式的型別提示和文件字串,告訴 LLM 該工具的功能、接受的參數以及返回值。無需手動編寫 Schema,你的型別提示就是 Schema。關於LLM 函式呼叫的底層運作原理,我們有專屬指南可供參考。
RunContext:向工具傳遞資料
這是 Pydantic AI 與其他框架的不同之處。RunContext 讓你能將執行時期資料(資料庫連線、使用者資訊、API 客戶端)傳遞給工具,而無需依賴全域狀態。
from dataclasses import dataclass
from pydantic_ai import Agent, RunContext
@dataclass
class SupportDeps:
customer_id: str
db_connection: DatabaseConnection
agent = Agent("openai:gpt-4o", deps_type=SupportDeps)
@agent.tool
async def get_order_history(ctx: RunContext[SupportDeps], limit: int = 5) -> str:
"""Fetch recent orders for the current customer."""
orders = await ctx.deps.db_connection.query(
"SELECT * FROM orders WHERE customer_id = $1 ORDER BY date DESC LIMIT $2",
ctx.deps.customer_id, limit
)
return format_orders(orders)ctx.deps 讓工具能夠存取你在執行時期傳遞的任何內容。工具不需要匯入全域資料庫連線,而是直接接收連線。這就是依賴注入,也是讓你的 Agent 具備可測試性的關鍵。
真實世界工具範例
@agent.tool
async def run_sql_query(ctx: RunContext[SupportDeps], sql: str) -> str:
"""Run a read-only SQL query against the analytics database.
Only SELECT queries are allowed."""
if not sql.strip().upper().startswith("SELECT"):
return "Error: only SELECT queries are allowed"
results = await ctx.deps.db_connection.fetch(sql)
return json.dumps(results, default=str)結論:得益於型別提示承擔了大量工作,Pydantic AI 的工具呼叫比任何其他框架都更簡潔。 你只需編寫帶有型別註解的一般 Python 函式,框架會處理其餘部分。
依賴注入:LangChain 夢寐以求的功能
如果你用過 FastAPI 的 Depends,你已經理解 Pydantic AI 的 DI 系統。如果沒用過,簡單來說:與其讓 Agent 主動去抓取所需資源(全域資料庫連線、API 客戶端、設定),不如在執行時期將所有資源交給它。
定義依賴項
from dataclasses import dataclass
from pydantic_ai import Agent
@dataclass
class AppDeps:
db: AsyncDatabasePool
search_client: SearchAPIClient
current_user: User
agent = Agent(
"openai:gpt-4o",
deps_type=AppDeps,
system_prompt="You are a customer support agent."
)在工具中使用依賴項
@agent.tool
async def lookup_account(ctx: RunContext[AppDeps]) -> str:
"""Look up the current user's account details."""
account = await ctx.deps.db.fetchrow(
"SELECT * FROM accounts WHERE user_id = $1",
ctx.deps.current_user.id
)
return json.dumps(account, default=str)
# Run with real dependencies
result = await agent.run(
"What's my account status?",
deps=AppDeps(db=real_db, search_client=real_search, current_user=user)
)為什麼 DI 讓你的 Agent 更具可測試性
這是真正的回報所在。在 LangChain 中,你必須透過 Chain kwargs 或閉包傳遞上下文,缺乏標準模式。而在 Pydantic AI 中,將真實依賴項替換為測試替身易如反掌:
# In your test file
from pydantic_ai import Agent
from your_app import agent, AppDeps
async def test_account_lookup():
mock_deps = AppDeps(
db=MockDatabase({"user_123": {"status": "active", "plan": "pro"}}),
search_client=MockSearch(),
current_user=User(id="user_123")
)
result = await agent.run("What's my account status?", deps=mock_deps)
assert "active" in result.output
assert "pro" in result.output無需猴子補丁(Monkey-patching)。無需模擬全域匯入。你只需傳遞不同的 deps。
結論:依賴注入是資深 Python 開發者偏好 Pydantic AI 的原因。這正是 FastAPI 影響力的體現。
模型供應商:OpenAI、Anthropic、Gemini、Ollama
Pydantic AI 是模型無關的。切換供應商只需更改一行程式碼:
# OpenAI
agent = Agent("openai:gpt-4o")
# Anthropic
agent = Agent("anthropic:claude-sonnet-4-20250514")
# Google Gemini
agent = Agent("google-gla:gemini-2.0-flash")
# Local Ollama
agent = Agent("ollama:llama3.1")其他所有內容——工具、結構化輸出、DI——保持不變。當你切換模型時,業務邏輯無需改變。
| 供應商 | 模型 | 免費方案 | 設定複雜度 |
|---|---|---|---|
| OpenAI | GPT-4o, GPT-4o mini, o1 | $5 額度(新帳戶) | 低,僅需 API Key |
| Anthropic | Claude Sonnet, Haiku, Opus | 無免費方案 | 低,僅需 API Key |
| Google Gemini | Gemini 2.0 Flash, Pro | 慷慨的免費方案 | 中,需專案設定 |
| Groq | Llama, Mixtral | 有免費方案 | 低,僅需 API Key |
| Ollama(本地) | Llama, Mistral, Phi 等 | 完全免費 | 中,需安裝 Ollama |
結論:模型無關的設計意味著你永遠不會被鎖定在單一供應商。 為了方便起见從 OpenAI 開始,使用 Anthropic 進行基準測試,並使用 Ollama 進行本地開發。
串流回應
對於聊天 UI 和即時應用程式而言,串流至關重要。Pydantic AI 在維持類型安全的同時支援串流:
from pydantic_ai import Agent
from pydantic import BaseModel
class AnalysisResult(BaseModel):
summary: str
sentiment: str
confidence: float
agent = Agent("openai:gpt-4o", result_type=AnalysisResult)
async def stream_analysis(text: str):
async with agent.run_stream(f"Analyze this text: {text}") as stream:
async for partial in stream.stream_structured():
# partial is a partially-validated AnalysisResult
print(f"Streaming: {partial}")
# Final result is fully validated
result = await stream.get_output()
print(f"Final: {result.summary} ({result.confidence:.0%} confident)")這與 FastAPI 的 StreamingResponse 完美搭配,相同的生態系,相同的模式。Pydantic AI Agents 文件涵蓋了進階串流選項,包括使用 stream_text() 進行純文字串流。
Pydantic AI vs LangGraph vs OpenAI Agents SDK
你來到這裡,可能正在問:「我該使用 Pydantic AI 還是 LangGraph?」誠實的回答是:它們解決不同的問題,你可能會同時使用兩者。
功能比較表
| 功能 | Pydantic AI | LangGraph | OpenAI Agents SDK |
|---|---|---|---|
| 類型安全 | 完整(Pydantic 模型) | 部分(TypedDict) | 最小化 |
| 依賴注入 | 內建(FastAPI 風格) | 無 | 無 |
| 結構化輸出 | 原生支援並含重試機制 | 透過輸出解析器 | 透過 JSON 模式 |
| 工具呼叫 | @agent.tool 裝飾器 | @tool 裝飾器 | 函式定義 |
| 多 Agent | 基本交接 | 進階(狀態機) | 交接 + 防護欄 |
| 串流 | 類型化串流 | 串流事件 | 串流 |
| 模型支援 | 10+ 供應商 | 主要為 LangChain 模型 | 僅限 OpenAI |
| 測試 | 內建 TestModel | 無內建測試 | 無內建測試 |
| 學習曲線 | 低(若熟悉 Pydantic) | 高(圖形概念) | 低(簡單 API) |
| 社群規模 | 成長中(16K stars) | 龐大(LangChain 生態系) | 成長中(OpenAI 支持) |
| 最佳適用場景 | 乾淨、可測試的 Agent | 複雜的狀態工作流程 | 僅限 OpenAI 的專案 |
何時使用哪一個
選擇 Pydantic AI 當你希望擁有乾淨、類型安全的 Agent 程式碼時。它非常適合帶有工具的單一 Agent 任務(客戶服務機器人、資料提取、程式碼審查 Agent)以及重視可測試性的情境。如果你的團隊已經使用 FastAPI 和 Pydantic,學習曲線幾乎是平的。
選擇 LangGraph 當你需要具有條件分支、人工審核循環和複雜狀態管理的複雜多步驟工作流程時。LangGraph 擅長協調多個步驟,而非提升單一 Agent 的品質。深入探討請見我們完整的 LangGraph vs CrewAI vs OpenAI Agents SDK 比較。
選擇 OpenAI Agents SDK 當你 100% 使用 OpenAI、希望設定盡可能簡單,且不需要多供應商支援或 DI 時。
組合模式
以下是資深團隊實際的做法:使用 Pydantic AI 建構單一 Agent(程式碼乾淨、可測試、類型化輸出),並使用 LangGraph 進行 Agent 間的協調(路由、狀態機、條件邏輯)。它們並非競爭關係,而是互補的層次。
# Pydantic AI agent -- clean, testable, type-safe
support_agent = Agent("openai:gpt-4o", result_type=SupportResponse, deps_type=SupportDeps)
# LangGraph graph -- orchestrates when to call which agent
graph = StateGraph(SupportState)
graph.add_node("classify", classify_intent)
graph.add_node("support", lambda state: support_agent.run_sync(state["query"]))
graph.add_node("escalate", escalate_to_human)結論:選擇 Pydantic AI 以獲得乾淨、可測試的 Agent 程式碼。選擇 LangGraph 以處理複雜的多步驟工作流程。兩者並非互斥。
使用 TestModel 測試你的 Agent
這是區分初學者指南與生產環境指南的關鍵章節。每個真實的程式碼庫都需要測試,而測試 Agent notoriously 困難,因為 LLM 呼叫速度慢、成本高且具有非確定性。Pydantic AI 提供了解決方案:TestModel。
from pydantic_ai import Agent
from pydantic_ai.models.test import TestModel
from pydantic import BaseModel
class SupportResponse(BaseModel):
answer: str
confidence: float
escalate: bool
agent = Agent("openai:gpt-4o", result_type=SupportResponse)
# In tests: swap the real model for TestModel
def test_support_agent():
with agent.override(model=TestModel()):
result = agent.run_sync("I need help with billing")
# TestModel returns valid structured data matching your result_type
assert isinstance(result.output, SupportResponse)
assert isinstance(result.output.confidence, float)
assert isinstance(result.output.escalate, bool)TestModel 會生成符合你 result_type 的有效資料,且無需進行任何 API 呼叫。零成本、確定性、快速。Pydantic AI 測試文件涵蓋了進階模式,例如用於自訂回應的 FunctionModel 以及用於檢查工具呼叫的 capture_run_messages。
同時測試工具和 DI
def test_order_lookup_tool():
# Mock dependencies
mock_deps = SupportDeps(
customer_id="test-123",
db_connection=MockDB(orders=[{"id": "ord-1", "status": "shipped"}])
)
with agent.override(model=TestModel()):
result = agent.run_sync(
"Where is my order?",
deps=mock_deps
)
assert isinstance(result.output, SupportResponse)沒有 API 呼叫。沒有不穩定的測試。沒有成本。在 CI/CD 中與其餘測試套件一起運行此測試。
這是整個 SERP 上最大的內容缺口。 沒有其他 Pydantic AI 指南涵蓋測試主題。如果你要為生產環境建構 Agent,這就是你需要的內容。
可觀測性:5 分鐘內整合 Logfire
生產環境中的 Agent 需要AI 可觀測性。你希望查看每一次 LLM 呼叫、工具叫用、延遲、Token 數量和成本。Pydantic AI 原生整合 Logfire,這是 Pydantic 團隊的可觀測性平台(基於 OpenTelemetry 建構)。
import logfire
from pydantic_ai import Agent
logfire.configure() # Uses LOGFIRE_TOKEN env var
logfire.instrument_pydantic_ai()
agent = Agent("openai:gpt-4o", result_type=MovieReview)
# Every run is now traced automatically
result = agent.run_sync("Review Inception")只需三行程式碼。你將獲得完整的追蹤記錄,顯示:發送的提示、模型回應、工具呼叫(若有)、驗證通過/失敗、重試、延遲和預估成本。如果 Logfire 不合你的胃口,Langfuse 是一個穩固的開源替代方案,支援上下文工程,可追蹤提示的演變過程。
常見問題
什麼是 Pydantic AI,它與 LangChain 有何不同?
Pydantic AI 是一個類型安全的 Agent 框架,其中 Python 型別提示驅動驗證、工具 Schema 和依賴注入。LangChain 是一個更大的框架,專注於將 LLM 呼叫鏈接在一起。關鍵差異在於:Pydantic AI 在框架層級驗證輸出,並提供內建的依賴注入以提升可測試性,而 LangChain 預設情況下兩者皆無。
如何使用 Pydantic AI 建構類型安全的 AI Agent?
為你的輸出定義一個 Pydantic BaseModel,將其作為 result_type 傳遞給 Agent,並呼叫 run_sync() 或 run()。Agent 將返回你模型的驗證實例,而非原始字串。請參閱「結構化輸出」章節以獲取完整範例。
我應該為生產環境 Agent 使用 Pydantic AI 還是 LangGraph?
對於重視類型安全、可測試性和乾淨程式碼的單一 Agent,請使用 Pydantic AI。對於協調具有條件路由的複雜多步驟工作流程,請使用 LangGraph。許多團隊同時使用兩者,即在 LangGraph 協調層內部使用 Pydantic AI Agent。
Pydantic AI 如何處理工具呼叫和依賴注入?
使用 @agent.tool 裝飾函式,Pydantic AI 會讀取其型別提示以生成工具 Schema。對於 DI,在 Agent 上設定 deps_type 並在工具中接受 RunContext[YourDeps]。執行時期依賴項(資料庫連線、API 客戶端)無需全域狀態即可流動。
如何為 Pydantic AI Agent 添加串流功能?
使用 agent.run_stream() 而非 agent.run()。它返回一個非同步上下文管理器,透過 stream_structured() 或 stream_text() 產生部分結果。最終結果仍會根據你的 result_type 進行完整驗證。
Pydantic AI 在 2026 年是否已具備生產就緒能力?
是的。版本 1.0 已於 2025 年 9 月發布,並承諾 API 穩定性。它由 Pydantic 團隊(下載量最高的 Python 資料驗證庫)支持,目前版本為 v1.74.0 並定期更新。
我可以將 Pydantic AI 與 Ollama 和本地模型一起使用嗎?
可以。使用 Agent("ollama:llama3.1") 並確保 Ollama 在本地運行。安裝 ollama 供應商額外套件:pip install "pydantic-ai[ollama]"。結構化輸出和工具的使用方式與雲端供應商相同。
如何測試 Pydantic AI Agent?
使用 TestModel,這是一個模擬模型,無需 API 呼叫即可生成符合你 result_type 的有效結構化資料。將你的測試包裝在 agent.override(model=TestModel()) 中,並對輸出執行斷言。請參閱「測試」章節以獲取完整的 pytest 範例。
Pydantic AI 能與 FastAPI 配合使用嗎?
完美契合。它們共享相同的依賴注入哲學,且由同一團隊建構。你可以在 FastAPI 端點中使用 Pydantic AI Agent,在它們之間共享依賴類型,並透過 StreamingResponse 串流 Agent 回應。
Pydantic AI 與 OpenAI Agents SDK 有什麼區別?
Pydantic AI 是模型無關的(適用於 OpenAI、Anthropic、Gemini、Ollama 等),具有依賴注入、用於測試的 TestModel 以及 Pydantic 驗證。OpenAI Agents SDK 更簡單,但鎖定於 OpenAI 模型,且缺乏 DI 和內建測試。選擇 Pydantic AI 以獲得靈活性;選擇 OpenAI Agents SDK 以獲得最簡單的僅限 OpenAI 設定。
重點摘要與下一步
| 概念 | 關鍵洞察 | 下一步 |
|---|---|---|
| 結構化輸出 | 你的 result_type 會自動驗證並重試 | 為所有 Agent 輸出定義 Pydantic 模型 |
| 工具 | 型別提示就是 Schema,無需手動定義 | 使用 @agent.tool 和 RunContext 建構工具 |
| 依賴注入 | 明確傳遞執行時期 deps 以提升可測試性 | 為每個 Agent 定義一個 deps_type 資料類別 |
| 測試 | TestModel 消除 CI/CD 中的 API 成本 | 在你的測試套件中添加 agent.override(model=TestModel()) |
| 模型供應商 | 一行程式碼切換模型,無需更改程式碼 | 從 OpenAI 開始,稍後基準測試替代方案 |
| 可觀測性 | 3 行 Logfire 設定即可獲得完整追蹤 | 在生產環境中添加 logfire.instrument_pydantic_ai() |
從一個具有結構化輸出的小型 Agent 開始。添加一個工具。添加依賴項。使用 TestModel 編寫測試。這就是生產環境之路,而你現在擁有走完這條路所需的一切。
官方 Pydantic AI 文件和 GitHub 儲存庫非常適合深入探索。框架發展迅速,因此請將變更日誌加入書籤。