Pydantic AI と LangGraph/LangChain

🧑 User

2026-11-08T05:29:21.791042Z

Pydantic AI とはどのようなパッケージですか?


🤖 Claude

2026-11-08T05:29:33.778925Z

Pydantic AI は、Pydantic の開発チームが作っている、型安全なエージェント構築用の Python フレームワークです。Pydantic をベースに、入力・出力・ツールのスキーマを構造化して扱えます。目指しているのは「LLM 向けの FastAPI」のような開発体験です。モデル非依存で、OpenAI、Anthropic、Google、Groq、Mistral、Ollama などで動きます。

主な特徴

位置づけ

LangChain や LlamaIndex より小さく、Python らしい書き方に寄せた設計です。ライセンスは MIT です。2024 年末に始まり、2025 年に 1.0 が出ました。

LangGraph との比較では、Pydantic AI は小さく型安全で習得が早く、複雑なステートマシンや human-in-the-loop は LangGraph が得意とされています。

最小コード例

from pydantic import BaseModel
from pydantic_ai import Agent

class Answer(BaseModel):
    city: str
    population: int

agent = Agent('anthropic:claude-sonnet-5-5', output_type=Answer)
result = agent.run_sync('インドの首都と人口は?')
print(result.output)

インストールは pip install pydantic-ai です。

LangGraph や CrewAI、MCP を使われているようなので、Pydantic AI も MCP クライアントとしてツール連携できます。LangGraph との使い分けや、既存の構成への組み込み方も整理できます。

Sources:


🧑 User

2026-11-08T05:30:13.798644Z

Pydantic AI を LangGraph/LangChain と組み合わせて使うことができますか?


🤖 Claude

2026-11-08T05:30:29.331677Z

はい、組み合わせられます。ただし、公式の「統合パッケージ」で繋ぐというより、自分でノードやツールの境界に差し込む形になります。検索で見つけた範囲では、公式の連携手順をまとめた資料は見つかりませんでした。以下のパターンは、両者の設計から考えたものです。

位置づけの違い

組み合わせパターン

  1. LangGraph のノード内で Pydantic AI の Agent を呼ぶ
    ノード関数の中で agent.run_sync(...) や await agent.run(...) を呼び、result.output(Pydantic モデル)を State に格納します。分岐、状態管理、human-in-the-loop は LangGraph に任せ、構造化出力の検証とリトライは Pydantic AI に任せられます。

  2. LangChain のツール資産を Pydantic AI で使う
    Pydantic AI は型注釈付きの関数をツールにできます。LangChain ツールは、薄いラッパー関数で包めば呼べます。MCP サーバー経由でツールを共通化する方法もあります。例えばComposio は、LangChain 向けには provider パッケージ、Pydantic AI 向けには MCP ツールセットで、両方に同じツール基盤を提供しています。

  3. MCP を共通のツール層にする
    ご自身の構成(ServiceNow、AWX、GitHub 連携など)なら、ツールを MCP サーバーとして公開すれば、LangGraph 側と Pydantic AI 側のどちらからも同じツールを使えます。フレームワークを混在させても、ツール実装が二重にならずに済みます。

注意点

使い分けの目安

LangGraph が複雑な状態遷移や human-in-the-loop に強く、Pydantic AI は型安全性と軽さに強い、というのが共通した評価です。LangChain 1.0 は内部で LangGraph を使っているので、まず LangChain の簡単なインターフェースから始め、必要なときに LangGraph へ降りるという使い方もできます。

必要なら、LangGraph のノードから Pydantic AI の Agent を呼ぶ最小コード例を書きます。

Sources:


🧑 User

2026-11-08T05:39:39.732811Z

LangGraph のノードから Pydantic AI の Agent を呼ぶ最小コード例を書いてください


🤖 Claude

2026-11-08T05:40:39.408974Z

📁 添付(本文非取得): fbfc83fa-1641-565c-b2a9-e5579f11b54e

📁 添付(本文非取得): 10dde217-c9ea-4782-9c35-38f85f084135

langgraph_pydantic_ai.py を送りました。

構成

動作確認
Pydantic AI の TestModel で LLM を差し替え、グラフ全体を実行しました。ノード呼び出し、型付き出力の受け渡し、分岐は意図どおり動きました。実際の LLM への接続は API キーがないため試していません。

