Task Splitter — 最安価で正しい実行
目標:品質を維持しつつ総コストを最小化してメインタスクを完了すること。 2つのレバー:(1) 各作業を最も安価に実行可能な階層にルーティングする、(2) 同一階層の作業を1つのスレッドにバッチ処理することで、各サブエージェントのコールドスタートコンテキストを一度だけ支払う。
スコアリング前に references/routing-rubric.md を、バッチプロンプトを作成する前に references/batch-brief-template.md を読むこと。
ハードルール
- T0作業はエージェントを生成しない。 決定論的なステップ(インストール、mkdir、mv、設定値、ジェネレーターの実行)はメインスレッドでインライン実行する。コールドスタートのサブエージェントはコマンド実行よりもコストがかかる。
- 安価な階層には決して
subagent_type: "fork"を使用しない。 Forkは常に親モデルで実行され、modelを無視する。代わりに、明示的なmodelとeffortを指定したgeneral-purpose(読み取り専用の探索にはExplore)を使用する。 - このスキルは、呼び出すすべてのAgent呼び出しに
effortを設定することを明示的に許可する。 階層テーブルに従って設定すること。Agent呼び出しには常にmodelとeffortの両方を渡す。 - 検証はモデルではなくスクリプトで行う。 テスト、リント、型チェック、ビルドはメインスレッドで実行する。スクリプトでチェックできるコードのレビューにモデル呼び出しを費やしてはならない。
- エスカレーションは失敗したサブタスクのみを、1段階上の階層に、1回だけ行う。 1回のエスカレーション後は停止し、ユーザーに問い合わせる。
- 同じファイルを編集する2つのサブタスクを、同一ウェーブの異なるバッチに決して含めてはならない。
階層テーブル(デフォルト — ルーティングログで調整すること)
| 階層 | スコア | 実行形態 | 典型的な作業 |
|---|---|---|---|
| T0 | 0 | メインスレッド、インラインシェル | 依存関係のインストール、ディレクトリの作成、リネーム、環境変数/設定値の設定 |
| T1 | 1–3 | model: haiku、effort: low | 既存パターンに従ったボイラープレート、コピー編集、単純なCRUD配線、ドキュメント、フィクスチャ |
| T2 | 4–6 | model: sonnet、effort: medium | 通常の機能コード、コンポーネント、エンドポイント、既存パターンに従ったテスト |
| T3 | 7–8 | model: sonnet、effort: high | 複数ファイルにわたるロジック、状態管理、統合、トリッキーなバグ、認証/支払い/セキュリティ |
| T4 | 9–10 | model: opus、effort: high | アーキテクチャ、横断的設計、データモデル、困難なデバッグ、パフォーマンス/並行性 |
プレビュー用の相対コスト重み:haiku = 1、sonnet = 3、opus = 5;努力量倍率 low = 1、medium = 1.5、high = 2.5。T0 ≈ 0。
ワークフロー
フェーズ0 — キャプチャと永続化
- メインタスクを10行以内に言い換える:目標、制約、受け入れ基準、スタック、対象外。
- スラッグを導出する。
<プロジェクト>/.claude/task-splitter/に既存の台帳があるか確認する(ls .claude/task-splitter/ 2>/dev/null)。このタスクに一致し、未完了のサブタスクがある場合は、そこから再開する(作業が完了していない最初のフェーズにスキップする)。 - そうでなければ、
<プロジェクト>/.claude/task-splitter/<YYYY-MM-DD>-<スラッグ>.mdをtemplates/split-ledger.mdから作成し、コンテキストセクションを埋める。各フェーズ後に更新する。プランモードで、プランファイル外へのファイル書き込みが許可されていない場合、台帳の内容をプランファイルの## 台帳見出しの下に配置し、承認後の最初のT0ステップとして実際のファイルを作成する。
フェーズ1 — 軽量偵察
分割に必要なものだけを読む:マニフェスト(package.json、pyproject 等)、エントリーポイント、機能が触れるファイル、再利用可能なユーティリティ。広範な検索が必要な場合は、1つの Explore エージェントを model: haiku、effort: low で使用し、パスと1行の調査結果のみを要求する。再利用可能なユーティリティと正確なファイルパスを台帳に記録する — これらは安価なエージェントが再探索することを防ぐコンテキストパケットとなる。
フェーズ2 — 分割
作業を原子的なサブタスクに分割する。各サブタスクは以下を持つ:
id (S1, S2…)、goal (1文)、files (正確なパス、新規または既存)、depends_on (ID)、done_check (pnpm test foo のようなコマンドまたは正確な基準)、type (短いタグ:インストール、スキャフォールド、コンポーネント、エンドポイント、テスト、マイグレーション、リファクタリング、設定、ドキュメント、デバッグ、設計…)。
原子的であること = 1つのエージェントが、他のサブタスクに属する決定を必要とせずに完了できること。設計上の決定は、それ自体の初期のサブタスク(多くの場合T4)に引き出し、後のサブタスクを機械的かつ安価に行えるようにする。
フェーズ3 — スコアリングとルーティング
references/routing-rubric.md の5次元ルーブリック(曖昧さ、推論深度、影響範囲、必要なコンテキスト、新規性;各0~2)で各サブタスクをスコアリングし、オーバーライドルールを適用し、スコアを階層にマッピングする。
次に、~/.claude/task-splitter/routing-log.md(存在する場合)を確認する:ある type が過去3回の実行中2回以上、特定の階層でエスカレーションされた場合、その階層を1段階上げて開始する;選択した階層より1段階低い階層で3回連続で初回合格した場合、階層を1段階下げることを検討する。
フェーズ4 — バッチ処理
- 依存関係ウェーブを構築する:ウェーブ1 = 未解決の依存関係がないサブタスク;ウェーブN = すべての依存関係が以前のウェーブにあるサブタスク。
- 各ウェーブ内で、
(model, effort)でグループ化し、さらにコード領域(同じ機能フォルダー/モジュール)でグループ化する。これにより、1つのエージェントが関連ファイルを一度にロードできる。 - バッチごとの制限:サブタスク数≤6または1つの一貫した領域;同一ウェーブ内で2つのバッチが同じファイルを編集しない(競合するサブタスクを同じバッチに移動するか、次のウェーブに移動する)。
- 小さなバッチを統合する:孤立したT1サブタスクは、同一ウェーブに別のT1バッチが存在すればそれに参加させる;ほとんど機械的な孤立したT1サブタスクは、代わりにインラインで実行してもよい。
- T0サブタスクは、そのウェーブの開始時に単一のインラインステップにグループ化する。
フェーズ5 — コストプレビュー(承認ゲート)
プランファイルに書き込む(プランモード外ではユーザーに表示する):
| ウェーブ | バッチ | モデル / 努力量 | サブタスク | 推定コスト |
|------|-------|----------------|----------|-----------|
| 1 | インライン| main / shell | S1, S2 | ~0 |
| 1 | B1 | haiku / low | S3, S4 | 2 |
| 1 | B2 | sonnet / medium| S5 | 4.5 |
| 2 | B3 | opus / high | S6 | 12.5 |
合計 ≈ 19 単位 (すべてOpus/高努力量のベースライン ≈ 75 単位 → 約75%削減)
推定コスト = サブタスク数 × モデル重み × 努力量倍率。すべてOpus/高努力量のベースラインを含めることで、削減額がわかるようにする。プランモードでは、ExitPlanModeで終了する。承認前には実行しない。
フェーズ6 — 実行
各ウェーブに対して、順番に:
- ウェーブのT0インラインステップを実行する。
- ウェーブのすべてのバッチを1つのメッセージで起動する(並列Agent呼び出し):
Agent(subagent_type: "general-purpose", model: <階層model>, effort: <階層effort>, description: "<ウェーブ>/<バッチ>: <短い説明>", prompt: <簡潔>)。 各ブリーフはreferences/batch-brief-template.mdから構築する。共有プリアンブルはすべてのバッチでバイト単位で同一にすること(プロンプトキャッシュに優しい)— 可変コンテンツはその後ろに配置する。 - 次のウェーブを開始する前に、ウェーブのすべてのバッチが報告するのを待つ。保留中のエージェントの結果を書き出したり推測したりしてはならない。
- 各バッチのステータスと報告されたファイルで台帳を更新する。
フェーズ7 — 検証とエスカレーション
- 各ウェーブ後、メインスレッドはサブタスクの
done_checkコマンドと、プロジェクトの安価なグローバルチェック(型チェック/リント/影響を受けるテスト)を実行する。 - 失敗したサブタスクは、1段階上の階層で、失敗した出力と以前のエージェントのレポートを添付して、単独で(または同じ新しい階層の他の失敗と一緒に)再実行される。
- サブタスクごとに最大1回のエスカレーション。それでも失敗する場合は、停止し、簡単な診断とともにユーザーに問い合わせる。T4の失敗は直接ユーザーに問い合わせる。
フェーズ8 — 記録と学習
- 台帳を完了としてマークする:サブタスクごとの最終階層、合格/エスカレーション、変更されたファイル。
- 各サブタスクの1行を
~/.claude/task-splitter/routing-log.mdに追加する(フォルダー/ファイルが存在しない場合は作成する;スキルのgitリポジトリ内では決して作成しない):YYYY-MM-DD | <プロジェクト> | <タイプ> | <開始階層> | <最終階層> | 初回合格|エスカレーション|失敗 - ユーザーに10行以内で報告する:行われたこと、最終コストとベースラインの比較、エスカレーションの有無、未解決の事項の有無。
出力規則
- メインスレッドは軽量に保つ:エージェントはファイル内容ではなく短いレポートを返す。
- 分割とコストプレビューには、散文ではなくテーブルをユーザーに提示する。
- タスク全体のスコアが合計≤3、またはサブタスクが≤2個の場合は、そのように伝えて直接実行する — 分割すると節約以上のコストがかかる。