タスク分解(エージェンティックプランニング)(タスクブンカイ)
LLMエージェントが複雑な目標を実行可能なサブタスクに分割するプロセス。階層的分解、逐次分解、適応的分解の3種類があり、エージェントの計画能力の根幹を成す技術である。
タスク分解とは
タスク分解(Task Decomposition)とは、LLMエージェントが複雑な目標や指示を、個別に実行可能な小さなサブタスクに分割するプロセスである。人間が大きなプロジェクトをToDoリストに落とし込むのと同様に、AIエージェントもまず全体像を把握し、それを段階的に処理可能な単位へ分解する必要がある。
タスク分解はエージェンティックプランニングの最初のステップであり、分解の品質がその後の実行精度を大きく左右する。分解が粗すぎると各サブタスクが複雑になりすぎ、細かすぎると不要なオーバーヘッドが発生する。適切な粒度の決定がタスク分解における最大の課題である。
タスク分解の3つのアプローチ
タスク分解には大きく分けて3つのアプローチが存在する。
| アプローチ | 概要 | メリット | デメリット | 適するタスク |
|---|---|---|---|---|
| 階層的分解(Hierarchical) | 目標をトップダウンで段階的に分解 | 構造が明確、見通しがよい | 事前知識が必要 | 定型業務、ソフトウェア設計 |
| 逐次分解(Sequential) | 1ステップずつ逐次的に次のタスクを決定 | 柔軟、動的に対応可能 | 全体の見通しが立ちにくい | 探索的タスク、リサーチ |
| 適応的分解(Adaptive) | 実行結果に応じて分解戦略を修正 | 最も柔軟、エラー回復力が高い | 実装が複雑、計算コスト高 | 不確実性の高いタスク |
階層的分解の詳細
階層的分解はHierarchical Task Network(HTN)に起源を持つ古典的な手法である。LLMの文脈では、まず高レベルのサブゴールを設定し、各サブゴールをさらに具体的なアクションに分解する。例えば「Webアプリケーションを作成する」というタスクは以下のように階層的に分解される。
Webアプリケーション作成
├── 要件定義
│ ├── ユーザーストーリー作成
│ └── 技術スタック選定
├── バックエンド開発
│ ├── DB設計
│ ├── API実装
│ └── 認証機能実装
├── フロントエンド開発
│ ├── UI設計
│ ├── コンポーネント実装
│ └── API連携
└── テスト・デプロイ
├── ユニットテスト
├── E2Eテスト
└── デプロイ設定
逐次分解の詳細
逐次分解はReActパターンと相性がよく、1つのサブタスクを実行した結果を見て次のサブタスクを動的に決定する。事前にすべてのサブタスクを列挙する必要がないため、探索的なタスクに適している。ただし、全体の進捗管理が難しく、同じサブタスクを繰り返し実行してしまうループ問題が発生しやすい。
プロンプトによるタスク分解の実現
LLMにタスク分解を行わせるプロンプト技法は複数存在する。
| 技法 | プロンプト例 | 特徴 |
|---|---|---|
| Zero-shot分解 | 「このタスクをステップに分解してください」 | シンプルだが品質にばらつき |
| Few-shot分解 | 分解例を数個提示してから依頼 | 品質安定、ドメイン適応が容易 |
| Plan-and-Solve | 「まず計画を立て、次にステップごとに解決してください」 | 計画と実行を明示的に分離 |
| Step-Back Prompting | 「まず高レベルの概念を確認してから分解してください」 | 抽象化→具体化の流れ |
| Least-to-Most | 簡単なサブ問題から順に解く | 段階的な難易度上昇 |
Plan-and-Solveプロンプティングは、Wang et al.(2023)が提案した手法で、Zero-shot-CoTの改良版である。「Let's first understand the problem and devise a plan to solve it. Then, let's carry out the plan and solve the problem step by step.」というプロンプトにより、LLMが自発的にタスクを分解してから実行する。
サブゴール設定とツールマッピング
タスク分解後、各サブタスクに対してサブゴール(達成条件)とツールマッピング(使用するツール)を設定する。
| サブタスク | サブゴール | 必要なツール | 依存関係 |
|---|---|---|---|
| データ収集 | 必要なデータがすべて取得済み | Web検索API、スクレイピング | なし |
| データ前処理 | クリーンなデータセットが完成 | Python実行環境 | データ収集 |
| 分析実行 | 統計結果が算出済み | Python実行環境、可視化ライブラリ | データ前処理 |
| レポート作成 | 読みやすい報告書が完成 | テキスト生成、図表挿入 | 分析実行 |
ツールマッピングでは、エージェントが利用可能なツール群の中から各サブタスクに最適なツールを選択する。HuggingGPTではLLMがHugging Faceのモデル群から適切なモデルを選択する仕組みを実現しており、ツールマッピングの先駆的な実装といえる。
タスク分解の評価指標
タスク分解の品質を評価するための指標には以下がある。
| 評価指標 | 意味 | 測定方法 |
|---|---|---|
| 完全性(Completeness) | すべての必要なサブタスクが含まれているか | 正解分解との比較 |
| 粒度適切性(Granularity) | サブタスクの粒度が実行に適切か | 実行成功率との相関 |
| 順序整合性(Order Consistency) | 依存関係が正しく反映されているか | DAG検証 |
| 冗長性(Redundancy) | 不要なサブタスクが含まれていないか | 実行ステップ数の比較 |
| 実行可能性(Feasibility) | 各サブタスクが実行可能か | ツールマッチング成功率 |
実装パターンと具体例
実際のフレームワークでのタスク分解の実装パターンを示す。
CrewAIでは、各エージェントにroleとgoalを定義し、Taskオブジェクトとして分解結果を明示的に管理する。LangGraphでは、ノード(処理単位)とエッジ(遷移条件)のグラフとしてタスク分解を表現する。AutoGenでは、会話の中でエージェント同士がタスクの分担を議論し、動的に分解する。
よくある質問(FAQ)
Q1: タスク分解の粒度はどう決めればよいか?
A1: 一般的な指針として、各サブタスクが「1つのツール呼び出しまたは1つのLLM推論で完了できる」粒度を目安にする。複数のツール呼び出しが必要なら、さらに分解する余地がある。逆に、サブタスク数が20を超える場合は、中間レベルのグルーピングを検討すべきである。
Q2: タスク分解でLLMが失敗するパターンは?
A2: 代表的な失敗パターンは、(1)重要なサブタスクの欠落(前提条件の確認漏れなど)、(2)依存関係の誤り(並列実行可能なタスクを逐次にする、逆に依存のあるタスクを並列にする)、(3)過度に抽象的な分解(「問題を解決する」のような実行不能なサブタスク)、(4)ツールとのミスマッチ(利用不可能なツールを前提とした分解)である。
Q3: 動的なタスク再分解はどう実装するか?
A3: Reflexionパターンを応用し、各サブタスクの実行後に「計画の妥当性を再評価する」ステップを挟む。実行結果が期待と異なる場合、残りのサブタスクを再分解する。LangGraphではConditional Edgeを使って、実行結果に応じた分岐を定義できる。ReWOO(Reasoning WithOut Observation)パターンでは、計画フェーズと実行フェーズを分離し、計画フェーズでの再分解コストを低減している。