「ワークフローが複雑になるほど、エージェントが暴走する」
10社以上のAIエージェント導入を支援してきた中で、最も多く耳にする悩みです。実際、生産環境でのAIエージェント失敗の60%以上は、モデルの能力不足ではなくワークフロー設計の問題だと言われています(Adopt AI, 2026年)。
問題は多くの場合、同じところにあります。最初から複雑なパイプラインを組もうとする。ループの終了条件を設定しない。並列化できるステップを直列に実行している。
この記事では、実際の導入支援で効果が確認された5つのワークフロー設計パターンを、LangGraphのコード例とともに解説します。どのパターンをどんな状況に使うか、判断基準も明確にします。
LangGraphのワークフロー設計の基礎については、AIエージェント構築完全ガイドでも詳しく解説しています。
まず試したい「5分即効」セットアップ
最もシンプルなLangGraphの線形ワークフローから始めましょう。以下はそのまま動くコードです。
# 動作環境: Python 3.11+, langgraph==0.2.x, langchain-anthropic>=0.3.0
# pip install langgraph langchain-anthropic python-dotenv
from langgraph.graph import StateGraph, END
from langchain_anthropic import ChatAnthropic
from typing import TypedDict
import os
# ステートの定義(ワークフロー全体で共有されるデータ)
class AgentState(TypedDict):
input: str
research: str
draft: str
final: str
# モデルの初期化
llm = ChatAnthropic(model="claude-sonnet-4-5", api_key=os.environ["ANTHROPIC_API_KEY"])
# ノードの定義(各ステップが独立した関数)
def research_node(state: AgentState) -> AgentState:
response = llm.invoke(f"以下のトピックについて調査してください: {state['input']}")
return {"research": response.content}
def draft_node(state: AgentState) -> AgentState:
response = llm.invoke(f"調査結果をもとに記事の下書きを作成: {state['research']}")
return {"draft": response.content}
def review_node(state: AgentState) -> AgentState:
response = llm.invoke(f"以下の下書きをレビューして最終版を作成: {state['draft']}")
return {"final": response.content}
# グラフの構築(線形ワークフロー)
workflow = StateGraph(AgentState)
workflow.add_node("research", research_node)
workflow.add_node("draft", draft_node)
workflow.add_node("review", review_node)
workflow.set_entry_point("research")
workflow.add_edge("research", "draft")
workflow.add_edge("draft", "review")
workflow.add_edge("review", END)
app = workflow.compile()
# 実行
result = app.invoke({"input": "LangGraphのワークフロー設計", "research": "", "draft": "", "final": ""})
print(result["final"])
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
5つのパターンを「選択基準」で理解する
実際の現場では「どのパターンを選ぶか」が最も重要です。以下の基準で判断してください。
| パターン | 適用場面 | 難易度 | LangGraph対応 |
|---|---|---|---|
| 線形(Sequential) | ステップが明確に依存、順序固定 | ★☆☆☆☆ | add_edge()のみ |
| 分岐(Router) | 入力タイプに応じた処理振り分け | ★★☆☆☆ | add_conditional_edges() |
| ループ(Retry) | 品質チェック+再試行が必要 | ★★★☆☆ | 条件付きエッジで戻り矢印 |
| 並列(Parallel/DAG) | 独立したサブタスクを同時実行 | ★★★★☆ | fan-out + fan-in |
| オーケストレーター | 長期・複雑タスクの分解・委任 | ★★★★★ | マルチグラフ構成 |
パターン1:線形(Sequential)
最もシンプル。Step 2はStep 1が完了してから始まります。上の即効セットアップコードがそのままこのパターンです。
使うべき場面: リサーチ → 執筆 → レビューのような、前ステップの結果が次ステップの必須入力になるタスク。
一つ注意点があります。線形パターンはどこかが失敗すると全体が止まるため、各ノードにエラーハンドリングが必要です。
パターン2:分岐(Router)
入力の種類を分類して、適切な処理ルートに振り分けます。カスタマーサポートエージェントの実装で最も効果的なパターンです。
from langgraph.graph import StateGraph, END
from typing import TypedDict, Literal
class SupportState(TypedDict):
message: str
category: str
response: str
def classify_node(state: SupportState) -> SupportState:
"""入力をカテゴリ分類するルーター"""
message = state["message"].lower()
if "請求" in message or "料金" in message:
category = "billing"
elif "バグ" in message or "エラー" in message:
category = "technical"
else:
category = "general"
return {"category": category}
def route_logic(state: SupportState) -> Literal["billing", "technical", "general"]:
"""分岐の判定ロジック(エッジ関数)"""
return state["category"]
def billing_node(state: SupportState) -> SupportState:
return {"response": f"請求専門チームが対応します: {state['message']}"}
def technical_node(state: SupportState) -> SupportState:
return {"response": f"技術サポートが対応します: {state['message']}"}
def general_node(state: SupportState) -> SupportState:
return {"response": f"一般サポートが対応します: {state['message']}"}
# グラフ構築
workflow = StateGraph(SupportState)
workflow.add_node("classify", classify_node)
workflow.add_node("billing", billing_node)
workflow.add_node("technical", technical_node)
workflow.add_node("general", general_node)
workflow.set_entry_point("classify")
# 条件付きエッジで分岐
workflow.add_conditional_edges("classify", route_logic, {
"billing": "billing",
"technical": "technical",
"general": "general"
})
workflow.add_edge("billing", END)
workflow.add_edge("technical", END)
workflow.add_edge("general", END)
app = workflow.compile()
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
パターン3:ループ(Retry / Quality Check)
エージェントが自己評価して、基準を満たすまで繰り返すパターン。コード生成やレポート作成で特に効果的です。
from langgraph.graph import StateGraph, END
from typing import TypedDict, Literal
class WritingState(TypedDict):
topic: str
draft: str
feedback: str
retry_count: int
approved: bool
MAX_RETRIES = 3 # 必ず上限を設定する(無限ループ防止)
def write_node(state: WritingState) -> WritingState:
"""下書き生成"""
# LLM呼び出し(省略)
return {"draft": f"下書き v{state['retry_count'] + 1}", "retry_count": state["retry_count"] + 1}
def review_node(state: WritingState) -> WritingState:
"""品質チェック"""
draft = state["draft"]
# 基準チェック(文字数、キーワード含有など)
if len(draft) > 100 or state["retry_count"] >= MAX_RETRIES:
return {"approved": True}
return {"feedback": "文字数が不足しています", "approved": False}
def should_retry(state: WritingState) -> Literal["retry", "done"]:
"""ループ継続か終了かの判定"""
if state["approved"] or state["retry_count"] >= MAX_RETRIES:
return "done"
return "retry"
workflow = StateGraph(WritingState)
workflow.add_node("write", write_node)
workflow.add_node("review", review_node)
workflow.set_entry_point("write")
workflow.add_edge("write", "review")
# ループ: 不合格なら write に戻る、合格なら END
workflow.add_conditional_edges("review", should_retry, {
"retry": "write",
"done": END
})
app = workflow.compile()
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
最重要ルール: `MAX_RETRIES`は必ず設定してください。設定しないと、モデルが自己評価で永遠にループするケースがあります。APIコストが青天井になります。
パターン4:並列(Parallel / DAG)
互いに独立したタスクを同時実行し、全ての結果をまとめます。実行時間を大幅に短縮できます。
# 並列実行の概念コード(fan-out → fan-in)
from langgraph.graph import StateGraph, END
from typing import TypedDict, List
class ResearchState(TypedDict):
query: str
results_A: str
results_B: str
results_C: str
final_summary: str
# 3つの調査ノードは独立して並列実行
def research_A(state: ResearchState) -> ResearchState:
return {"results_A": f"Source A の調査結果: {state['query']}"}
def research_B(state: ResearchState) -> ResearchState:
return {"results_B": f"Source B の調査結果: {state['query']}"}
def research_C(state: ResearchState) -> ResearchState:
return {"results_C": f"Source C の調査結果: {state['query']}"}
def aggregate_node(state: ResearchState) -> ResearchState:
"""全結果を統合(fan-in)"""
summary = f"統合結果:n{state['results_A']}n{state['results_B']}n{state['results_C']}"
return {"final_summary": summary}
workflow = StateGraph(ResearchState)
workflow.add_node("research_A", research_A)
workflow.add_node("research_B", research_B)
workflow.add_node("research_C", research_C)
workflow.add_node("aggregate", aggregate_node)
# fan-out: 開始点から3つのノードに同時分岐
workflow.set_entry_point("research_A") # LangGraphは同一レイヤーのノードを並列実行
# fan-in: 全ノードがaggregateに収束
for node in ["research_A", "research_B", "research_C"]:
workflow.add_edge(node, "aggregate")
workflow.add_edge("aggregate", END)
app = workflow.compile()
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
【要注意】よくある設計ミスと回避策
失敗1:ループに終了条件を設定しない
❌ ループノードに`MAX_RETRIES`も終了条件も設定しない
⭕ 必ず最大反復回数をステートに持ち、超過したら強制終了
なぜ重要か: モデルの自己評価は必ずしも収束しません。条件なしループは数百回のAPI呼び出しを引き起こし、コストが数万円単位になるケースがあります。
失敗2:全ステップを線形に並べる
❌ 独立したタスクAとBを、A→B→C…と直列に接続する
⭕ 依存関係を分析し、独立したステップは並列実行に変更する
なぜ重要か: 5ステップすべてが独立している場合、並列化で実行時間を最大5分の1に短縮できます。
失敗3:エラー時のフォールバックがない
❌ ノードがエラーを返した時、グラフ全体がクラッシュする設計
⭕ 各ノードにtry/exceptとエラー状態をステートで伝播する設計
def safe_research_node(state: AgentState) -> AgentState:
try:
# LLM呼び出し
response = llm.invoke(state["input"])
return {"research": response.content, "error": None}
except Exception as e:
# エラーをステートで伝播(クラッシュさせない)
return {"research": "", "error": str(e)}
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
パターン選択のフローチャート
実際の設計現場では、以下の順序で考えると判断が速くなります:
- タスク間に依存関係があるか? → ある → 線形 or 分岐
- 品質基準を繰り返しチェックが必要か? → ある → ループ追加
- 独立したサブタスクが複数あるか? → ある → 並列化
- タスク自体が動的に変わるか? → ある → オーケストレーター
まとめ:今日から始める3つのアクション
- 今日やること: 線形パターンのサンプルコードを実際に動かしてみる。LangGraph v1.0の基本構造を手で書いて理解する
- 今週中: 現在のワークフローを見直して、並列化できるステップを特定する。ループがある場合はMAX_RETRIESを設定する
- 今月中: 本番ワークフローに分岐パターンを導入し、エラーログを確認して品質を測定する
あわせて読みたい:
- AIエージェント構築完全ガイド — エージェントの基礎設計から実装まで
- CrewAI vs LangGraph vs AutoGen 比較 — マルチエージェントフレームワーク選定ガイド
著者: 佐藤傑(さとう・すぐる)
株式会社Uravation代表取締役。早稲田大学法学部在学中に生成AIの可能性に魅了され、X(旧Twitter)で活用法を発信(@SuguruKun_ai、フォロワー10万人超)。100社以上の企業向けAI研修・導入支援を展開。著書累計3万部突破。
ご質問・ご相談は お問い合わせフォーム からお気軽にどうぞ。
参考・出典
- Common Workflow Patterns for AI Agents (2026 Guide) — GUVI Blog(参照日: 2026-04-11)
- LangGraph: Agent Orchestration Framework for Reliable AI Agents — LangChain公式(参照日: 2026-04-11)
- LangGraph in 2026: Build Multi-Agent AI Systems That Actually Work — DEV Community(参照日: 2026-04-11)
- Multi-Agent Frameworks Explained for Enterprise AI Systems [2026] — Adopt.ai(参照日: 2026-04-11)