標準のループから、独自の手順へ

前の節で、モデルとツールの往復を組み立てる標準的なエージェントを学びました。ここでは、その周囲を含めて独自の手順を組みたい場合を考えます。途中で持っておく情報は、第7節で学んだ「状態」につながります。

LangChainのエージェントでは、モデルとツールの往復を比較的少ない設定で構成できます。しかし、すべての仕事が同じループに収まるわけではありません。問い合わせを分類した後で異なる処理へ分ける、必要な情報がそろうまで入力を確認する、回答案を作ってから必ず承認を受ける、といった独自の手順もあります。

LangGraphは、こうした状態を持つ処理を、グラフとして構成するためのフレームワークです。ここでのグラフは、処理のまとまりを点、次へ進む接続を線で表した見取り図です。LangChainで作ったモデル処理やエージェントを、さらに細かい手順の中へ組み込むための仕組みとして理解するとつながります。

node・edge・stateの三つを分ける

node(ノード)は、処理の単位です。質問の分類、資料検索、モデルによる回答作成、結果の検査などを、それぞれのnodeとして表せます。nodeが必ず生成AIである必要はありません。確定したルールで検査する通常の処理も含められます。

edge(エッジ)は、処理の進み方を表します。「分類した後は検索する」という固定した接続も、「資料が見つかったら回答し、見つからなければ不足を伝える」という条件付きの接続もあります。state(ステート)は、その処理の間で引き継ぐ情報です。今回の質問、取得した資料、回答案、処理の状態などを保持します。

重要なのは、stateはモデルの頭の中ではなく、アプリケーションが管理するデータだということです。nodeが状態を読み、必要な更新を返し、次のnodeがその情報を使います。どのnodeが何を変更するかを明確にすると、処理の責任が見えるようになります。

出張相談の例なら、検索nodeの実行前は「質問はあるが資料は未取得」、実行後は「質問と取得した資料がある」という状態になります。回答nodeはその資料を読み、回答案を状態へ追加します。処理が次へ進むことがedge、引き継ぐ情報がstateだと区別できます。途中の項目を書き残すだけなら、モデルに新しい事実を学習させたことにはなりません。

分岐と繰返しを、制御できる形で表す

たとえば、質問に必要な条件が足りなければ追加質問へ進み、条件がそろえば資料を検索し、根拠が足りれば回答する、という経路を考えます。どの時点で分岐し、何を条件として次へ進むかをグラフに表すことで、生成だけに手順を委ねずに構成できます。

一部の分岐をモデルの分類結果に基づいて決めることもできますが、その場合でも、許可する分類や遷移先はアプリケーションが定義します。モデルがどんな文字列を返しても、任意の処理へ進めるようにする必要はありません。柔軟な判断と、決められた経路を組み合わせることができます。

繰返しでは、状態が変わる条件と終了条件が重要です。検索を続けても、必要な資料が存在するとは限りません。試行回数、時間、必要情報の有無などで打ち切る経路を用意します。

checkpointerは、処理の状態を再開につなぐ

LangGraphは、checkpointerを通してthreadの状態を記録できます。会話の継続に加え、人の確認で待機する処理や、途中で中断した処理の再開にも関わります。「この申請についてどこまで処理したか」を保存することで、新しいプロセスでも続きを判断できる構成を作れます。

ただし、状態を保存することと、外部で行った処理をすべて元に戻せることは別です。メールを送信したという外部の事実は、stateを以前の値に戻しても取り消されません。保存した状態と、外部システムの状態の両方を考える必要があります。

いつLangGraphを直接扱うのか

標準のツール利用ループで目的を満たせるなら、最初から独自のグラフを書く必要はありません。LangChainのcreate_agentを使い、必要な制御を設定する方法で進められます。一方、決まった業務手順を厳密に表したい、複数の処理を特定の条件で組み合わせたい、といった場合には、LangGraphを直接扱う意味が出てきます。

LangChainで構成したエージェントを、より大きなグラフの一つの処理として利用することもできます。どちらか一方しか使えないという関係ではありません。次の節では、この状態と再開の仕組みを利用した、人の確認を挟む処理を説明します。