AIエージェントを組んでいると、ある時点で必ず「重いタスクを別コンテキストウィンドウで動かしたい」という要件にぶつかります。会話履歴が肥大化してLLMの精度が落ちる、観点ごとに専門家を分けたい、並列で複数の観点を走らせたい。理由はだいたいこのあたりです。

このとき検討対象になるサブエージェント機構として、本稿では3つを扱います。

どれを選んでも「親と分離した別コンテキストで子を起動する」という効果は同じです。違いは 定義ファイルの場所と書き方、そしてランタイムごとの可搬性 に出ます。実装イメージを伴って整理します。


別コンテキストを作るのは指示書ではなくランタイムのツール

最初に押さえたい原則です。

AGENTS.md / CLAUDE.md などの指示書 = 何をすべきか書いてあるだけ
ランタイムが提供するツール          = 実際にコンテキストを切るエンジン

両方が揃って初めて別コンテキストが生まれます。指示書に「サブを呼べ」と書いただけではコンテキストは分離しません。実際にプロセスやsessionを切るのは、ランタイムが内蔵しているツール の仕事です。

ランタイム 別コンテキストを作るツール
Claude CodeTaskツール(別名Agentツール)
Codex CLIspawn_agentツール
OpenClawsessions_spawnツール

そして重要なのが、これらのランタイムは同居しません。あるプロセス内で動いているのはどれか1つだけで、他のランタイムのツールはそこから呼べません。OpenClawの中でClaude CodeのTaskツールが使えたりはしないということです。

お知らせ

OpenClawの構築代行・コンサルティングなど、お気軽にご相談ください。
エージェント設計・ワークスペース構成・Heartbeat / Slack連携の本番運用まで、月額AI顧問サービス(CAIO)として伴走支援しています。自社にAI実装ノウハウを蓄積したい企業向け。

月額AI顧問サービス(CAIO)を見る

各機構の定義方法

ここからが本題です。同じ「戦略コンサル観点のサブ」を作るとして、それぞれの流儀でどう書くかを並べます。

Claude Code Task: マークダウン1ファイル

.claude/agents/consultant-strategy.md
---
name: consultant-strategy
description: 戦略・競争・ポートフォリオ観点の経営レビューを行う
tools: Read, Grep, WebSearch
---
あなたは戦略コンサルタント専門のサブエージェントです。
Porter / Christensen / Lean Startupの知見を使い…
出力フォーマット: JSON {verdict, reasons[], next_actions[]}

これだけで完結します。フロントマターにname / description / 使えるツール一覧を書き、本文がシステムプロンプトになります。1ファイル置くだけ でTaskツールから呼び出せるようになる。これがClaude Code方式の最大の魅力です。

Codex spawn_agent: TOMLファイル1個

.codex/agents/consultant-strategy.toml
name = "consultant-strategy"
description = "戦略・競争観点の経営レビューを行う"
model = "claude-opus-4-7"
sandbox_mode = "read-only"
developer_instructions = """
あなたは戦略コンサルタント専門のサブエージェントです。
Porter / Christensen / Lean Startupの知見を使い…
"""

こちらも1ファイルで完結します。MarkdownではなくTOML形式で、本文はdeveloper_instructions = """..."""の文字列内に書きます。Claude Codeとの拡張子・構文の違いはありますが、「1ファイル = 1サブ」という設計思想は共通です。

OpenClaw sessions_spawn: ワークスペースフォルダ単位

ここが本稿で一番強調したい点です。

OpenClawのsessions_spawnは、Claude CodeやCodexのように「サブ専用の単一ファイル」という概念を持ちません。サブ自身も親と完全に同じ流儀の「正規エージェント」として登録します。つまり、サブを増やすたびに ワークスペースフォルダごと作る ことになります。

ワークスペースフォルダを作る

サブ(子セッション)には AGENTS.mdとTOOLS.mdだけが自動注入され、SOUL.md / MEMORY.md / USER.md / IDENTITY.md / HEARTBEAT.md / BOOTSTRAP.mdは注入されません。子の人格・口調・出力フォーマット・ルールはすべてAGENTS.mdに集約するのが正解です。