実行方法
pip install langgraph pydantic-ai のあと、ANTHROPIC_API_KEY を設定して python langgraph_pydantic_ai.py を実行します。別のプロバイダーを使う場合は、冒頭の MODEL 文字列(例: openai:...)を変更してください。

次のステップとして、ノード内で Pydantic AI に MCP サーバーのツールを持たせる形にもできます。


🧑 User

2026-11-08T08:53:46.799678Z

pydantic_ai.Agent に instructions 引数で与えたプロンプト文をシステムプロンプトとしてLLMに入力するコード、及び、pydantic_ai.Agent.tool_plain に引数としてあたえた Callable がLLMのツールとして動作するようにしているコードは、GitHub の何処にありますか?


🤖 Claude

2026-11-08T08:54:37.520838Z

調査はほぼ終わっています。最後に、Anthropic 側でシステムプロンプトを組み立てている箇所の行番号を確認します。

pydantic/pydantic-ai リポジトリのコードを clone して該当箇所を確認しました。確認したのは main の 0f7648a(2026-11-08 時点)です。行番号はこのコミットのもので、更新されるとずれます。パスはすべて pydantic_ai_slim/pydantic_ai/ 配下です。

1. instructions がシステムプロンプトになる流れ

段階 場所 内容
受け取り agent/__init__.py 約 812 行(Agent.__init__) instructions 引数を _instructions.normalize_instructions(...) で正規化し、self._instructions に保存します。
型と正規化 _instructions.py AgentInstruction(str、関数、InstructionPart など)の定義と、normalize_instructions があります。
実行時に解決 _agent_graph.py の _get_instructions(約 1408 行) エージェント側の instructions と、ツールセット側の instructions を結合します。
リクエストに格納 _agent_graph.py 約 2942〜2945 行 self.request.instructions = InstructionPart.join(instruction_parts) で、ModelRequest.instructions に入れます。
モデル共通の取り出し models/__init__.py の _get_instruction_parts(約 2208 行) 各プロバイダー実装が使う共通ヘルパーです。
プロバイダーごとの変換 Anthropic: models/anthropic/__init__.py(_map_message が system_prompt を作り、約 1712 行で 'system': ... として送ります)。OpenAI: models/openai.py 約 2632 行 OpenAI は system や developer ロールのメッセージにします。Google、Groq、Mistral などは各ファイルで _get_instruction_parts を呼びます。

つまり、instructions はメッセージ履歴の一部として保存されず、各リクエストごとにその時点の値から組み立てられます。この点が system_prompt 引数との違いです。

2. tool_plain に渡した関数が LLM のツールになる流れ

段階 場所 内容
デコレータ agent/__init__.py 3270 行付近(Agent.tool_plain) 内部の tool_decorator が、self._function_toolset.add_function(...) を呼びます。
登録 toolsets/function.py 614 行(FunctionToolset.add_function) 関数を Tool オブジェクトにして登録します。
スキーマ生成 tools.py 355 行の Tool クラス。その中で _function_schema.function_schema(...) を呼びます。実体は _function_schema.py 110 行 型ヒントから Pydantic の検証器 SchemaValidator と JSON スキーマを作り、docstring から説明文を取り出します。
LLM 向け定義 toolsets/function.py 769 行(get_tools) 各ツールから ToolDefinition(名前、説明、parameters_json_schema)を作ります。ToolDefinition の定義は tools.py 700 行です。
プロバイダー形式へ変換 Anthropic: models/anthropic/__init__.py 3861 行(_map_tool_definition) name、description、input_schema を持つ BetaToolParam にします。
ツール呼び出しの受付 tool_manager.py 352 行(ToolManager)、handle_call(1348 行)、1326 行付近の self.toolset.call_tool(...) LLM が返したツール呼び出しを受け、ツールセットに渡します。
実行 toolsets/function.py 851 行(call_tool)→ tool.call_func → _function_schema.py 81 行(call) 引数を検証したうえで、同期関数は run_in_executor で、非同期関数は await で実行します。

読む順番のおすすめ

  1. 指示文: _agent_graph.py の _get_instructions、次に models/anthropic/__init__.py の _map_message。
  2. ツール: _function_schema.py の function_schema が最も核心です。型ヒントがスキーマに変わり、同じ関数がそのまま呼ばれる仕組みがここにあります。

Sources: