ジェネラティブエージェンツの大嶋です。
運営している勉強会コミュニティStudyCoで「【LangChainゆる勉強会#12】LangGraphの最新ドキュメントを全体的にざっと読む」というイベントを開催しました。
アーカイブ動画はこちらです。
LangGraphは最近アップデートが活発で、ドキュメントも充実してきています。 LangGraphのドキュメントに一通り目を通す時間を作ろうと、この勉強会を開催しました。
今回LangGraphのドキュメントを読んでみて、「この機能はあまり知られていなそうだな」と感じたものを、3つほどピックアップしてこの記事で紹介します。
Send APIによる動的なエッジの構成
まず、Send APIについてです。
LangGraphでは基本的な使い方として、「add_conditional_edges」を使って、条件に応じてノードを選択するエッジを作成します。 しかし、単純にadd_conditional_edgesを使うだけでは、「実行時にノードの数を動的に変更したい」といったことはできません。
そのように、より動的にエッジを構成するために、LangGraphでは「Send API」が提供されています。 Send APIのコンセプトは以下のページで解説されています。
上記のページでは、Send APIを使う一般的な例として、map-reduceが挙げられています。 map-reduceでは、mapの処理として「同じ処理を実行するノードを、データの数だけ用意して実行する」ということになり、これはまさに動的にエッジを構成する例です。
map-reduceの実装例は、次のページに掲載されています。
ステートの共有
次に、ステートの共有についてです。
チャットボットなどのアプリケーションを提供するうえで、「スレッド内の会話履歴を記憶させたい」というのに加えて、「スレッドをまたいでユーザー単位で記憶を共有したい」といったケースが考えられます。 そのようなケースのサンプルコードが以下のページに掲載されています。
上記のページのコードから、とくに重要な箇所を簡単に説明します。
まず、グラフのステートとして、「SharedValue」という、あるキーをもとにシェアする値を定義します。
from langgraph.managed.shared_value import SharedValue class AgentState(MessagesState): info: Annotated[dict, SharedValue.on("user_id")]
実行時のconfigで、SharedValueで指定したキーに適当な値を設定します。
config = {"configurable": {"thread_id": "1", "user_id": "1"}} for update in graph.stream({"messages": [{"role": "user", "content": "hi"}]}, config, stream_mode="updates"): print(update)
このようにSharedValueを使うことで、「スレッドをまたいでユーザー単位で記憶を共有する」という実装ができるということです。
NodeInterruptによる動的なブレークポイントの設定
最後に、NodeInterruptについてです。
LangGraphでは、「interrupt_before」という設定によって、あるノードに処理がきた際に、処理を中断することができます。
より動的に処理を中断する方法として「NodeInterrupt」が提供されています。 サンプルコードは次のページに掲載されています。
こちらも、上記のページのコードから、とくに重要な箇所を簡単に説明します。
from langgraph.errors import NodeInterrupt def step_2(state: State) -> State: if len(state['input']) > 5: raise NodeInterrupt(f"Received input that is longer than 5 characters: {state['input']}") print("---Step 2---") return state
簡単に言えば、NodeInterruptをraiseすると、動的にグラフの実行をinterruptできるということです。
ノードの遷移のタイミングで処理を中断したい場合は「interrupt_before」を使えば十分ですが、より動的な制御が必要な場合は「NodeInterrupt」を使えるということになります。
おわりに
以上、LangGraphのあまり知られていなそうな機能を3つ紹介しました。
今回の勉強会は「LangGraphの最新ドキュメントを全体的にざっと読む」というテーマだったため、1つ1つの内容は深堀りできませんでした。 開催後のアンケートでも、「このあたりを深堀りしてほしい」といった意見をいくつかいただいており、もう少し深堀りする会も開催したいと考えています。
LangChain / LangGraph、その他のテーマで引き続き勉強会を開催していきます。 LangGraphの話でもLangGraph以外の話でも、もしも「こんな話が聞きたい」というテーマがあれば、ぜひお声がけください!