部品はあるのに毎回つなぎ直す ─ Workflows で skill 3 役と Subagent を 1 つの司令塔に束ねる

/fetch-weather を呼んで、その結果を /render-card に手で渡して、それを notion-poster Subagent に渡して、最後にメインの Claude に「Notion に投稿しといて」と打つ。毎朝この 4 ステップを手で繋いでいませんか?

私は半年これをやっていました。skill を 4 つ作って、Subagent を 3 つ作って、.claude/skills/ には手で叩く skill が 5 つ並んでいて、それぞれは確かに動きます。でも、それらを「順番に呼ぶ」ところは毎回メインコンテキストで手作業。3 つ目を呼び忘れて、4 つ目に変な引数を渡して、結局やり直す。

部品はあるのに、組み立てだけ毎回ゼロから組み直している状態でした。

これも Claude Code 側ですでに整理されています。司令塔 skill を 1 つ書くだけで、Subagent と部品 skill が順番に呼ばれて、ユーザーは /weather-orchestrator の一発で終わる、という型です。シリーズ過去回で扱った Skills のデフォルト挙動(#04)/Subagents(#05)/Skill の手動 invoke(#06)の組み合わせを 1 つに束ねる、4 大コア概念の 4 つ目です。

なお #06 で書いた通り、2025 後半に Custom Slash Commands は Skills に統合されました。本記事では .claude/commands/<name>.md ではなく .claude/skills/<name>/SKILL.md 側で書きます。.claude/commands/ は今も後方互換で動きますが、新規は Skills 側で書くのが推奨です。

3つの役割は性格が違う

まずは 3 役の整理から。同じ「拡張」と呼ばれていても、それぞれ得意分野がはっきり違います。

  • 司令塔 skill = 人間が /コマンド名 で叩く。disable-model-invocation: true を付けて「私だけが叩く」型にする。ユーザーとの対話、ワークフロー全体の流れの制御、Subagent や部品 skill への委譲を担う
  • Subagent = データ取得・調査担当。独立コンテキストで重い処理を回し、結果だけメインに返す。ログや読み込んだファイル本文をメインに撒かない
  • 部品 skill = 出力生成担当。ファイル書き出し・SVG 生成・整形など、再利用可能な手順を 1 ファイルにまとめたもの

プログラミングに例えると、司令塔 skill は main() やコントローラ、部品 skill はメソッドや共通関数、Subagent は別スレッドで動く専門ワーカー、というイメージで読み進めてもらって構いません(実体は frontmatter とプロンプトを書いたマークダウンファイルで、Claude が呼び出して中の指示を実行する仕組みです)。

3 役を 1 つの絵で並べるとこうなります。

flowchart TD User["ユーザー<br/>/weather-orchestrator"] Cmd["司令塔 skill<br/>(disable-model-invocation: true)"] Sub["Subagent<br/>(独立コンテキスト)"] SkillP["部品 skill (preload)<br/>Subagent の知識"] SkillT["部品 skill (Skill tool)<br/>出力生成"] Main["メイン会話"] User --> Cmd Cmd -- "Agent tool" --> Sub Sub -. "起動時に注入" .- SkillP Sub -- "Skill tool で呼ぶ" --> SkillP Sub -- "結果だけ返す" --> Cmd Cmd -- "Skill tool" --> SkillT SkillT -- "ファイル書き出し" --> Cmd Cmd --> Main

司令塔 skill が真ん中で指揮を執り、左で Subagent にデータ取得を投げて、右で部品 skill に出力生成を投げる。ユーザーは入口の /weather-orchestrator だけ覚えていればよい。

「全部メインに置く」と詰む理由は前回までで扱いました

skill を増やしすぎると character budget を食う話は #04 Skills 入門 で、Subagent をいつ作るかの判断基準は #05 Subagents 入門 で、disable-model-invocation: true を付けた手動 invoke 型 skill の最小構成は #06 Skills 手動 invoke 入門 で、それぞれ書きました。本記事ではこれらの話を繰り返さず、「3 役を 1 つの司令塔で束ねる」 ところだけに集中します。

3 役を司令塔 skill に束ねると、メインの Claude(とその先のユーザー)は /weather-orchestrator を呼ぶ」しか覚えなくていい。記憶のコストが 1 になります。手順書のうち頻繁に変わる部分(API のエンドポイント、SVG の色、ファイル保存先)は部品 skill 側に閉じ込められるので、司令塔 skill を触る必要がなくなります。

誰が誰を呼ぶか — Agent tool と Skill tool の使い分け

公式 docs の言葉づかいを踏まえると、3 役間の呼び出し関係は 3 種類しかありません。

呼ぶ側呼ばれる側使う仕組み
司令塔 skillSubagentAgent toolsubagent_type: <agent-name> で指定)
司令塔 skill または Subagent部品 skillSkill toolskill: <skill-name> で呼び出し)
Subagent 起動時部品 skillfrontmatter の skills: リスト(preload)

