【型安全】Pydantic AI超入門!Pythonで堅牢なマルチエージェント・RAGを構築する実践ガイド
1. はじめに:なぜLLM開発に「Pydantic AI」が必要なのか?
AIエージェントやRAG(Retrieval-Augmented Generation)のシステム開発において、開発者を最も悩ませるのが「LLMの出力の不安定さ」です。プロンプトで「JSON形式で返却してください」と指示しても、時として余計なテキストが混ざったり、キーの名前が変わったりして、システムがクラッシュすることがあります。
この課題を解決するために登場したのが、Pythonのデータバリデーションライブラリとして絶大な人気を誇るPydanticの公式開発チームが手がけた Pydantic AI です。
Pydantic AIは、LLMの入出力をPythonの「静的型付け」によって厳密に管理し、型安全なAIエージェント開発を実現します。本記事では、Pydantic AIの基本的な使い方から、実務に役立つコンテキスト注入、マルチエージェントへの応用、そして開発時によく遭遇するエラーの対策まで徹底的に解説します。
2. Pydantic AIのコアコンセプトと特徴
Pydantic AIは、LangChainやLlamaIndexなどの既存フレームワークに比べ、非常にシンプルで直感的な設計になっています。その特徴は以下の3点に集約されます。
- 「型安全な構造化出力 (Structured Outputs)」
LLMからのレスポンスをPydanticのモデル(
BaseModel)として直接受け取れます。パースエラーが発生した場合は、自動的にLLMへ再試行(リトライ)を促す仕組みが内蔵されています。 - 「依存関係の注入 (Dependency Injection)」
テストや本番環境でデータベース接続、外部APIクライアントなどを動的に切り替える仕組み(
Deps)が標準提供されています。 - 「コントロールの容易さ」 過度に抽象化されたマジック(魔法)が少なく、通常のPythonコードと同じ感覚でデバッグやカスタマイズが可能です。最新のLLMフレームワークのトレンドについては、smolagents入門記事 でも紹介されていますが、Pydantic AIは特にプロダクション環境における堅牢性に強みを持っています。
ソースコードは Pydantic AI GitHubリポジトリ で公開されており、急速にコミュニティが拡大しています。
3. 環境構築とクイックスタート
まずは、Pydantic AIをインストールしましょう。今回はOpenAIのAPIを利用する前提でセットアップを進めます。
pip install pydantic-ai openai python-dotenv
環境変数にOpenAIのAPIキーを設定します。
OPENAI_API_KEY=your-api-key-here
シンプルな型安全エージェントの実装
まずは、ユーザーの入力から「ユーザー情報」を構造化データとして抽出する簡単なコードを書いてみましょう。
import os
from pydantic import BaseModel, Field
from pydantic_ai import Agent
from dotenv import load_dotenv
load_dotenv()
# 1. 期待する出力のスキーマをPydanticで定義
class UserProfile(BaseModel):
name: str = Field(description="ユーザーの名前")
age: int = Field(description="ユーザーの年齢(推定も含む)")
skills: list[str] = Field(default=[], description="プログラミングスキルや得意技術")
# 2. エージェントの初期化
# result_typeにPydanticモデルを指定することで、戻り値の型が固定されます
agent = Agent(
'openai:gpt-4o-mini',
result_type=UserProfile,
system_prompt="ユーザーの自己紹介文からプロフィール情報を正確に抽出してください。"
)
# 3. エージェントの実行
result = agent.run_sync("私の名前は田中です。32歳で、PythonとGo言語を普段書いています。")
# 結果の取得(型安全にアクセス可能)
profile: UserProfile = result.data
print(f"名前: {profile.name}")
print(f"年齢: {profile.age}")
print(f"スキル: {', '.join(profile.skills)}")
このコードを実行すると、LLMが返したテキストが自動的に UserProfile のインスタンスにマッピングされます。IDEの型補完(IntelliSense)が効くため、エディタ上で profile. と入力するだけでプロパティが候補に現れます。
4. 【応用】依存関係(Deps)の注入とRAGの実装
実務におけるAIエージェントでは、データベースのクエリ結果や、外部APIから取得した情報をプロンプトに組み込む必要があります。Pydantic AIでは、Deps(Dependencies)オブジェクトを使用して、これらを安全にエージェント内へ注入できます。
以下は、ナレッジベース(疑似的なデータベース)から情報を検索し、それをもとに回答するシンプルなRAGシステムの例です。
from dataclasses import dataclass
from pydantic_ai import Agent, RunContext
# 1. 依存関係のコンテキストを定義
@dataclass
class DatabaseConnection:
knowledge_base: dict[str, str]
def query(self, topic: str) -> str:
return self.knowledge_base.get(topic, "該当する情報が見つかりませんでした。")
# 2. エージェントの作成。deps_typeで注入する型を明示
rag_agent = Agent(
'openai:gpt-4o-mini',
deps_type=DatabaseConnection,
system_prompt="提供されたコンテキスト情報のみを使用して、ユーザーの質問に回答してください。"
)
# 3. システムを補助する「システムツール(Tool)」の定義
@rag_agent.tool
def search_knowledge_base(ctx: RunContext[DatabaseConnection], topic: str) -> str:
"""ナレッジベースから特定のトピックに関する情報を検索します。"""
# 引数 ctx から安全にデータベース接続を取り出す
return ctx.deps.query(topic)
# 4. 実行環境のセットアップと実行
db = DatabaseConnection(
knowledge_base={
"pydantic-ai": "Pydantic AIは、PythonのPydanticチームが開発した型安全なLLMエージェント構築フレームワークです。",
"o3-mini": "o3-miniはOpenAIが開発した最新の推論(Reasoning)モデルです。"
}
)
# 実行時にdepsを渡す
response = rag_agent.run_sync(
"Pydantic AIとは何ですか?詳しく教えてください。",
deps=db
)
print(response.data)
このアプローチの素晴らしい点は、テストの際に DatabaseConnection のモック(Mock)を簡単に渡せる点です。ユニットテストが極めて書きやすくなり、プロダクション環境のコード品質が向上します。
(なお、OpenAIのReasoningモデルを活用したい場合は、OpenAI「o3-mini」APIの実装ガイド も参考になります。)
5. よくあるエラーとトラブルシューティング
Pydantic AIの導入時に直面しやすいエラーと、その原因および解決策を解説します。
エラー例1: ValidationError (LLMの出力フォーマット崩れ)
【現象】
LLMが期待通りのJSONフォーマットを返さず、Pydanticがパースを試みた際に pydantic_core._pydantic_core.ValidationError が発生する。
【原因】 使用しているLLMのモデルが構造化出力(Structured Outputs)に完全に対応していない、またはプロンプトが複雑すぎてパースに失敗している。
【解決方法】
-
APIの構造化出力機能を有効化する: Pydantic AIは、OpenAIなどの
response_format={"type": "json_schema", ...}を自動で利用します。可能であれば、構造化出力にネイティブ対応しているモデル(例:gpt-4o,gpt-4o-mini)を使用してください。 -
リトライ回数を増やす: エージェント定義時に
retriesパラメータを設定することで、パースエラー発生時に自動でエラーメッセージをLLMへフィードバックし、再生成させることができます。agent = Agent( 'openai:gpt-4o-mini', result_type=UserProfile, retries=3 # パースエラー時に最大3回自動リトライ )
エラー例2: RunContext の型不一致エラー
【現象】
ツール(@agent.tool)内で ctx.deps にアクセスした際、AttributeError が発生する、または静的解析ツール(Mypy / Pyright)に警告される。
【原因】
ツールの第一引数である ctx: RunContext[DepsType] の型注釈が、Agent(deps_type=DepsType) で指定した型と一致していない。
【解決方法】 ツールの型定義を厳密に揃えてください。
# 誤り
@agent.tool
def my_tool(ctx: RunContext, query: str): ...
# 正しい
@agent.tool
def my_tool(ctx: RunContext[MyDatabaseType], query: str): ...
6. まとめ:堅牢なAIエージェントの未来へ
Pydantic AIは、これまで「ブラックボックスで不安定」とされてきたLLMアプリケーションに、「静的型付け」という強力な盾をもたらします。
- 期待する出力を Pydantic で宣言する
result_typeで出力を完全に保証するDepsを使ってモックや外部依存を安全に注入する
これらのアプローチにより、複数人のチーム開発や、ミッションクリティカルなシステムへのAIエージェント導入が劇的に容易になります。
LLMの能力が向上する現代だからこそ、アプリケーションの基盤には信頼性の高い「型」が必要です。ぜひ本記事を参考に、あなたのPythonプロジェクトにPydantic AIを取り入れ、堅牢なAIアプリケーションを構築してみてください!
参考文献
- Pydantic AI Documentation (公式ドキュメント)
- Pydantic GitHub Repository (GitHub)