AIエージェントのアーキテクチャはReAct・Plan-and-Execute・マルチエージェントの3パターンに集約される。「シンプルなタスクはReAct、複雑なタスクはPlan-and-Execute、専門領域をまたぐタスクはマルチエージェント」という選定基準が実践的な出発点だ。

AIエージェントのアーキテクチャパターン概観

AIエージェントのアーキテクチャを選ぶ際、最初に把握すべきは3つの主要パターンだ。それぞれが異なるトレードオフを持ち、タスクの複雑さとユースケースによって使い分ける。

【AIエージェント3アーキテクチャパターンの比較概念図】

【ReAct】              【Plan-and-Execute】     【マルチエージェント】
シンプル・即応型         計画先行型               分散協調型

目標                   目標                    目標
 |                      |                       |
思考→実行→観察          [プランナー]              [オーケストレーター]
思考→実行→観察          タスク1→タスク2→タスク3    /        |        ...                     実行1   実行2   実行3   専門A   専門B   専門C
 |                      |                       |
完了                   完了                     統合・完了

適性: 単純〜中程度       適性: 複雑・多ステップ     適性: 異なる専門領域

ReAct(Reasoning + Acting)パターン

ReActはAIエージェントの最も基本的なパターンだ。「思考 (Thought) → 行動 (Action) → 観察 (Observation)」の3ステップをループして目標を達成する。LLMが「次に何をすべきか」を考え、ツールを実行し、結果を観察して次の思考につなげる流れだ。

メリット: シンプルで実装しやすく、各ステップのログが取りやすいためデバッグが容易。多くのフレームワークで標準的にサポートされている。
デメリット: 長いタスクや複雑な依存関係があると、LLMが方向性を見失いやすい。1ステップごとにLLM呼び出しが発生するためコストが積み上がる。

from langchain_anthropic import ChatAnthropic
from langchain.agents import AgentExecutor, create_react_agent
from langchain.tools import tool
from langchain import hub

@tool
def web_search(query: str) -> str:
    """Web上の最新情報を検索する。ニュース・技術情報・市場データの取得に使用。"""
    # 実際にはSearch APIを呼び出す
    return f"検索結果: '{query}' に関する最新情報..."

@tool
def calculate(expression: str) -> str:
    """数式を計算する。例: '(100 + 200) * 0.1'"""
    try:
        result = eval(expression)
        return str(result)
    except Exception as e:
        return f"計算エラー: {e}"

llm = ChatAnthropic(model="claude-3-5-sonnet-20241022")
tools = [web_search, calculate]

# ReActプロンプトテンプレートを取得
prompt = hub.pull("hwchase17/react")
agent = create_react_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True, max_iterations=10)

result = executor.invoke({
    "input": "日本のAI市場規模を調べて、前年比成長率を計算してください"
})

Plan-and-Executeパターン

Plan-and-Executeは「まず全体計画を立て、計画に沿って実行する」パターンだ。最初のステップでLLMがタスク全体をサブタスクのリストに分解し、その後各サブタスクを順番に実行する。複雑なタスクでReActが迷走しやすいという弱点をカバーする。

メリット: タスクの全体像を把握してから実行するため、複雑なタスクでも方向性がブレにくい。並行実行が可能なサブタスクを特定しやすい。
デメリット: 最初の計画が間違っていた場合、計画の修正コストが高い。計画フェーズとのステップが増えるため、シンプルなタスクには過剰。

from langgraph.graph import StateGraph, END
from typing import TypedDict, List
from langchain_anthropic import ChatAnthropic

class PlanExecuteState(TypedDict):
    goal: str
    plan: List[str]
    executed_steps: List[str]
    current_step_index: int
    final_result: str

llm = ChatAnthropic(model="claude-3-5-sonnet-20241022")