skills: での preload と Skill tool での動的呼び出しは、見た目が似ていても別物です。公式 Subagents docs はこう説明しています:

The full content of each listed skill is injected into the subagent’s context at startup. This field controls which skills are preloaded, not which skills the subagent can access: without it, the subagent can still discover and invoke project, user, and plugin skills through the Skill tool during execution.

リストされた各スキルの完全なコンテンツは、起動時にサブエージェントのコンテキストに挿入されます。このフィールドは、サブエージェントがアクセスできるスキルではなく、どのスキルがプリロードされるかを制御します。このフィールドがなくても、サブエージェントは実行中にスキルツールを通じてプロジェクト、ユーザー、およびプラグインのスキルを検出して呼び出すことができます。

つまり:

  • preload = 起動時に skill の本文を全部コンテキストに注入する。Subagent はその知識を読んだ状態で動き始める。動的呼び出しではなく、ドメイン知識として常駐する
  • Skill tool 呼び出し = 必要なタイミングで skill を実行する。終わったら結果が返ってくる

「ある skill のことを知っている」と「その skill を実際に走らせる」は別の操作です。実装で両方を使うこともあります(次節の weather 実装がまさにそれ)。

コミュニティ実装の weather 例で 2 パターンを見る

shanraisshan さんが orchestration-workflow.md で公開しているリポジトリには、司令塔 skill → Subagent → 部品 skill の完全実装が置かれています。Anthropic 公式ではなく個人による best-practice の整理ですが、部品 skill の preload パターンと動的呼び出しパターンを同じワークフローで両方使う良い実装例です。

実装は 4 つのファイルからなります。

ファイル役割
.claude/skills/weather-orchestrator/SKILL.md司令塔 skill(手動 invoke 型)
.claude/agents/weather-agent.mdSubagent(データ取得)
.claude/skills/weather-fetcher/SKILL.md部品 skill(preload で Subagent に注入)
.claude/skills/weather-svg-creator/SKILL.md部品 skill(司令塔から動的呼び出し)

実行フローは 3 ステップです。

sequenceDiagram autonumber actor User as ユーザー participant Cmd as /weather-orchestrator<br/>(司令塔 skill) participant Agent as weather-agent<br/>(Subagent) participant Fetcher as weather-fetcher<br/>(部品 skill / preload) participant API as Open-Meteo API participant SVG as weather-svg-creator<br/>(部品 skill / Skill tool) User->>Cmd: /weather-orchestrator Cmd->>User: AskUserQuestion<br/>(摂氏か華氏か?) User-->>Cmd: 摂氏 Cmd->>Agent: Agent tool<br/>(subagent_type: weather-agent, prompt: 摂氏で温度を) Note over Agent,Fetcher: 起動時に weather-fetcher が<br/>frontmatter skills: で preload 済み Agent->>Fetcher: Skill tool<br/>(skill: weather-fetcher) Fetcher->>API: WebFetch<br/>(Dubai の温度) API-->>Fetcher: 26 (摂氏) Fetcher-->>Agent: temperature=26, unit=摂氏 Agent-->>Cmd: temperature=26, unit=摂氏 Cmd->>SVG: Skill tool<br/>(skill: weather-svg-creator) SVG-->>Cmd: weather.svg + output.md 生成完了 Cmd-->>User: 完了サマリ

