← Claudeエージェント実装:深掘り編
LESSON 04 / 06

プランニングと自己修正のパターン

所要時間 14分 上級レベル

エージェントの賢さは 「どう計画し、どう修正するか」 の設計で決まります。本レッスンでは、4つの実装パターンを比較します。

4つの主要パターン

パターン 特徴 適している場面
1. ReAct 「考え→行動→観察」を毎ターン 探索的タスク
2. Plan-and-Execute 最初に全体計画、その後実行 定型タスク
3. Reflexion 失敗時に反省と再試行 難易度の高いタスク
4. Tree-of-Thought 複数の計画を並行探索 意思決定タスク

パターン1: ReAct(Reason + Act)

最もシンプル。毎ターン「考え」「行動」「観察」を繰り返す。

# プロンプト構造

各ターンで以下の3要素を出力:
- Thought(思考):今の状況分析と次に取るべき行動
- Action(行動):呼ぶツール
- Observation(観察):ツール結果から学んだこと

例:
Thought: ユーザーは商品Aの返品を希望している。まず注文履歴を確認する必要がある。
Action: get_user_orders(user_id="...")
Observation: 商品Aは2週間前に注文、配送済み。返品期限内。
Thought: 返品プロセスを開始できる。理由を聞く必要がある。
Action: ask_user("返品理由を教えてください")

ReActの長所・短所

  • 長所:実装がシンプル、思考の透明性が高い
  • 短所トークン消費が多い、長期計画が苦手

パターン2: Plan-and-Execute

最初に全体計画を立て、その後実行する。

# Phase 1: プランニング

call_claude(
    system="あなたはプランナーです。目標達成のための具体的なステップを箇条書きで作成してください。",
    user="目標:来週月曜の経営会議用に、Q1売上レポートをCSVで作成し、Slackで共有する"
)

→ 計画例:
1. 売上DB から Q1 (1/1〜3/31) のデータを取得
2. CSV形式でフォーマット
3. ドキュメントツール (Google Drive) に保存
4. Slack の #management チャネルに共有

# Phase 2: 実行
for step in plan:
    result = execute_step(step)
    if result.failed:
        # 再プランニング
        plan = replan(plan, current_step, result.error)

Plan-and-Executeの長所・短所

  • 長所:計画と実行の責務分離、再利用しやすい
  • 短所:計画段階で間違うと立て直しが必要、動的な状況に弱い

パターン3: Reflexion(反省パターン)

失敗時に 反省して再試行。難易度の高いタスクに有効。

def reflexion_loop(goal, max_attempts=5):
    attempts = []

    for i in range(max_attempts):
        # 過去の失敗を踏まえて試行
        result = execute_with_context(goal, attempts)

        if result.success:
            return result.value

        # 反省フェーズ
        reflection = call_claude(
            system="あなたは失敗から学ぶリフレクション役です。",
            user=f"""
            目標: {goal}
            試行: {result.attempt}
            結果: {result.error}

            次の質問に答えてください:
            1. なぜ失敗したか
            2. 次回どう変えれば成功するか
            3. 避けるべきパターン
            """
        )

        attempts.append({
            "attempt": result.attempt,
            "error": result.error,
            "reflection": reflection,
        })

    return None  # 全試行失敗

パターン4: Tree-of-Thought

複数の計画を並行探索し、最良を選ぶ。

def tree_of_thought(goal, n_plans=3):
    # n個の計画を並行生成
    plans = [generate_plan(goal) for _ in range(n_plans)]

    # 各計画を評価
    for plan in plans:
        plan.score = evaluate_plan(plan, criteria=[
            "実現可能性",
            "効率性",
            "リスク",
            "目標達成度",
        ])

    # 最高スコアの計画で実行
    best = max(plans, key=lambda p: p.score)
    return execute_plan(best)

失敗パターンと対処

無限ループ

# 同じツール+引数の繰り返しを検知

def detect_loop(history):
    recent_calls = [h for h in history[-5:] if h.tool_call]
    if len(recent_calls) >= 3:
        # 直近3つが同じならループ
        if all(c == recent_calls[0] for c in recent_calls):
            return True
    return False

# ループ検知時の処理
if detect_loop(history):
    history.append(system_message(
        "同じツール呼び出しを繰り返しています。アプローチを変えてください。"
    ))

ハルシネーション(捏造)

# ツール結果の検証ステップ

「以下のツール呼び出しの結果を検証してください:
- 結果は妥当な形式か?
- 期待していた情報が含まれているか?
- 異常値・エラー兆候はないか?

結果: {result}」

停止条件の曖昧さ

# 明示的な完了判定

system_prompt += """
【タスク完了の条件】
以下の全てを満たした場合のみ「完了」と判定:
1. ユーザーの目標が達成された
2. 結果が期待形式で出力された
3. ユーザーへの確認が完了した

完了時は必ず「タスクは完了しました。理由:...」と回答してください。"""

パターンの組み合わせ

実際の本番システムでは、複数パターンを 組み合わせ ます。

例:カスタマーサポートエージェント
- 全体: Plan-and-Execute(手続きが定型)
- 各ステップ: ReAct(柔軟な対応が必要)
- 失敗時: Reflexion(難しい問合せの場合)
- エスカレ判断: Tree-of-Thought(複数選択肢から)

このレッスンのまとめ

ReAct」「Plan-and-Execute」「Reflexion」「Tree-of-Thought」の4パターンを使い分けることで、エージェントの賢さが大きく変わります。次のレッスンでは、ヒューマン・イン・ザ・ループの実装を学びます。

よくある質問

この記事に関連する質問と答えをまとめました。

Q.ReAct と Plan-and-Execute の使い分けは?
A.
探索的タスクは ReAct、定型タスクは Plan-and-Execute が向きます。実装シンプルさは ReAct、効率性は Plan-and-Execute。本番運用ではこの2つの組み合わせが多いです。
Q.Reflexion はどんな時に使う?
A.
失敗しやすい難易度の高いタスクで効果的です。「過去の失敗から学んで再試行」を組み込むことで、単発実行では達成できないタスクも完了率が上がります。