maestro/docs/tools/spawnsubtask.md
oss-sync a6d1879d63
Some checks failed
CI / build-and-test (push) Has been cancelled
sync: update from private repo (c764df2f)
2026-06-29 01:32:25 +00:00

6.6 KiB
Raw Blame History

SpawnSubTask

タスクを並列サブタスクに分解して実行する。各サブタスクは独立した workerジョブで動き、完了後に親タスクが結果を集約する。

デフォルト無効opt-in。SpawnSubTask は Bash などと同じセンシティブ扱いのツールで、初期状態ではエージェントに提示されない。使うにはワークスペースの 設定 → ツール タブで明示的に有効化する。有効化していない場合、SpawnSubTask は呼べず、分解は Delegate(直列・インプロセス)で行う。

タスク分解の既定手段は Delegate直列。research / general / brainstorming などのピースは Delegate でサブ調査を 1 件ずつこなす。SpawnSubTask は「壁時計時間の短縮のために独立テーマを本当に並列で走らせたい」ワークスペースだけが有効化する。

基本

SpawnSubTask({
  title: "ローカル LLM 比較調査",
  instruction: "Ollama, vLLM, llama.cpp の最新性能ベンチマークを比較する。各ツールについて: 1) 直近6ヶ月の主要ベンチマーク, 2) ハードウェア要件, 3) 対応モデル一覧 を output/report.md にまとめる。",
  piece: "research"   // 任意。指定しないと自動分類
})

呼び出すと subtasks/{index}/ にサブタスクのワークスペースが作られ、結果はそこに集約される。

いつ使うか

まず Delegate直列で足りるかを検討する。SpawnSubTask は opt-in で有効化したうえで、並列の別ジョブで壁時計時間を縮めたい場合に限って使う。

並列分解が効果的なケース

  • 2 つ以上の 独立したテーマ(互いに参照しない)
  • 各テーマが軽くなく、調査・処理に時間がかかる
  • 分解後の各タスクが単独でも意味を持つ成果物になる
  • 壁時計時間の短縮が GPU・実行枠の追加消費に見合う

例:

  • 「3 つの製品比較レポート」→ 製品ごとに 3 サブタスク
  • 「複数 PDF の OCR 処理」→ ファイルごとに分解
  • 「複数 SNS の情報収集」→ プラットフォーム別に分解

分解しないほうがよいケース

  • 単一テーマで論理的に連続する処理A→B→C のように依存)
  • サブタスクが極端に小さい(オーバーヘッドの方が大きい)
  • 全体像を見ながら判断する必要がある作業(対話的タスク等)

instruction の書き方

  • 完結した依頼文で書く(親タスクの文脈を持たないので、サブタスクは instruction だけで判断する)
  • 期待する成果物(出力ファイル名・場所)を明示
  • 必要な前提情報があれば文中に展開

「これと同じ調査を別キーワードでやって」 「キーワード『A』『B』『C』について、各々のメリット・デメリットを比較する独立した調査を行い、output/A-vs-B.md にまとめる」

piece の指定

  • 省略時: 親と同じ classifier ロジックで自動選択
  • 明示する場合: research, general, office-process 等の piece 名を指定

WaitSubTask完了待ち

SpawnSubTask でサブタスクを起動したあとは、WaitSubTask(引数なし)を 1 回呼んで全サブタスクの完了を待つ

SpawnSubTask({ title: "A の調査", instruction: "..." })
SpawnSubTask({ title: "B の調査", instruction: "..." })
SpawnSubTask({ title: "C の調査", instruction: "..." })
WaitSubTask()   // ここで全部の完了を待つ
// 再開後、subtasks/*/result.md を Read して集約 → complete
  • WaitSubTask同期的にブロックしない。呼ぶとジョブはいったん停止parkして worker を解放し、全サブタスクが終わると 同じ movement のまま再開 する
  • 再開時、各サブタスクの結果は subtasks/{index}/result.md に書き出されている。Read で読んで集約レポートを作る
  • 起動した分の成果物は subtasks/{index}/output/ 以下にも残る

ワークフロー

  1. SpawnSubTask を必要な数だけ呼ぶ(並列に起動される)
  2. WaitSubTask() を 1 回呼ぶ
  3. 再開後、subtasks/*/result.md を読んで集約する
  4. complete で終了する

auto-park取りこぼし防止

サブタスクがまだ走っている最中に completesuccessを呼んでも、エンジンが偽の完了を返さず、自動で park して完了を待つWaitSubTask を呼び忘れても結果を取りこぼさない安全網。とはいえ意図を明示するため、原則 WaitSubTask を明示的に呼ぶこと。

orphan の自動キャンセル

親ジョブが失敗・キャンセル・リトライしたとき、まだ走っているサブタスクは自動でキャンセルされる。親が消えたのに子だけ GPU を使い続ける「ゾンビサブタスク」は発生しない。

ただし ASKユーザー回答待ちで停止した場合は子を残す。親があとで再開して結果を使うため。

delegate との違い

delegate SpawnSubTask + WaitSubTask
既定 デフォルト有効(分解の既定手段) デフォルト無効(要 opt-in 有効化)
実行 直列・インプロセス 並列・別ジョブ
待機 自動1 ツール呼び出しで完結) WaitSubTask で待つ
負荷 GPU・実行枠が軽い 並列ぶん多く消費する
向く用途 逐次の分解・重い委譲全般 独立テーマを並列で短時間化したいとき

起動の間隔spawn_stagger_ms

短時間に大量の SpawnSubTask を呼ぶと、その一団が GPU スロットの優先順位を一気に奪ってしまう。これを避けるため、SpawnSubTask のキュー投入の間に既定で 1 秒の間隔を入れる。

subtasks:
  spawn_stagger_ms: 1000   # SpawnSubTask 投入間の間隔(ミリ秒、デフォルト 1000、0 で無効)
  • 0 にすると間隔を入れず即時に投入する
  • エージェントから見た呼び出し方は変わらない(透過的に間隔が入るだけ)

結果の参照

サブタスク完了後、親タスクは:

  • subtasks/{index}/result.md にサブタスクの要約結果があるRead で読む)
  • subtasks/{index}/output/ 以下にサブタスクの成果物がある

制限

  • ネスト深さは subtasks.maxDepth(デフォルト 2まで
  • サブタスクが waiting_human 等で停止すると親もブロックされる