~PythonでのLangGraph活用時にハマるポイントを徹底解説~
LangGraphは、LangChainのワークフロー管理を強化するためのフレームワークです。特に SubGraph
(ネストされたグラフ構造)を活用すると、複雑な処理の分割や管理がしやすくなります。しかし、 Pydantic
を組み合わせた場合、意外な落とし穴にハマることがあります。
本記事では、実際に遭遇したエラーを事例として紹介し、その原因と解決策を詳しく解説します。
🔹 この記事で解説すること
✅ SubGraph
の基本概念と Pydantic
との組み合わせ方
✅ SubGraph
の State
に Pydantic
を使った際の問題点
✅ 実際のエラー事例とその解決策
✅ LangGraph
の最新バージョンでの修正点
これを読めば、 LangGraph
で Pydantic
を適用する際の注意点がクリアになります!
1️⃣ LangGraphのSubGraphとは?
まずは SubGraph
について簡単に整理しておきましょう。
▶ SubGraph の基本概念
LangGraph は、ノード(Node)とエッジ(Edge)を定義することで、処理のフローを構築するフレームワークです。通常のグラフ構造に加えて、あるグラフの中に別のグラフを組み込む「ネスト構造」を作成できます。これを SubGraph
と呼びます。
例えば、以下のような構造を考えてみましょう。
from typing import TypedDict
class GraphState(TypedDict):
key: str
count: int
しかし、 TypedDict
には以下のような制約があります。
🔴 型チェックが緩い(値のバリデーションがない)
🔴 デフォルト値を定義しにくい
🔴 データの変換がしづらい
そこで、 Pydantic
を使うと、型チェックやデフォルト値の管理がしやすくなります。
from pydantic import BaseModel, Field
class GraphState(BaseModel):
key: str
count: int = Field(default=0) # デフォルト値を指定
これにより、State
のデータ構造をより厳密に管理できるようになります。
しかし、 Pydantic
を使った場合に特有の問題が発生します。次のセクションで具体的な事例を見ていきましょう。
3️⃣ エラー事例①:SubGraphのStateのデフォルト値が適用されない
▶ 発生したエラー
Pydantic
の BaseModel
を SubGraph
の State
に使ったとき、本来ならデフォルト値が適用されるはずの value
に None
が入ってしまい、 ValidationError
が発生しました。
from pydantic import BaseModel, Field
class ChildState(BaseModel):
path: list[str]
value: str = Field(default="default value")
# グラフを実行
graph.invoke({"path": []})
# エラー発生
# ValidationError: none is not an allowed value (type=type_error.none.not_allowed)
▶ 原因
LangGraph の State
は、内部的に Pydantic
の通常の初期化とは異なる方法でインスタンスを生成しているため、 Field(default=...)
が適用されません。
▶ 解決策
デフォルト値を明示的に __init__
で設定することで回避できます。
class ChildState(BaseModel):
def __init__(self, **input):
input["value"] = input.get("value") or "default value"
super().__init__(**input)
path: list[str]
value: str
この方法なら、 invoke
実行時に value
のデフォルト値が正しく設定されるようになります。
4️⃣ エラー事例②:親のStateが子のStateのフィールドを持っていないとエラーが発生する
▶ 発生したエラー
親の State
に SubGraph
の State
のフィールドを含めていないと、以下のような InvalidUpdateError
が発生します。
graph.invoke({'path': []}, debug=True)
# エラー発生
# InvalidUpdateError: Expected dict, got
▶ 原因
LangGraph の state.py
では dict
を前提にキーの存在確認を行っています。しかし、 Pydantic
の BaseModel
は辞書型ではないため、期待される処理の分岐に入らずエラーが発生します。
▶ 解決策
親の State
に SubGraph
の State
のフィールドをすべて含めることで回避できます。
class ParentState(BaseModel):
path: list[str]
value: str # 子のStateのフィールドを追加
5️⃣ 最新バージョン(0.1.15 以降)での改善点
LangGraph の 0.1.15
以降では、この State
の取り扱いが改善されました。
✅ BaseModel
を State
に使っても InvalidUpdateError
が発生しないよう修正
✅ SubGraph
の State
のデフォルト値が正しく適用されるよう修正
6️⃣ まとめ|LangGraph × Pydantic の正しい使い方
問題点 | 原因 | 解決策 |
---|---|---|
SubGraph の State のデフォルト値が適用されない |
LangGraph の State の初期化処理が Pydantic と異なる |
__init__ でデフォルト値を明示的に設定する |
親の State に子の State のフィールドがないとエラー |
BaseModel が辞書型ではないため、LangGraph の State チェックでエラーが発生 |
親の State に子の State のフィールドを含める |
0.1.14 以前のバージョンでは BaseModel の State でエラーが発生 |
LangGraph の State 管理が TypedDict を前提に設計されていた |
0.1.15 以降にアップデートする |
💡 LangGraph を Pydantic
と組み合わせる場合は、常に最新バージョンを確認しましょう! 🚀