その他

【LLM】LLMの推論能力を最大限に引き出すPlan-and-Execute

その他
この記事は約10分で読めます。

はじめに

みなさんこんにちは。株式会社インプルの岩崎です。

本日は、AIツールを作っている時に見つけた思考パターン、Plan-and-Execute についてまとめました。

Plan-and-Execute とは

Plan-and-Executeは、AIに「まず考えてから動く」という規律を持たせるアーキテクチャで、複雑なタスクを解く際に、「まず全体の計画を立て、次にそれに従って一つずつタスクをこなしていく」という二段階のプロセスを踏む手法のことです。

みなさんが旅行に行く時、「航空券を取る」→「宿を予約する」→「パッキングする」と順序立てて考えるのと同じアプローチを、タスクを行うAIに行わせます。

導入することでのメリット

Plan-and-Executeを採用することで、以下のメリットが得られます。

  • ゴールまでの視点が持てる
    最初にゴールを設定してから作業を開始できるので、最終的なゴールを見失わずに作業を進めることができます。
  • エラーの最小化
    最初の計画段階でロジックを整理するため、実行時のミスを減らすことができます。
  • 効率的なツール利用
    検索、計算、コード実行など、どのステップで何を使うべきかが明確になるので、効率的に作業を進めることができます。

通常の一発で回答する場合よりも、APIの使用量などが増えるデメリットもある一方、複雑なタスクに対してはプランを立てることで順序立てて実行することができるので、回答の精度やユーザーの期待に近い回答を出すことができるメリットがあります。

仕組みを作る2つの柱

Plan-and-Execute の名の通り、この手法は「Planner(計画器)」「Executor(実行器)」という2つの役割(あるいはプロンプト)に分かれています。

Planner (計画担当)では、ユーザーの曖昧な依頼を、実行可能な「小さなステップ(サブタスク)」のリストに分解します。例えば、「最新のiPhoneの価格を調べて、私の予算で何台買えるか計算して」というタスクについては、下記の3つのステップに分解し、プランを作成します。

  • ステップ1:最新iPhoneの価格を検索する。
  • ステップ2:ユーザーの予算を確認する(あるいは入力を促す)。
  • ステップ3:予算を価格で割る計算をする。

上記のプランを受け、Executor (実行担当)では、Plannerが作ったリストを上から順に実行します。各ステップの結果をPlannerに報告し、必要に応じて計画を修正(リプランニング)することもあります。
例えば、予算で一台もiPhoneが買えない場合は、中古を提案するプランを追加したり、分割払いで最新iPhoneを買うプランを作ったり、と言った感じですね。

似たようなアーキテクチャ

AIの思考法は、この思考法以外にもさまざまなものがあります。例えば、Plan-and-Executeに似たような思考法では、下記のようなものがあります。

手法特徴
Chain of Thought (CoT)思考の過程を書き出す基本形(Plan-and-Executeの先駆け)。
ReAct「推論」と「行動(検索など)」を交互に繰り返す。
Plan-and-Solve最初に全体計画を明示的に作成してから解く手法。
LangGraph (LangChain)グラフ構造を用いて、計画→実行→修正のループを高度に制御する。

上記の手法は、また時間があれば解説したいと思います!

実際のプログラムとプロンプト

概念については大体理解していただけたかと思いますが、実際のプログラムではどのように動作しているのでしょうか?今回は、Pythonを用いた疑似コードを元に紹介します。

Pythonによる実装イメージ

現在、Plan-and-Executeの実装で最も勢いがあるのは LangGraph (LangChain) を使った構成です。ここでは、そのエッセンスを凝縮した簡易的な実装イメージを紹介します。

以下のコードは、概念を理解するための擬似コードに近い構成ですが、LangGraphなどで採用されているロジックに基づいています。

from typing import List, TypedDict

# 1. 状態(State)の定義:プランと実行結果を保持する
class PlanExecuteState(TypedDict):
    input: str        # ユーザーの依頼
    plan: List[str]   # 分解されたステップ
    past_steps: list  # 実行済みの結果
    response: str     # 最終回答

# 2. Plannerの定義:タスクを分解する
def planner(state: PlanExecuteState):
    # ここでLLMを呼び出し、タスクを箇条書きで出力させる
    # プロンプト例: "以下のタスクをステップに分解してください: {input}"
    plan = ["最新の株価を検索する", "過去3ヶ月の推移と比較する", "分析結果をまとめる"]
    return {"plan": plan}

# 3. Executorの定義:ステップを1つずつ実行する
def executor(state: PlanExecuteState):
    plan = state["plan"]
    current_step = plan.pop(0) # 最初のタスクを取り出す
    
    # ここでツール(検索エンジンや計算機)を呼び出す
    result = f"『{current_step}』の実行結果: OK" 
    
    return {"past_steps": state["past_steps"] + [result], "plan": plan}

# 4. 制御フロー(擬似ループ)
# 計画が空になるまでExecutorを回し、最後に回答を生成する

# 1. 状態(State)の定義:プランと実行結果を保持する
ここでは、AIエージェントたちがコメントアウトした内容について書き込み、参照する共通のメモリになります。