左側ライン(Step 4〜6)が preload された部品 skill のパターンweather-fetcherweather-agent の frontmatter skills: に書かれていて、Subagent 起動時に本文がコンテキスト注入されます。Subagent はその知識に基づいて Skill tool で weather-fetcher を呼びます。

右側ライン(Step 8〜9)が 独立 skill のパターンweather-svg-creator はどの Subagent にも preload されていません。司令塔 skill から Skill tool で直接呼び出されます。

真ん中の司令塔 skill が Agent tool と Skill tool を両方使う指揮役として機能します。

司令塔 skill の中身は 30 行で済む

weather-orchestrator/SKILL.md の本体を見てみます。司令塔と聞くと複雑そうですが、実体は短い指示書です。

---
description: ドバイの天気を取得して、SVG の天気カードを作成する
disable-model-invocation: true
model: haiku
allowed-tools: - AskUserQuestion - Agent - Skill
---
# Weather Orchestrator(司令塔)
ドバイ(UAE)の現在の気温を取得し、SVG の天気カードを生成する。
## ワークフロー
### Step 1: ユーザーに単位を確認
AskUserQuestion ツールを使い、ユーザーに気温の単位(摂氏か華氏か)を確認する。
選択された単位を捕捉してから次へ進む。
### Step 2: Subagent で気象データを取得
Agent ツールを使い、weather-agent を呼び出す。
- subagent_type: weather-agent
- prompt: ドバイ(UAE)の現在の気温を [ユーザーが選んだ単位] で取得し、 数値と単位を返す。
- model: haiku
### Step 3: SVG 天気カードを生成
Skill ツールを使い、weather-svg-creator を呼び出す。
- skill: weather-svg-creator

ポイントは 4 つ。

  1. disable-model-invocation: true を付けている — 司令塔は私が叩きたいタイミングで動かしたいので、Claude が auto-discovery で勝手に起動するのを止めます
  2. allowed-toolsAgentSkill を両方許可している — これが司令塔の必須セットです。AskUserQuestion は Step 1 の対話用。Bash も WebFetch もここには入れません。司令塔はあくまで指揮役で、実作業は委譲先がやる
  3. 「Step 1 → Step 2 → Step 3」の指示書を日本語の段落のように書いてある — if-then のスクリプトを自分で書く必要はありません。Claude Code がこのマークダウンを読んで、それぞれのステップで対応するツールを呼んでくれる
  4. model: haiku を指定している — 司令塔は判断が単純なので、軽量モデルで十分。重い処理は Subagent 側に書いて、そこで sonnet を使う

実コードはこれだけ。30 行のマークダウンが、3 役を順番に呼ぶ司令塔として機能します。

Execution Contract — Claude が省略するのを止める(推奨パターン)

ここからは shanraisshan さんの公開実装には含まれていませんが、私が司令塔 skill を書くときによく追加するパターンを 1 つ紹介します。司令塔 skill 本文に「やってはいけないこと」を明示しておくと、Claude が暴走するのを大きく減らせます。

例えば weather-orchestrator 相当の司令塔に、私はこういう Execution Contract ブロックを足します。

## Execution Contract(厳守)
このコマンドは必ず weather-agent Subagent に委譲して完了させること。次は禁止:
- Bash・WebFetch・その他のツールで自分で気象データを取得する
- Step 1 を飛ばす(ユーザーの単位選択は agent への必須入力)
- agent が気温を返す前に weather-svg-creator を呼ぶ
Agent ツールを呼び出せない場合は、停止してユーザーにエラーを報告すること。即興で代替してはいけない。

これは「自分で WebFetch すれば早いんじゃないか」と Claude が判断してショートカットするのを止めるための 明示的な禁止リストです。

オーケストレーション設計でいちばん壊れやすいのが、まさにこの「途中で Claude が省略する」。Subagent を経由せずに直接 WebFetch を呼んでしまうと、Subagent 側で書いたメモリ更新(履歴記録など)がスキップされ、ログも残らない。表面的には動いて見えるので発見が遅れる。

3〜5 行の禁止リストを司令塔 skill 本文に入れるだけで、設計通りに動く確率が大きく上がります。

