---
id: subtasks
title: サブ実行・並列実行
category: advanced
order: 100
keywords: [サブタスク, SpawnSubTask, WaitSubTask, 並列, 直列, waiting_subtasks, 分解, delegate, サブエージェント, 完了待ち]
---

# サブ実行・並列実行

大きな仕事は、エージェントが複数のサブ調査に分解して進めます。「5 社を比較調査して」のように独立した調査項目が並ぶタスクで効果的です。

分解には 2 つのやり方があります。

- **delegate（直列・既定）**: サブ調査を **1 件ずつ順番に** こなします。各サブは綺麗なコンテキストで動くので品質が揃いやすく、GPU・実行枠も軽くて済みます。調査・分析・ブレインストーミング系のタスクは既定でこちらを使います。並列に比べると壁時計時間は少し長くなります。
- **SpawnSubTask（並列・任意）**: 独立したサブタスクを **別ジョブとして同時に** 走らせます。壁時計時間は縮みますが、その分の実行枠を消費します。**デフォルトでは無効**で、必要なワークスペースだけがツール設定で有効化します（後述）。

ふだんは delegate で分解が完結するため、ほとんどのタスクで SpawnSubTask を有効にする必要はありません。

## delegate（直列のサブ調査）

エージェントが `delegate` ツールを呼ぶと、その場でサブエージェントがインライン実行されます。サブの中間ターンは親のコンテキストに入らず、最終結果だけが親に戻ります。複数の delegate は順番に（直列で）実行されます。

delegate は標準で有効なので、特別な設定は不要です。実行中の様子はチャット欄に専用のコンソール枠でリアルタイム表示され、完了後の記録は「概要 > サブ実行」に残ります。

## SpawnSubTask（並列の別ジョブ・要有効化）

`SpawnSubTask` はデフォルト無効のツールです。使うには、ワークスペースの **設定 → ツール** タブで明示的にオンにします（Bash などと同じ「センシティブ／任意有効化」の扱い）。有効にしていないワークスペースでは、エージェントに SpawnSubTask が提示されず、分解は委譲実行で行われます。

有効にしたうえでエージェントが `SpawnSubTask` を呼ぶと、サブタスクがキューに追加されます。複数回呼べば複数のサブタスクが並列にスケジュールされます。各サブタスクには独立した専用ワークスペースが割り当てられ、別ジョブとして実行されます。

サブタスクを起動したあと、エージェントは `WaitSubTask` を呼んで全部の完了を待ちます。このとき親タスクは **waiting_subtasks** 状態に入り、いったん停止して実行枠（worker）を手放します（待っている間に他の仕事が詰まりません）。すべての子が完了すると親が再開し、子の成果をまとめて最終出力を作ります。

ツール設定の詳しい場所は [ワークスペースとメンバー](./21-workspaces.md) の「ツールポリシー」を参照してください。ジョブの状態遷移については「[タスクの実行と監視](03-running.md)」を参照してください。

## サブタスクまわりの安全策

サブタスクを取りこぼしたり、止めたはずの処理が裏で動き続けたりしないよう、いくつかの安全策が働きます。

- **待ち忘れの防止**: 子がまだ走っている最中にエージェントが「完了」しようとしても、結果を待たずに終わってしまうことはありません。自動でいったん停止して、全部の完了を待ってから続けます。
- **止めたら子も止まる**: 親タスクが失敗・キャンセル・リトライしたとき、まだ走っているサブタスクも一緒に止まります。親が消えたのに子だけが裏で動き続けて GPU を使う、ということがなくなりました。ただし、ユーザーの回答待ち（割り込み待ち）で止まっている間は、あとで再開して結果を使うため子は止めません。
- **起動を少しずつ**: 一度に大量のサブタスクを起動しても、順番待ちの列に少しずつ（既定で 1 秒間隔）並べます。一団が実行枠を一気に奪って他のタスクを後回しにしてしまうのを防ぎます。間隔は `config.yaml` の `subtasks.spawn_stagger_ms` で調整できます（`0` で無効）。

