🐈

型安全にLLMを扱う:`pydantic_ai`の使い方大全【実例豊富】

に公開
2

LLM をアプリケーションに組み込む際、多くの人が経験しているであろう問題はこれです:

  • モデル出力が「ただの文字列」で扱いにくい
  • JSONに変換させても崩れることが多い
  • 想定外のフォーマットで返ってきてバグる

そんなときに使えるのが pydantic_ai
これは LLMの入出力をPydanticモデルで型安全に扱えるライブラリ です。

この記事では、基本から応用まで 実例たっぷりpydantic_ai を紹介します。


✅ インストール

pip install pydantic-ai

OpenAIを使う場合は、環境変数 OPENAI_API_KEY をセットしてください。


1. 基本:レスポンスを構造化する

from pydantic_ai import Agent
from pydantic import BaseModel

class WeatherInfo(BaseModel):
    location: str
    temperature: float
    condition: str

agent = Agent("openai:gpt-4o-mini", output_type=WeatherInfo)

result = agent.run_sync("東京の天気を教えて")
print(result.output)

出力例

WeatherInfo(location='東京', temperature=29.3, condition='晴れ')

👉 文字列ではなく構造化データ が返るため、そのままDB保存やAPIレスポンスに利用できます。


2. 入力データを渡す(依存性注入)

from dataclasses import dataclass
from pydantic_ai import Agent, RunContext
from pydantic import BaseModel

class Task(BaseModel):
    title: str
    deadline: str

@dataclass
class TaskDeps:
    title: str
    deadline: str

agent = Agent("openai:gpt-4o-mini", deps_type=TaskDeps, output_type=Task)

@agent.system_prompt
def system(ctx: RunContext[TaskDeps]) -> str:
    d = ctx.deps
    return f"次の情報で Task を生成: title={d.title}, deadline={d.deadline}"

result = agent.run_sync(
    "新しいタスクを作成してください",
    deps=TaskDeps(title="月次レポート提出", deadline="2025-09-01"),
)

print(result.output)

出力例

Task(title='月次レポート提出', deadline='2025-09-01')

👉 外部データを依存性として注入しつつ構造化出力 が可能です。


3. 複雑なデータ構造を扱う

from pydantic import BaseModel

class Product(BaseModel):
    name: str
    price: float
    tags: list[str]

class Catalog(BaseModel):
    items: list[Product]

agent = Agent("openai:gpt-4o-mini", output_type=Catalog)

result = agent.run_sync("人気のプログラミング関連商品を3つ紹介してください")
print(result.output)

出力例

Catalog(items=[
    Product(name="Python入門書", price=2500, tags=["python", "book"]),
    Product(name="Raspberry Pi 5", price=8000, tags=["hardware", "iot"]),
    Product(name="VSCode拡張パック", price=0, tags=["editor", "plugin"])
])

4. バリデーションと例外処理

不正な出力は即エラーに。

try:
    result = agent.run_sync("わけのわからない形式で出力して")
    print(result.output)
except Exception as e:
    print("Validation Error:", e)

👉 output_validator によるバリデーションエラー を標準で検出できます。


5. 関数呼び出し(ツール / 出力関数)

関数を呼び出し、その返り値を最終出力にする場合は「出力関数(output function)」として登録します。

from pydantic_ai import Agent

def add_numbers(a: int, b: int) -> int:
    return a + b

agent = Agent("openai:gpt-4o-mini", output_type=add_numbers)

result = agent.run_sync("3と5を足してください")
print(result.output)

出力例

8

👉 OpenAIの「function calling」と同等の仕組みを もっと簡単に 利用できます。


6. ストリーミング応答

# asyncio 環境で
async with agent.run_stream("東京の観光スポットを教えて") as result:
    async for message in result.stream_text():
        print(message)

👉 リアルタイムUIやチャットボット に最適。


7. データ正規化に使う

ユーザー入力を標準化して保存する例。

class User(BaseModel):
    name: str
    email: str
    age: int

agent = Agent("openai:gpt-4o-mini", output_type=User)

result = agent.run_sync("私は田中太郎、30歳、メールは taro at example.com")
print(result.output.model_dump())

出力例

{'name': '田中太郎', 'email': 'taro@example.com', 'age': 30}

👉 入力の揺れを吸収 し、クリーンなデータを得られます。


8. 複数候補を返す(ランキングや提案)

class Idea(BaseModel):
    title: str
    description: str

class IdeaList(BaseModel):
    ideas: list[Idea]

agent = Agent("openai:gpt-4o-mini", output_type=IdeaList)

result = agent.run_sync("新しいSaaSアイデアを5つ提案してください")
print(result.output)

👉 候補リストを構造化して返せる ので、そのままUIに表示可能。


9. 複数ツールの組み合わせ

from datetime import datetime
from pydantic_ai import Agent

def current_time() -> str:
    return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

def multiply(a: int, b: int) -> int:
    return a * b

agent = Agent("openai:gpt-4o-mini", tools=[current_time, multiply])

result = agent.run_sync("今の時刻を表示し、7×8を計算してください")
print(result.output)

👉 エージェントに複数の関数を渡してオーケストレーション が可能です。
(最終出力を関数値にしたい場合は「出力関数」として output_type に登録)


🔥 まとめ

pydantic_ai を使うと…

  • LLM出力を 型安全に 扱える
  • 依存性注入 で応答を制御可能
  • 複雑なJSON構造 を直接取得できる
  • 関数呼び出しやツール連携 が簡単
  • バリデーションで 出力の破損を防止

つまり、従来の「文字列ベースで無理やりパースするコード」から解放され、信頼できるAIアプリ開発 が実現できます。


💡 個人的には、「LLM × APIサーバ」や「LLM × DB」 のケースで特に威力を発揮すると思います。
これからLLMアプリを作る人は、まず pydantic_ai を導入することを強くおすすめします。

Discussion

syakesabasyakesaba

現時点で result_typeresult.dataoutput_typeresult.output に変わってます。
記事を修正してください。

1
SOFTBASESOFTBASE

ご指摘ありがとうございます。最新の仕様に従って修正しました。ありがとうございました。