Subagent 側にも Execution Contract を書く

同じ思想で、Subagent 側にも禁止リストを足しておきます。weather-agent 相当の Subagent ならこんな書き方になります。

## Execution Contract(厳守)
気温の取得は必ず **Skill ツール** 経由で weather-fetcher skill を呼び出して行うこと。次は禁止:
- WebFetchWebSearchcurl など HTTP/API 系ツールを自分で叩く
- skill の指示を読み取って自分の中でインライン実行する
- 理由(キャッシュ済み、「もう値は知っている」など)を問わず、Skill ツールの呼び出しを省略する
このエージェントのツール許可リストは、意図的にネットワーク系ツールを除外している。もし「ネットワークツールが必要だ」と感じたら、それは skill を迂回しているサインである。停止して Skill(weather-fetcher) を使うこと。

ポイントは、「ツール許可リストから WebFetch を外す」ことと「禁止リストに『自分で WebFetch するな』と書く」ことを両方やる点です。構造(ツール許可リスト)と指示(本文の Execution Contract)の二段構えで省略を防ぎます。許可リストから外しておけば物理的に呼べませんが、それでも Claude は「Bash で curl を組み立てる」など別ルートを探そうとするので、本文側で明示的に止める価値があります。

設計上のポイントは、禁止リストの最後の段落:

このエージェントのツール許可リストは、意図的にネットワーク系ツールを除外している。もし「ネットワークツールが必要だ」と感じたら、それは skill を迂回しているサインである。

「ツールがない=代替手段を探せ」ではなく「ツールがない=正しい呼び方をしていない」と読ませる書き方。Claude にメタ認知させる効果があります。

Subagent の frontmatter — preload と allowedTools の組み合わせ

weather-agent.md の frontmatter は短いです。

---
name: weather-agent
description: ドバイ(UAE)の気象データが必要なときに積極的に呼び出すこと。このエージェントは Skill ツール経由で weather-fetcher skill を呼び、リアルタイム気温を取得する。
allowedTools: - "Read" - "Skill"
model: sonnet
color: green
maxTurns: 5
permissionMode: acceptEdits
memory: project
skills: - weather-fetcher
---

注目するのはこの 3 行の組み合わせ。

  • skills: [weather-fetcher] — 起動時に weather-fetcher の全文がコンテキストに注入される
  • allowedTools: [Read, Skill] — Skill tool が許可リストにあるので、weather-fetcher を実際に呼べる
  • WebFetchBashWebSearch入っていない — Subagent 単独では API を叩けない構造

「preload で『この部品 skill の存在と全文を知っている』」「Skill tool で『その手順を実行する』」「allowedTools で『その実行を許可する』」の 3 段階で、ぴったり閉じた設計になっています。

description に「積極的に」が入っているのもポイントで、メインの Claude がこの Subagent を auto-discovery で呼びやすくするためのキーワードです。公式 Subagents docs には「To encourage proactive delegation, include phrases like ‘use proactively’ in your subagent’s description field(積極的な委任を促進するには、サブエージェントの説明フィールドに「積極的に使用する」などのフレーズを含めます。)」と書かれています。

どこまで skill で、どこから Subagent か

ここまでで「部品 skill 2 種類、Subagent 1 種類、司令塔 skill 1 種類」の役割分担を見ました。私が実装するときに迷うのは「ある処理を skill にすべきか Subagent にすべきか」です。

判断基準を 1 つだけ決めると楽になります:「コンテキストを別世界に切り離したいか」

  • 部品 skill で十分: 「同じ手順を書いて、必要なときに呼び出して、ファイルを書き出す」だけ。メインコンテキストの続きで動いてよい
  • Subagent が必要: 「10 ファイル読む」「外部 API を 5 回叩く」「100 行のログが出る」「結果は要約だけ欲しい」。メインコンテキストにログを撒きたくない

