Pydantic AI 多模態輸入與輸出

現代的大型語言模型(LLM)如 GPT-4o 或 Gemini 1.5 Pro 已經不再侷限於處理純文字,而是演進成了強大的「多模態 (Multimodal)」模型。它們不僅能夠「看」懂圖片、「聽」懂語音片段,甚至能分析整段影片、文件,還能為你「生成」全新的圖片。

Pydantic AI 將這些多模態輸入的支援無縫整合到了 Agent 的執行流程中,讓你可以非常直覺地傳遞非文字的資料給模型。

傳遞多模態輸入的基本概念

在處理單純文字的應用場景中,當我們呼叫 run_syncrun 時,傳入的第一個參數通常是單純的字串:

# 純文字輸入
agent.run_sync("請幫我寫一首關於海洋的詩")

當需要傳遞多模態資料(例如文字搭配圖片)時,我們需要將輸入參數改為一個陣列 (List)。這個陣列中可以混搭字串與 Pydantic AI 提供的多模態輔助類別,模型會依照你傳入的順序來解讀這些內容。

Pydantic AI 根據資料的來源,主要提供兩大類的輸入方式:

  • URL 型態 (ImageUrl, AudioUrl, DocumentUrl 等):當你的檔案已經發佈在公開網路上時使用。
  • 二進位型態 (BinaryContent):當你需要讀取本地端檔案,或是直接傳遞檔案的二進位內容 (Bytes) 時使用。

處理圖片輸入

如果圖片已經有公開的網址,你可以使用 ImageUrl 類別,直接將網址提供給模型。這在分析網路資源或社群媒體上的圖片時非常方便。

範例:分析網路圖片 (ImageUrl)

以下範例展示了如何讓 AI 幫忙分析一張網路圖片:

from pydantic_ai import Agent
from pydantic_ai.messages import ImageUrl

# 建立 Agent,使用具備視覺能力的 GPT-4o 模型
agent = Agent('openai:gpt-4o')

# 準備一組混合了文字與圖片的輸入陣列
user_input = [
    "請詳細描述這張圖片中出現的動物,並猜測這張照片是在什麼環境下拍攝的?",
    # 傳入圖片的公開網址
    ImageUrl('https://example.com/photos/wildlife.jpg')
]

# 將陣列作為 Prompt 傳入 Agent
result = agent.run_sync(user_input)
print(result.data)
強制下載 (force_download) 有些模型供應商可能無法直接存取你提供的 URL(例如遇到防爬蟲機制或需要登入的網站)。你可以加上 force_download=True,讓 Pydantic AI 應用程式先在伺服器端下載該檔案,再將內容轉交給模型。 範例寫法:ImageUrl('https://example.com/img.png', force_download=True)

處理本地端檔案與文件

在實際的商業應用中,我們經常需要處理本地端的檔案,例如使用者上傳的發票圖片、或是需要從內部伺服器讀取的 PDF 報表。這時候使用 BinaryContent 是最適合的做法。這在處理敏感文件或不對外公開的檔案時非常有用。

範例:分析本地端 PDF 文件 (BinaryContent)

下方範例展示了如何讀取一份本地的 PDF 文件,並請 AI 總結內容:

from pathlib import Path
from pydantic_ai import Agent, BinaryContent

# 建立 Agent,使用 Claude 模型
agent = Agent('anthropic:claude-3-5-sonnet-latest')

# 讀取本地端的 PDF 檔案
pdf_path = Path('financial_report.pdf')

user_input = [
    "請幫我從這份財務報表中,提取出『本季總營收』與『淨利潤』。",
    # 傳入二進位資料並明確指定 MIME type
    BinaryContent(
        data=pdf_path.read_bytes(),
        media_type='application/pdf'
    )
]

result = agent.run_sync(user_input)
print(result.data)

在使用 BinaryContent 時,強烈建議提供正確的 media_type(例如 application/pdf, image/png, audio/wav),以確保底層模型能夠正確解析該檔案格式。

處理語音輸入

現代語言模型也能直接「聽」音訊檔案。你可以將使用者的客服錄音檔傳給模型,它不僅能轉譯成文字,還能分析講者的情緒與語氣,大幅簡化傳統的語音處理流程。