def create_plan(state: PlanExecuteState) -> PlanExecuteState:
    """目標をサブタスクのリストに分解する"""
    response = llm.invoke(f"""以下の目標を達成するための実行ステップを3〜5個のリストで返してください。
目標: {state['goal']}
形式: 1. ステップ1
2. ステップ2
...""")
    steps = [line.split(". ", 1)[1] for line in response.content.strip().split("
") if ". " in line]
    return {**state, "plan": steps, "current_step_index": 0}

def execute_step(state: PlanExecuteState) -> PlanExecuteState:
    """現在のステップを実行する"""
    step = state["plan"][state["current_step_index"]]
    result = llm.invoke(f"実行してください: {step}
前のステップの結果: {state['executed_steps']}")
    return {**state,
            "executed_steps": state["executed_steps"] + [result.content],
            "current_step_index": state["current_step_index"] + 1}

def finalize(state: PlanExecuteState) -> PlanExecuteState:
    summary = llm.invoke(f"以下の実行結果をまとめてください:
{state['executed_steps']}")
    return {**state, "final_result": summary.content}

workflow = StateGraph(PlanExecuteState)
workflow.add_node("plan", create_plan)
workflow.add_node("execute", execute_step)
workflow.add_node("finalize", finalize)
workflow.add_conditional_edges("execute",
    lambda s: "finalize" if s["current_step_index"] >= len(s["plan"]) else "execute",
    {"finalize": "finalize", "execute": "execute"})
workflow.set_entry_point("plan")
workflow.add_edge("plan", "execute")
workflow.add_edge("finalize", END)

マルチエージェントパターン

マルチエージェントは複数の専門化されたエージェントが協調してタスクを遂行するパターンだ。オーケストレーター (指揮者) が全体を管理し、各専門エージェント (演奏者) が自分の領域を担当する。

典型的な構成例として、「リサーチエージェント (Web検索・情報収集) → 分析エージェント (データ処理・計算) → ライティングエージェント (レポート作成) → レビューエージェント (品質確認)」のような役割分担がある。各エージェントはLLMと専用ツールを持ち、自分の専門領域に特化した判断を行う。

詳細な実装パターンについては「マルチエージェントシステムの設計と実装」を参照してほしい。

アーキテクチャ選定のフレームワーク

パターン 複雑さ タスク適性 デバッグ容易性 コスト 推奨場面
ReAct 単純〜中程度のタスク 高 (ステップが明確) 低〜中 PoC・単一目標タスク
Plan-and-Execute 複雑・多ステップタスク 中 (計画が見える) 中〜高 業務分析・調査レポート
マルチエージェント 複数専門領域タスク 低 (分散して複雑) 大規模ワークフロー自動化
ユースケース ReAct Plan-Execute Multi-Agent 理由
FAQ自動応答 × 単純な検索→生成で完結
市場調査レポート作成 調査→分析→執筆の計画が効果的
コードレビュー自動化 セキュリティ/品質/パフォーマンス専門エージェントが有効
カスタマーサポート (複雑) 一次対応・エスカレーション・専門回答の役割分担
データパイプライン監視 イベント→判断→アクションのシンプルなループ
【アーキテクチャ選定の判断ツリー】

タスクは単純か? (1〜3ステップ)
  Yes → ReAct を選択
  No  ↓
タスクを事前に計画できるか?
  Yes → Plan-and-Execute を選択
  No  ↓
複数の専門領域にまたがるか?
  Yes → マルチエージェント を選択
  No  → ReAct または Plan-and-Execute を選択

※ 迷ったら ReAct でスタートし、必要に応じて進化させる

まとめ――「シンプルに始めて、必要に応じて進化させる」

  • ReAct: 単純〜中程度のタスクに最適なシンプルなパターン。まず試す第一選択
  • Plan-and-Execute: 複雑・多ステップタスクに強い。計画の可視性がデバッグを助ける
  • マルチエージェント: 複数専門領域をまたぐ大規模タスクに有効。実装コストは最も高い
  • 迷ったらReActから始め、限界が明確になってから高度なパターンに移行する

よくある質問

Q. ReActパターンとは何ですか?

「推論 (Reasoning)」と「行動 (Acting)」を交互に繰り返すエージェントアーキテクチャです。LLMが思考→ツール実行→結果観察→次の思考というループでタスクを進めます。シンプルで実装しやすく、最も広く使われています。

Q. どのアーキテクチャパターンを選ぶべきですか?

単純なタスク (1〜3ステップ) ならReAct、複雑なタスク (5ステップ以上) ならPlan-and-Execute、複数の専門領域にまたがるタスクならマルチエージェントが適しています。まずReActで始め、必要に応じて進化させるアプローチを推奨します。

Q. マルチエージェントはいつ必要ですか?

1つのエージェントでは扱いきれない複雑さ (異なる専門領域、並行処理、役割分担) がある場合に有効です。例えば、リサーチエージェント+分析エージェント+レポート作成エージェントの協調が必要な業務分析タスクなどです。