weather の例で当てはめると、

  • データ取得(weather-fetcher)は 部品 skill だが Subagent に preload して呼ぶ。API レスポンスのフルボディはメインコンテキストに来てほしくない。Subagent の独立コンテキストで temperature_2m だけ抽出して、26 という数字だけ返してもらう
  • SVG 生成(weather-svg-creator)は 独立 skill。司令塔のコンテキストにすでに温度値があり、SVG テンプレートに代入してファイル書くだけなので、別コンテキストにする必要がない

経験則として、デバッグログが要らなくなる単位で Subagent に切り分けると、メインの会話が読みやすくなります。逆にメインコンテキストに「途中の判断材料」を残したい処理は部品 skill のままにする。

ハマる罠 4 つ

実装で踏みやすいポイントを 4 つ。

罠 1: 司令塔 skill の本文に複雑な手順を全部書いてしまう

司令塔 skill が 200 行になっていたら危険信号です。司令塔は「Subagent を呼ぶ」「部品 skill を呼ぶ」とだけ書くのが weather 実装の設計。実作業は Subagent 側か部品 skill 側に書く。

「Step 2 で WebFetch を 5 回叩いて…」が司令塔本文に書いてあったら、それは Subagent に切り分けるべき処理です。司令塔が長くなる=指揮役が現場仕事まで抱えている状態。

罠 2: 同じ部品 skill を preload と Skill tool の両方で呼ぶ

公式 Skills docs は、preload と Skill tool 呼び出しが排他ではなく併用できる設計だと書いています。weather 実装も併用しています。

ただし、初心者が混乱しやすいのは「Subagent の skills: にも書いて、司令塔からも Skill tool で呼ぶ」と二重ロードになるケース。同じ skill の本文がメインと Subagent の両方のコンテキストに乗ります。

判断基準: 「Subagent がその skill の知識を読み込んだ状態で動き始めてほしい」なら preload「特定のタイミングで実行だけしたい」なら Skill tool。weather-fetcher は前者(Subagent が温度取得の手順を知った状態で動く)、weather-svg-creator は後者(司令塔が温度を持ったタイミングで実行だけしたい)。

罠 3: Execution Contract を書かない

「自分で WebFetch すれば早いんじゃないか」と Claude が判断する瞬間は必ず来ます。司令塔本文と Subagent 本文の両方に、3〜5 行の禁止リストを入れておく。

私の経験では、Contract を書かずに作った司令塔は 3 回に 1 回くらい途中で省略します。書いておけば省略はほぼゼロになります。

罠 4: Subagent から Subagent を Bash で呼ぼうとする

リポジトリの CLAUDE.md にこう書いてあります(shanraisshan さんが公開しているもの):

Subagent は bash コマンド経由では 別の Subagent を呼び出せない。Agent ツールを使うこと(v2.1.63 で Task から改名。Task(...) も引き続きエイリアスとして動く)。

Bash で claude --agent を叩く方式と、Agent tool で subagent_type を指定する方式は別物です。Subagent から Subagent を呼ぶときは、後者を使います。

「vague terms like ‘launch’ that could be misinterpreted as bash commands」(bash コマンドと誤解されかねない launch のような曖昧な語)を避けろ、と続きにあります。Subagent の指示書に「launch a subagent for…」のような曖昧な動詞を使うと、Claude が Bash で実行コマンドを組み立てようとすることがある。Use the Agent tool with subagent_type: ...(Agent ツールを subagent_type: ... 付きで使え)のように、明示的にツール名で書きます。

今週やる 1 つ — /morning-report を 3 役で書き直す

#06 で書いた /morning-check を、Workflows 形式に発展させます。3 つのファイル合計 50 行で、司令塔 skill / Subagent / 部品 skill の 3 役分担のミニ事例ができます。

ファイル 1: .claude/skills/morning-report/SKILL.md(司令塔・15 行)

---
description: 直近 5 コミットを解析して、reports/YYYY-MM-DD.md に日次レポートを書き出す
disable-model-invocation: true
allowed-tools: - Agent - Skill
---
# Morning Report(司令塔)
## Execution Contract(厳守)
ログ解析は必ず git-diff-analyzer Subagent に委譲すること。
git コマンドの実行や、ソースファイルを自分で読むことは禁止。
## ワークフロー
### Step 1: Subagent で直近コミットを解析
Agent ツールを使い、git-diff-analyzer を呼び出す。
- subagent_type: git-diff-analyzer
- prompt: 直近 5 コミットを 3 つの箇条書きで要約せよ。要約テキストだけを返す。
### Step 2: Skill で日次レポートを書き出す
Skill ツールを使い、Step 1 の要約を渡して daily-report-writer を呼び出す。