## SpawnSubTask の引数

| 引数 | 説明 |
|---|---|
| title | サブタスクのタイトル（簡潔に） |
| instruction | 何を調査・実行し、どんな形式で `output/` に書くかの具体的な指示 |
| piece | 使用するピース（省略時は `general`） |

`piece` には `general` / `research` / `brainstorming` / `data-process` / `office-process` などを指定できます。指定したピースが見つからない場合はエラーになります。

## サブ実行の確認

タスク詳細の **概要（Overview）タブ**に出る「サブ実行」欄で進捗を確認できます。ここには SpawnSubTask で生成した並列サブタスク、および delegate で起動したサブエージェント（インライン直列実行）の両方が一覧されます。delegate だけを使ったタスクでも表示されます。

実行中の delegate サブエージェントは、チャット欄に専用の小さなコンソール枠でリアルタイムに文字出力が流れます（メインエージェントと同じ見え方）。完了後は「概要 > サブ実行」に作業記録（タイムライン）が残ります。

SpawnSubTask で起動したサブタスクの**中で** delegate が動いた場合も、その進捗が親タスクの委譲ビューに表示されます。チャット欄ではサブタスクごとにまとめたリアルタイムコンソールで様子を確認でき、完了後は「概要 > サブ実行」のカード内にそのサブタスクが実施した delegate の記録も残ります。並列サブタスクを使う構成でも、ひとつ上の親タスク画面から委譲の進捗をまとめて把握できます。

- ヘッダーに「N/M 完了」のカウンタが出る
- 各サブタスク・delegate 実行はカード表示で、ステータス・出力ファイル・ログ・入力ファイルを開ける
- delegate 実行は展開して「何をしたか」の詳細（ツール呼び出し・成功/中断）を確認できます
- Chat 画面ではインラインのカードとして進捗が流れる

各子は独立ワークスペースを持つため、成果物（`output/`）も子ごとに分かれて配信されます。

## サブタスク内での会話振り返り

サブタスクは実行中、自分自身の会話履歴（transcript）を `SearchTaskConversation` / `ReadTaskConversation` で振り返れます。長く回るサブタスクが序盤の指示や制約を思い出すのに使えます。ただし振り返れるのは自分の履歴だけで、親タスクや他タスクの会話（`SearchWorkspaceTasks`）には引き続きアクセスできません。

## 待機中の入力（割り込み）

親が waiting_subtasks の間でも、Chat 画面から親へメッセージを送れます（割り込み = interjection）。送ったメッセージは、エージェントが次のイテレーションで取り込みます。

- 割り込みが効くのは **running** と **waiting_subtasks** の間
- 入力欄がロックされるのはジョブ割り当て中（dispatching）のみ
- 割り込みは親タスクに対して行われ、実行中の個々の子タスクには直接届きません

## 分解の上限

無限再帰や暴走を防ぐため、`config.yaml` の `subtasks` セクションで上限を設定します（キーはスネークケース）。

```yaml
subtasks:
  max_depth: 2        # SpawnSubTask のネスト最大深度（デフォルト 2、0 で分解禁止）
  max_per_parent: 10  # 1 ジョブが生成できるサブタスクの最大数（デフォルト 10）
```

- `max_depth: 0` にすると分解そのものを無効化できます
- 深度上限に達したジョブでは SpawnSubTask が提示されず、エージェントは自力で処理します
- `max_per_parent` を超える生成はできません

## TIP

> ふだんの分解は委譲実行で十分です。SpawnSubTask の並列化は、独立したテーマが複数あって壁時計時間を縮めたいときだけ、ツール設定で有効にして使います。

> 前の結果に依存する逐次処理は、1 つのタスク内の movement 遷移で扱う方が確実です（→「[ピースの仕組み](05-pieces.md)」）。

> サブタスクへの instruction には、成果物を `output/` にどう書くかまで具体的に指定すると、親がまとめやすくなります。