# 2. Plannerの定義:タスクを分解する
ここで先ほど紹介したPlannerが、最初の1回だけ呼び出され、大きなタスクを分解します。プロンプト例にもあるように、input された情報に対して plan で分割されていますね。プロンプトについては、後ほど紹介しますが、「各ステップは、前のステップの結果を利用できるように設計せよ」と命じることが肝になってきます。

# 3. Executorの定義:ステップを1つずつ実行する
ここも先ほど紹介したように、実行役のステップで、リストの先頭にあるタスクを1つだけ実行します。プランの実際の動作・実務を担当し、実行結果を past_steps に追記し、完了したタスクを plan から削除します。

そして、このプランが空になるまで計画を回し、最後に回答を生成させる流れになります。

実装のアレンジ

先ほど紹介したPythonのコードには、下記のようなアレンジもできます。

Re-plannerは、1つのステップが終わるたびに、「このままの計画で大丈夫か?」を判定するプロセスです。概念の紹介でもあったように、必要に応じてリプランニングする必要が出てくる時、このロジックが役に立ちます。

def replanner(state: AgentState):
    # これまでの実行結果(past_steps)を見て、次のアクションを決める
    # A) 計画通り進める
    # B) 計画が間違っていたので、残りのplanを書き換える
    # C) 十分な情報が集まったので、final_answerを作成して終了する
    
    if "十分な情報がある" in check_result:
        return "end"
    else:
        return "continue"

通常のプロンプトとの違い

さて、Pythonによる実装イメージは持っていただけたかと思いますが、AIのツールではプロンプトも大事になります。通常のプロンプトと、Plan-and-Executeの仕組みは、コードそのものよりも「AIにどういう役割(ペルソナ)を与え、どういう形式で出力させるか」というプロンプト設計に大きく依存します。

項目単純なプロンプトPlan-and-Execute用
指示内容「〜について調べて教えて」「〜を分解し、ステップごとに実行せよ」
思考の深さ直感的な回答(ハルシネーションのリスク)論理的な積み上げ(正確性が高い)
エラー対応途中で間違えても突き進む途中で計画を修正できる

プロンプトの実装イメージ

まず最初のPlannerには、全体を俯瞰し詳細まで理解させる能力が必要になります。
常に逆算の思考を持たせ、最後のゴールから逆算してどのようなステップが必要になるのか考えて、プランを立てられるように支持する必要があります。
出力についても、プログラム側で処理しやすいよう、JSONや番号付きのリストで出力させると、やりやすいです。

システムプロンプト例:
「あなたは複雑な問題を解く戦略家です。ユーザーの依頼を、具体的かつ独立したステップに分解してください。
各ステップは『〜を検索する』『〜を計算する』といった、単一の動作である必要があります。
形式は必ず以下のJSON形式で出力してください:
{"plan": ["step1", "step2", ...], "goal": "最終目的"}」

続けて処理するExecutorは、実行役と紹介した通り、「今、何をすべきか」に集中させますが、前のステップの結果を正しく渡す必要があります。
過去の情報を変数のように扱わせ、「前ステップの結果{result-1}を使って、XXせよ」と指示してあげます。ツールを使っても情報が得られなかった場合、適当に嘘をつかず、「失敗した」と報告させることも重要です。AIは何かと答えを出さなければ、と嘘の情報(ハルシネーション)を出すこともあるので、これもプロンプトで制御してあげる必要があります。

さて、応用で紹介したRe-plannerですが、実はここが最も高度なプロンプトです。Executorからの報告を受けて、「完遂・継続・修正」の3択を判断させます。これにより、AIが一度立ち止まって考えることができ、回答の精度を向上させることができます。

これまでの実行結果を分析し、以下のいずれかを選択してください。

完了 (finish): ユーザーの質問に答える準備が整った。
継続 (continue): 計画通り次のステップに進む。
修正 (revise): 予想外の結果が出たため、残りのステップを書き換える。

判断の根拠と、修正が必要な場合は新しい計画を提示してください。

この技術を活用しているツール

さて、このPlan-and-Executeの思考法は、さまざまなAIツールで活用されています。

例えば、AIエージェントのAntigravityやDevinでは、ユーザーからのタスクに対して、プランを作成しタスクを実行しています(Devinは2025年の10月ごろに使ってた記憶ですが。。。)。それぞれのツールの記事も作成していますので、よろしければご覧ください!

また、この記事を作るきっかけになった、AIスライド生成ツールのGenspark(ジェンスパーク)も、この思考法を使っています。前々から存在を知っていたものの、最近初めて使ってみて、凄さを実感しました・・・。こちらは記事がないので公式から。

Just a moment...

おわりに

いかがだったでしょうか?

実は、AIスライドツールも、内容を作る部分や構成を作成する部分は、今回紹介した思考法を盛り込んだ方が良さそうな気がしています・・・。でも、そしたらGensparkと仕組みはほぼ一緒になっちゃうのですが。。。オリジナルの機能を追加して、ニッチな部分を責められないか、模索中です笑。

ご覧いただきありがとうございました。