LangGraphの障害耐性設計:RetryPolicy・TimeoutPolicy・error_handlerが本番エージェントに必要な理由
エージェントがデモを卒業して本番稼働を始めると、「ハッピーパス以外」の問題が一気に押し寄せる。LangGraphはその答えを3つのプリミティブとして整理した。
出典: Fault Tolerance in LangGraph: Retries, Timeouts, and Error Handlers
要点 (事実のみ)
- LangGraphは障害耐性のための3つのプリミティブを提供する:
RetryPolicy(指数バックオフ+ジッター付き自動リトライ)、TimeoutPolicy(ウォールクロックまたは進捗ベースのタイムアウト)、error_handler(リトライ枯渇後に実行されるノード) - 3つはすべて
add_nodeの引数として直接アタッチでき、set_node_defaultsでグラフ全体のデフォルトも設定可能 RetryPolicyのデフォルトretry_onはConnectionErrorや httpx/requests の 5xx など過渡的エラーに限定されており、ValueErrorやRuntimeErrorなどプログラミングバグ系は対象外TimeoutPolicyのidle_timeoutはLangChain LLMモデルのストリームチャンクやチャイルドタスクイベントを「進捗シグナル」としてリセットするため、長時間ストリーミング中の誤タイムアウトを防ぐ- 記事ではSAGAパターンを使ったフライト予約(座席確保→決済→発券)の実装例を示し、
error_handlerからのCommand(goto="compensate")でアトミックな補償処理を実現している
徐 聖博の見解
私がこの記事を読んで最も価値を感じたのは、error_handler の「リトライ枯渇後にしか発火しない」という設計判断と、「失敗写像がチェックポイントにアトミックにコミットされる」という2点だ。
受託開発やAIエージェントの実装を日常的にやっていると、フォールトトレランスのコードがビジネスロジックより長くなる、という記事冒頭の指摘は体感としてよくわかる。これまでは各ノード内に try/except とリトライループを手書きし、しかも「どのステップまで完了したか」を別途ステートで管理する必要があった。LangGraphがこれをノード定義の宣言的設定として吸収したことで、業務ロジックとエラー処理の見通しが格段に良くなる。
特に重要なのはSAGAパターンの例だ。支払い処理や座席確保のような副作用を伴うワークフローでは、「全体をリトライする」設計は必ず破綻する。各ステップが独立したリトライポリシーを持ち、枯渇時に補償ノードへアトミック遷移する構造は、分散システムの教科書的な正解に近い。私たちが企業向けのAIエージェント実装を検討するとき、まさにこの「部分失敗の補償」をどう設計するかが最大の難所になる。ライブラリ側がこの構造を提供してくれるのは、開発工数の観点でも大きい。
一方で、idle_timeout の「進捗シグナル」がLangChain LLMモデルのストリームイベントに依存している点は、サードパーティツールや自前のHTTPクライアントを使う場合に注意が必要だ。その場合は refresh_on="heartbeat" に切り替えて runtime.heartbeat() を明示的に呼ぶ設計にする必要があり、ここは実装時に見落としやすいポイントだと思う。
発注側の意思決定という観点では、「エージェントに外部APIを叩かせる業務自動化」を検討している企業ほど、このような障害耐性の仕組みがフレームワーク側に組み込まれているかどうかを選定基準に入れるべきだ。プロトタイプでは見えない問題が、本番の数十ステップ・長時間実行で一気に顕在化する。
(編集レンズ: 実装・運用視点 / 発注側・中小企業・開発実務への含意)