workspace-consultant-strategy/
├── AGENTS.md         ← 戦略専門の人格・出力JSON仕様・口調をここに集約
├── TOOLS.md          ← 子が使えるツール仕様
└── memory/           ← 必要なら(親と分離)

「子は分業特化なのでロール定義1ファイルで十分」というOpenClawの設計思想に沿った構成です。親と同じファイル構成を子にも作る必要はありません。

openclaw.jsonに登録する

{
  "agents": {
    "list": [
      {
        "id": "management-consultant",
        "workspace": "${SHARED_REPO}/workspace-management-consultant",
        "heartbeat": {
          "every": "30m",
          "activeHours": { "start": "09:00", "end": "22:00", "timezone": "Asia/Tokyo" }
        },
        "subagents": { "allowAgents": ["consultant-*"] }
      },
      {
        "id": "consultant-strategy",
        "workspace": "${SHARED_REPO}/workspace-consultant-strategy"
      }
    ]
  }
}

サブも親もここに並列で登録します。「親 → 子」という階層関係はopenclaw.jsonには現れず、どちらも同格の登録エントリとして書く点が独特です。親が子を呼ぶ関係は、AGENTS.md / HEARTBEAT.mdの中に「サブをsessions_spawnで呼べ」と書くことで成立します。

heartbeat設定はトップレベルではなくagents.list[].heartbeatに書く のがポイントです。子エージェントにはheartbeatフィールドを書かないことで「子はheartbeat起動しない」が表現されます。仕様上、いずれかのエージェントにheartbeatブロックがあれば、heartbeatブロックを持つエージェントだけが定期起動対象になります。

つまり

OpenClaw sessions_spawnでは、サブエージェントを「親の小道具」として作るのではなく、「親と同格の独立エージェント」として作る。

これが、Claude CodeやCodexの「1ファイルで完結」スタイルとの一番の違いです。


私が勘違いしていたポイント

検討中に最大のつまずきになったのがここでした。

サブエージェントの定義は、Claude CodeやCodexの感覚で「1ファイル書けば1サブ」と思っていたのですが、OpenClaw sessions_spawnの流儀に乗る場合は 「親も子もワークスペースフォルダを持つ正規エージェント」 であり、サブを増やすたびにworkspace-<name>/を増設し、openclaw.jsonagents.listに並べる、という発想になります。

これは欠点ではなく、設計思想の違いです。サブが独自のMEMORY.mdを持って学習を積み重ねたり、独自のSOUL.mdで人格を持ったりする選択肢が開けます。Claude Code Taskはサブが基本ステートレス(毎回プロンプト本文だけで動く)なので「使い捨て」想定。OpenClaw sessions_spawnは「恒常的に存在し続ける専門家」想定だと考えると腑に落ちます。


ハートビート / Slackトリガーとの組み合わせ

実運用では、サブを直接呼ぶことはほぼありません。HeartbeatやSlackで起動された親が、必要に応じてサブを呼ぶ という二段構造になります。

[OS の launchd / systemd]
       │ 30 分ごと
       ▼
[OpenClaw Gateway デーモン]
       │ heartbeat 設定で "management-consultant" 起動
       ▼
[親セッション]   ← コンテキスト window A
   ├─ workspace-management-consultant/ を読み込み
   ├─ HEARTBEAT.md の指示に従って観点判定
   └─ sessions_spawn(agentId=..., task=...) を呼ぶ
              │
              │  即座に tool_result が返る(中身は accepted /
              │  childSessionKey / runId のみ。実作業結果は
              │  まだ入っていない)
              ▼
       親は sessions_yield で待機状態に入る
              │
              ▼
       [Gateway がサブの新セッション生成]
              │
              ▼
   [サブセッション]   ← コンテキスト window B(完全分離)
       ├─ AGENTS.md + TOOLS.md だけが自動注入される
       └─ 戦略レビューを実行 → 完了
              │
              ▼
       Gateway が「子の作業結果」を OPENCLAW_INTERNAL_CONTEXT
       ブロックに包んだ user_message として親 session に push
              │
              ▼
       親が次のターンで wake → user_message を受け取る
              │
              ▼
       親セッションが結果を memory/ に追記し最終応答を組み立てる

