LESSON 30分

ストーリー

田中VPoE
ここまでエージェントの設計パターンとツール実装を学んだ。次は、これらを実際に組み合わせてワークフローとして構築する方法を学ぶ
あなた
ワークフローの構築フレームワークがあるんですか?
田中VPoE
LangGraphだ。LangChainチームが開発したエージェントワークフロー構築フレームワークで、グラフベースでエージェントの行動フローを定義できる
あなた
グラフベースということは、ノードとエッジでフローを構築するんですね
田中VPoE
その通り。各ノードが「LLM呼び出し」「ツール実行」「条件判断」などの処理を担当し、エッジがノード間のデータの流れを定義する。複雑なエージェントワークフローを可視化しやすく、保守しやすい設計になる

LangGraphとは

基本概念

LangGraphは、ステートフルなエージェントワークフローをグラフ構造で定義・実行するフレームワークです。

LangGraphの構成要素:

[StateGraph]
  ├── State(状態): ワークフロー全体で共有されるデータ
  ├── Node(ノード): 処理を行う関数
  ├── Edge(エッジ): ノード間のデータの流れ
  └── Conditional Edge: 条件に応じた分岐

LangChainとの関係

項目LangChainLangGraph
目的LLMアプリケーション開発の汎用フレームワークエージェントワークフロー専用
構造チェーン(直線的なパイプライン)グラフ(分岐・ループを含むフロー)
状態管理限定的ファーストクラスサポート
適するケースRAG、プロンプトチェーンマルチステップエージェント、複雑なワークフロー

StateGraphの基本

State定義

ワークフロー全体で共有する状態(State)を定義します。

from typing import Annotated, TypedDict
from langgraph.graph import StateGraph
from langgraph.graph.message import add_messages

# State定義: ワークフロー全体で共有されるデータ構造
class AgentState(TypedDict):
    messages: Annotated[list, add_messages]  # メッセージ履歴(自動追記)
    current_step: str                         # 現在のステップ
    order_data: dict | None                   # 取得した注文データ
    final_response: str | None                # 最終回答

ノード定義

各ノードはStateを受け取り、更新されたStateを返す関数です。

from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, AIMessage

llm = ChatOpenAI(model="gpt-4o")

# ノード1: LLMで意図を分析
def analyze_intent(state: AgentState) -> AgentState:
    messages = state["messages"]
    response = llm.invoke(messages)
    return {
        "messages": [response],
        "current_step": "intent_analyzed"
    }

# ノード2: 注文を検索
def search_order(state: AgentState) -> AgentState:
    # messagesから注文番号を抽出して検索
    order_data = {"order_id": "ORD-12345", "status": "shipped"}
    return {
        "order_data": order_data,
        "current_step": "order_searched"
    }

# ノード3: 最終回答を生成
def generate_response(state: AgentState) -> AgentState:
    order_data = state.get("order_data", {})
    messages = state["messages"] + [
        HumanMessage(content=f"注文データ: {order_data}。これを基に顧客に回答してください。")
    ]
    response = llm.invoke(messages)
    return {
        "messages": [response],
        "final_response": response.content
    }

グラフの組み立て

from langgraph.graph import END

# グラフの作成
workflow = StateGraph(AgentState)

# ノードの追加
workflow.add_node("analyze_intent", analyze_intent)
workflow.add_node("search_order", search_order)
workflow.add_node("generate_response", generate_response)

# エッジの定義(ノード間の接続)
workflow.set_entry_point("analyze_intent")
workflow.add_edge("analyze_intent", "search_order")
workflow.add_edge("search_order", "generate_response")
workflow.add_edge("generate_response", END)

# グラフのコンパイル
app = workflow.compile()

実行

# ワークフローの実行
result = app.invoke({
    "messages": [HumanMessage(content="注文ORD-12345の状況を教えてください")],
    "current_step": "start",
    "order_data": None,
    "final_response": None
})

print(result["final_response"])

グラフの可視化

LangGraphはワークフローをMermaid図として可視化できます。

# グラフの可視化
print(app.get_graph().draw_mermaid())
graph TD
    start["__start__"] --> analyze_intent
    analyze_intent --> search_order
    search_order --> generate_response
    generate_response --> end_node["__end__"]

TypeScriptでのLangGraph

LangGraphはTypeScriptでも利用可能です。

import { StateGraph, END } from "@langchain/langgraph";
import { ChatOpenAI } from "@langchain/openai";
import { HumanMessage } from "@langchain/core/messages";

// State定義
interface AgentState {
  messages: HumanMessage[];
  currentStep: string;
  orderData: Record<string, unknown> | null;
  finalResponse: string | null;
}

// チャネル定義(Stateの各フィールドの更新戦略)
const graphChannels = {
  messages: {
    value: (prev: HumanMessage[], next: HumanMessage[]) => [...prev, ...next],
    default: () => []
  },
  currentStep: { value: (_: string, next: string) => next, default: () => "start" },
  orderData: { value: (_: any, next: any) => next, default: () => null },
  finalResponse: { value: (_: any, next: any) => next, default: () => null }
};

// グラフの作成
const workflow = new StateGraph<AgentState>({ channels: graphChannels });

workflow.addNode("analyzeIntent", analyzeIntent);
workflow.addNode("searchOrder", searchOrder);
workflow.addNode("generateResponse", generateResponse);

workflow.setEntryPoint("analyzeIntent");
workflow.addEdge("analyzeIntent", "searchOrder");
workflow.addEdge("searchOrder", "generateResponse");
workflow.addEdge("generateResponse", END);

const app = workflow.compile();

まとめ

ポイント内容
LangGraphの役割エージェントワークフローをグラフ構造で定義・実行
主要構成要素State、Node、Edge、Conditional Edge
Stateワークフロー全体で共有されるデータ構造
NodeStateを受け取り更新する処理関数

チェックリスト

  • LangGraphの基本概念とLangChainとの違いを理解した
  • State定義の方法を理解した
  • ノード(Node)の実装パターンを把握した
  • グラフの組み立てとコンパイルの流れを理解した

次のステップへ

次は「条件分岐とルーティング」を学びます。条件に応じてワークフローの分岐やパラレル実行を行う方法を理解しましょう。


推定読了時間: 30分