範例:轉譯語音並進行情緒分析

以下範例示範了如何讀取一段 MP3 錄音檔,並交由模型進行多維度的分析:

from pathlib import Path
from pydantic_ai import Agent, BinaryContent

# 使用支援多模態的 Gemini 模型
agent = Agent('gemini-1.5-pro')

# 讀取本地端的音訊檔
audio_path = Path('customer_support.mp3')

user_input = [
    "請幫我完成以下任務:\n"
    "1. 將這段客服通話轉譯為逐字稿。\n"
    "2. 分析這位客戶的情緒是憤怒、平靜還是開心?\n"
    "3. 總結客戶的主要訴求。",
    # 傳入音訊的二進位資料與對應的 MIME type
    BinaryContent(
        data=audio_path.read_bytes(),
        media_type='audio/mp3'
    )
]

result = agent.run_sync(user_input)
print(result.data)

處理圖片生成 (多模態輸出)

除了接收與理解多模態的輸入資料外,Pydantic AI 也支援多模態的「輸出」,例如讓模型根據提示詞為你生成圖片。透過內建的 ImageGenerationTool 搭配 BinaryImage 型別,你可以很輕易地將圖片生成的步驟無縫整合進 Agent 的工作流程中。

範例:指定圖片生成模型

在這個範例中,我們會為主線對話模型配置一個產生圖片的內建工具,並明確指定該工具要使用的底層圖片生成模型(例如 gpt-image-2)。透過設置 action='generate',我們可以強制模型直接執行生成動作,而不必讓模型自己猜測是否要呼叫工具。

from pydantic_ai import Agent, BinaryImage, ImageGenerationTool

# 建立 Agent,並設定對話主線模型
agent = Agent(
    'openai-responses:gpt-5',
    builtin_tools=[
        ImageGenerationTool(
            model='gpt-image-2', # 明確指定底層圖片模型
            action='generate',   # 強制生成,不讓模型猜測
            quality='high',      # 指定圖片品質
            size='1024x1024',    # 指定圖片解析度
            output_format='webp',# 指定輸出的圖片格式
        )
    ],
    # 限制模型最終必須回傳一張圖片
    output_type=BinaryImage,
)

# 執行任務
result = agent.run_sync('畫一隻在下雨天撐紅色雨傘的柴犬')

# 將生成的圖片二進位資料寫入本地端檔案
with open('dog.webp', 'wb') as f:
    f.write(result.output.data)

支援的媒體類別總覽

總結來說,Pydantic AI 框架提供以下幾種常用的輔助類別,幫助你應對各種多模態的開發情境:

  • 網路連結型
    • ImageUrl:支援常見的圖片格式 (JPEG, PNG, WebP 等)。
    • AudioUrl:支援音訊檔,讓模型直接進行語音辨識或情緒分析。
    • VideoUrl:支援影片片段分析。
    • DocumentUrl:支援線上文件(如公開的 PDF 連結)。
  • 二進位資料型
    • BinaryContent:通用的二進位內容容器,適用於本地端讀取的圖片、語音、PDF、文字檔等。只要填入 data 與對應的 media_type 即可通用。

注意事項與最佳實踐

在開發多模態 AI 應用程式時,有一些實務上的細節需要特別注意:

  • 模型支援度:並非所有的 LLM 都支援所有的檔案類型。例如,某些模型僅支援圖片,但尚未支援音訊或影片。在撰寫程式碼前,請務必確認你選用的模型供應商 (Provider) 有正式支援該媒體類型。
  • 檔案大小限制:各大模型 API 通常對上傳的檔案大小有嚴格限制(例如單張圖片不超過 20MB,音訊不超過 25MB 等)。在開發上線系統時,務必在接收檔案的階段加入大小的檢查與防護機制,避免 API 請求失敗。
  • 標註 MIME 類型:雖然 Pydantic AI 或模型有時可以從附檔名自動推斷出格式,但為了系統的穩定性,當你使用 BinaryContent 時,手動明確指定 media_type 永遠是最好的習慣。