LangGraphは、生成AI(LLM)を活用したアプリケーションのワークフローを簡潔に定義・実行できるライブラリです。
ワークフローは「ノード」と「エッジ」を使って構築し、エッジによって処理の順序や条件分岐を定義します。
この仕組みによって、複雑なロジックもグラフ(有向グラフ)として整理でき、生成AIを絡めた高度な処理フローもスムーズに表現可能です。
今回は、LLMを使わずにまずはシンプルな関数をノードとして組み込み、基本的な挙動を確認します。
後々、LLMによるテキスト生成や外部APIへの問い合わせなどを繋げる下準備として、まずは基礎構築に慣れてみましょう。
環境
- Python 3.12
- langgraphライブラリ(
poetry add langgraph
などでインストールできます)
最初の一歩:シンプルなグラフ
シンプルなノードとエッジ
以下は、add_one
という単純な関数をノードとしてグラフに追加した例です。
START
からadd_one
へ繋ぐエッジを張ることで、処理の入口としてadd_one
が実行されます。
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START
# 状態を表すためのTypedDict
class State(TypedDict):
total: int
def add_one(state: State):
# totalを1加算する単純な処理
return {"total": state["total"] + 1}
graph_builder = StateGraph(State)
graph_builder.add_node("add_one", add_one)
graph_builder.add_edge(START, "add_one") # START → add_one
graph = graph_builder.compile()
print(graph.invoke({"total": 5}))
実行結果
{'total': 6}
{"total": 5}
が{"total": 6}
に変わりました。
ここで、END
へのエッジを明示しなくても、エラーにはなりません。
add_edge(START, "add_one")
はset_entry_point("add_one")
で置き換えることも可能で、最初に実行されるノードを指定する方法が複数ある点も覚えておきましょう。
これで、START -> add_one -> END
という非常にシンプルなフローが定義できました。
条件分岐を導入する
add_conditional_edges
で条件分岐
LangGraphでは、add_conditional_edges
メソッドを使うことで、特定のノード実行後に条件判定を行い、結果に応じて次のノードを分岐させることができます。
以下の例では、add_five
でtotal
に5を足した後、even_or_odd
関数で偶数・奇数を判定し、その結果に応じてshow_even
またはshow_odd
を呼び出しています。
from typing_extensions import TypedDict
from langgraph.graph import StateGraph
class State(TypedDict):
total: int
def add_five(state: State):
return {"total": state["total"] + 5}
def even_or_odd(state: State):
return "even" if state["total"] % 2 == 0 else "odd"
def show_even(state: State):
print(f"{state['total']} is even")
def show_odd(state: State):
print(f"{state['total']} is odd")
graph_builder = StateGraph(State)
graph_builder.add_node("add_five", add_five)
graph_builder.set_entry_point("add_five")
graph_builder.add_node("show_even", show_even)
graph_builder.add_node("show_odd", show_odd)
graph_builder.add_conditional_edges(
source="add_five", # add_five実行後に条件分岐
path=even_or_odd, # 偶数・奇数を判定する関数
path_map={"even": "show_even", "odd": "show_odd"},
)
graph = graph_builder.compile()
graph.invoke({"total": 6})
実行結果
11 is odd
{'total': 6}
で開始し、add_five
で{'total': 11}
となり、even_or_odd
が"odd"
を返したため、show_odd
ノードが実行されました。
これにより、条件に応じたフロー分岐が簡単に実装できます。
繰り返し処理(ループ)の実装
条件を満たすまで繰り返す
add_conditional_edges
を用いて、特定の条件が満たされるまで同じノードを繰り返すことも可能です。
以下はtotal
が10
を超えるまでadd_one
を繰り返し実行する例です。
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, END
class State(TypedDict):
total: int
def add_one(state: State):
return {"total": state["total"] + 1}
def is_over_10(state: State):
# totalの値分"☆ "を出力し、totalが10を超えるか判定
print("☆ " * state["total"])
return state["total"] > 10
graph_builder = StateGraph(State)
graph_builder.add_node("add_one", add_one)
graph_builder.set_entry_point("add_one")
graph_builder.add_node("is_over_10", is_over_10)
graph_builder.add_conditional_edges(
source="add_one",
path=is_over_10,
path_map={True: END, False: "add_one"},
)
graph = graph_builder.compile()
graph.invoke({"total": 0})
実行結果
☆
☆ ☆
☆ ☆ ☆
☆ ☆ ☆ ☆
☆ ☆ ☆ ☆ ☆
☆ ☆ ☆ ☆ ☆ ☆
☆ ☆ ☆ ☆ ☆ ☆ ☆
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆ ☆
total
が0から始まり、add_one
を繰り返し呼び出してtotal
を increment し続け、is_over_10
がTrueを返すまでループします。
最終的にtotal
が11になった段階で終了しました。
まとめ
- LangGraphは、ノード(関数)とエッジ(処理フロー)によって構造的にワークフローを定義できるライブラリです。
- LLMを用いずとも、基本的なノード追加・条件分岐・ループの仕組みを理解できます。
- 複雑な処理やLLMとの連携を見据える前に、このようなシンプルな例で基礎を固めておくと、後々応用が容易になります。
本記事ではあくまで基本的な使い方の一端を紹介しましたが、LangGraphはこれ以外にもさまざまな機能を持っています。
是非公式ドキュメントや実際のコード例を参照し、LLMや外部APIなどを組み合わせたより高度なワークフロー構築にも挑戦してみてください。
参考リンク
以上で、LangGraphの基本ワークフロー構築例の紹介でした。