ここで重要な挙動が 「親→子→親」が単一ターンでは完結せず、マルチターンで進行する 点です。sessions_spawnは呼び出し直後に「受付完了」だけを返し、実作業の結果は子の完了後にannounceとしてuser_message経由で親に届きます。OpenClawがyield/wakeを自動でハンドリングしてくれるので親側のコードは書き足さなくて良いですが、「子の結果を直後の同一ターンで連続加工する」モデルではないことは押さえておきましょう。

Slackの場合も入口が違うだけで、Gatewayの先 は同じ流れです。Slackチャンネルから受信したメッセージをmanagement-consultantに渡し、必要ならsessions_spawnでサブに委譲する、という形になります。

この構造の良いところは、HeartbeatとSlackで 親エージェント以下の構造を完全に共有できる 点です。サブを増やしても、入口(Heartbeat / Slack)に手を入れる必要はありません。

HEARTBEAT.mdに書く中身(例)

## 30 分ごとの手順

1. `memory/` の最終更新日を確認
2. 戦略観点が必要なら以下を呼ぶ:

   sessions_spawn(
     agentId="consultant-strategy",
     task="""
     直近1週間の経営スナップショット: {内容}
     依頼: 撤退/拡大判断を XYZ 形式で返せ
     """
   )

3. 子の announce が user_message で戻ってきたら `memory/YYYY-MM-DD.md` に追記
4. 集約ロジックを走らせる

sessions_spawnのパラメータ名はtaskです(messageではない点に注意)。ほかにもlabel / model / thinkingなどのオプションが指定できます。

お知らせ

OpenClawをチームで使いこなす設計、お任せください。
親エージェント・サブエージェントの分割、AGENTS.md / SOUL.md / HEARTBEAT.mdの設計、Slack連携の運用設計まで、月額AI顧問サービス(CAIO)として実装代行・伴走支援を行っています。

月額AI顧問サービス(CAIO)を見る

3機構の比較

Claude Code Task Codex spawn_agent OpenClaw sessions_spawn
定義形式Markdown + YAMLTOMLMarkdown群 + JSON5登録
サブ1個あたりのファイル数11最小1(フルだと5〜7)
登録作業不要不要openclaw.jsonに追記
サブ独自メモリ擬似的に可(Readで読む)同左ネイティブに可(MEMORY.md)
サブ独自人格フロントマター本文developer_instructionsSOUL.mdで本格定義可
並列起動◎(複数Taskを1メッセージで)
Heartbeat統合自前実装が必要自前実装が必要ネイティブ対応
Slack統合自前実装が必要自前実装が必要ネイティブ対応(@slack/bolt内蔵)

判断軸はシンプルです。

  • HeartbeatやSlackを入口に使うならOpenClaw sessions_spawnが有力。Claude CodeやCodexに乗せ替えると入口を自前で作り直す羽目になります
  • 使い捨てサブで十分ならClaude Code Taskが最軽量。1ファイルで完結する手軽さは大きい
  • 独自記憶や人格を持つ恒常サブが欲しいならOpenClaw sessions_spawn。ワークスペースを使い分けて人格・記憶ごと分離できる

結論: OpenClaw sessions_spawnで行く

私のケースでは、HeartbeatとSlackを入口にする要件があり、観点別コンサルのように「サブが独自の判断履歴を持って学習し続ける」運用も視野に入っているため、OpenClaw sessions_spawn で行くことに決めました。

最初は「Claude Codeに載せ替えればTaskツールで楽にサブを書けるかも」と思っていましたが、

  1. Heartbeat / Slackの入口を自前で作り直すコストが大きい
  2. サブの最小構成(AGENTS.md 1ファイル)ならClaude Codeと書く量はあまり変わらない
  3. サブが独自メモリを持てる選択肢が将来効いてくる可能性がある

の3点で、OpenClaw内で完結させる方針が筋が通りました。

サブを増やすたびにworkspace-<name>/フォルダとopenclaw.jsonのエントリが増えていく、というスタイルに慣れる必要はありますが、「サブも親と同格の正規エージェント」という思想に乗ればむしろシンプル だと感じています。

この記事を書いた人
せお丸(田中淳介)
理事長

せお丸(田中淳介)

AI駆動開発協会 代表理事 サイバーフリークス株式会社 代表取締役