ファイル 2: .claude/agents/git-diff-analyzer.md(独立コンテキスト・20 行)

---
name: git-diff-analyzer
description: 直近の git アクティビティを要約するときに PROACTIVELY 呼び出すこと。git log と diff の出力を解析し、簡潔な箇条書き要約を返す。
allowedTools: - "Bash(git *)" - "Read"
model: haiku
maxTurns: 5
---
# Git Diff Analyzer(Subagent)
## Execution Contract(厳守)
git データは自分で解析すること。さらに別 Subagent に委譲してはいけない。返すのは要約のみで、生の diff 内容は含めない。
## ワークフロー
1. 実行: git log --oneline HEAD~5..HEAD
2. 実行: git diff --stat HEAD~5..HEAD
3. 影響度が大きい上位 3 件の変更を特定する
4. 返却: 日本語の箇条書き 3 件、各 60 文字以内

ファイル 3: .claude/skills/daily-report-writer/SKILL.md(再利用手順・15 行)

---
name: daily-report-writer
description: 渡された要約テキストを reports/YYYY-MM-DD.md に書き出す
allowed-tools: - "Read" - "Write"
---
# Daily Report Writer(部品 skill)
## タスク
呼び出し元コンテキストから要約テキストを受け取る。それを日次レポートファイルに書き出す。
## 手順
1. 当日の日付を YYYY-MM-DD 形式で用意する
2. 要約を reports/<date>.md に書く。先頭の見出しは # Daily Report <date>3. ファイルが既に存在する場合は、上書きせず新しいセクションを追記する

3 つを保存したら、/morning-report を一発打つだけで「Subagent が git ログを別コンテキストで解析 → 部品 skill が要約をファイル書き出し」が走ります。

メインの会話には git の生ログも diff も流れてきません。Subagent の独立コンテキストで処理されて、要約 3 行だけ司令塔に戻ってきます。

まとめ: 部品作りと司令塔書きは別の作業

私自身、最初は司令塔と Subagent と部品 skill を「使い分ける」発想がなく、全部 1 ファイルにベタ書きしていました。/daily-report の本文が 400 行になり、Claude が途中で省略するようになり、修正もどこを触ればいいか分からなくなりました。

3 役に切り分けたら、司令塔が 15 行になり、Subagent と部品 skill の責任が明確になり、修正もどこを触ればいいか即座に分かるようになりました。司令塔を触らずに、Subagent の出力フォーマットだけ変えたいときは Subagent ファイルだけ開く。SVG の色だけ変えたいときは部品 skill ファイルだけ開く。

部品を作るのと、部品を組み立てる司令塔を書くのは別の作業です。後者を覚えると、Claude Code が「単発ツール集」から「自分専用の業務システム」に変わります。

TL;DR

  • 司令塔 skill → Subagent → 部品 skill の 3 役を分担すれば、ユーザーは 1 つの /コマンド名 だけ覚えればよい
  • 司令塔は短い指示書(disable-model-invocation: true 付き)、Subagent は独立コンテキストのデータ取得、部品 skill は再利用手順の出力生成
  • Agent tool で Subagent を呼び、Skill tool で部品 skill を呼ぶ。両方を allowed-tools に入れた skill が司令塔になる
  • 部品 skill には 2 つの呼ばれ方がある: Subagent の frontmatter skills: で preload、または Skill tool で動的呼び出し
  • Execution Contract(やってはいけないことリスト)を司令塔と Subagent の両方に書くと、Claude が途中で省略しなくなる
  • 罠: 司令塔が太りすぎる / preload と tool 呼び出しの混在 / Contract を書かない / Subagent から Bash で claude –agent を叩く
  • 今週やる 1 つ: /morning-report を司令塔 skill / Subagent / 部品 skill の 3 ファイル 50 行で書き直す