Claude Code /research の待ち時間をゼロに:Skill × サブエージェント構成

/research コマンドの課題:バックグラウンド不可、コンテキスト消費

ども!最近Claude Codeでのトークン削減にうるさい龍ちゃんです。

前回、Claude Code サブエージェントの最適構成:Opus で考え、Sonnet で動かすという記事でトークン消費を抑える話をしました。今回もその系統のお話です。

Claude Codeの調査品質がバラバラ?:/researchで解決する方法で紹介した /research、機能としては便利でした。調査深度の選択、CRAAP評価、統一フォーマットでの出力…。でもOpusともっと話したい僕としては課題がありました。

  • バックグラウンドで動かない: 調査が終わるまでずっと待つしかない
  • 親コンテキストを食う: 検索結果がどんどん積まれて、長い調査の後はメイン会話がもっさりする
  • 全部同じモデルで動く: 判断も検索も同じモデル。Opus でやる必要のない作業もある

「前回の Opus + Sonnet 構成、/research にもサブエージェントを使えばいけるんじゃない?」

と思い立ったので実践です。


TL;DR:何が変わったか

先に結論だけ知りたい方向けのまとめです。

課題解決策
バックグラウンドで動かないTask tool の run_in_background: true で解決
親コンテキストを食う検索結果は Worker のコンテキストに閉じ込め
全部同じモデルで動く計画・評価は Opus、検索実行は Sonnet に分業

詳しい実装方法と使用感は続きをどうぞ。

完全版は GitHub Gist で公開しています。.claude/ ディレクトリに配置すればすぐに使えます。


サブエージェントのネスト制限

実装を進める前に知っておくべき重要な制限があります。

Claude Code のサブエージェントは、別のサブエージェントを起動できません。

GitHub issue でも報告されています:

No Nested Delegation: Sub-agents are not allowed to create other sub-agents, ensuring a single-level structure that prevents infinite nesting and keeps the execution hierarchy simple and manageable.

無限再帰を防ぐための意図的な設計です。サブエージェントとして起動されたエージェントは、定義ファイルに tools: [Task] と書いてあっても Task tool が使えなくなります。

つまり「Skill → Orchestrator → Worker」のような階層構造は作れない。Skill やメインセッションから直接 Worker を起動する設計にする必要があります。

本当は専任ユーザーみたいな代わりで報告だけ聞くという完全独立構成をしたかったのですが…。ここをカスタマイズで乗り切るって方法もあるんですが、大規模になるので一旦は我慢です。


Commands → Skill + サブエージェントで何が変わったか

Before:
.claude/commands/research.md(1ファイル)  After:
.claude/skills/research/SKILL.md        # エントリーポイント
.claude/agents/research-worker.md       # 検索実行(Sonnet)

変えたこと

1. Commands から Skill に移行

.claude/commands/research.md の単一ファイル構成から、Skill + Agent の分離構成に変更しました。

Before:
.claude/commands/research.md(1ファイル)

After:
.claude/skills/research/SKILL.md        # エントリーポイント
.claude/agents/research-worker.md       # 検索実行(Sonnet)

Claude Code v2.1.3(2025年1月9日)で Commands と Skills が概念的に統合されました。どちらも引き続き使えますが、Skills はディレクトリ構造や allowed-tools 指定などの追加機能があるため、今回は Skills 形式 を採用しました。というか新規で作るならSkillが推奨されています。(僕は合わせてすべてのCommandsをSkillsに変換しました。)

2. メインセッション + Worker パターン

ネスト制限を踏まえて、以下の役割分担にしました。

役割担当モデル
計画・評価・レポート作成メインセッションOpus
検索実行WorkerSonnet

前回の記事で紹介した「Opus で考え、Sonnet で動かす」構成がそのまま実現できています。

3. Worker を並列で動かせるようにした

調査深度に応じて Worker を複数起動できるようにしました。

深度Worker 数分担
クイック1主要情報のみ
標準2-3公式/ブログ/日本語で分担
ディープ4-6さらに細分化

アーキテクチャ

ネスト制限を踏まえた設計です。

メインセッション (Opus)
 │
 ├─ /research skill がユーザーに質問
 │   - 調査深度(クイック/標準/ディープ)
 │   - 信頼性要件(公式のみ/ブログも含む/幅広く)
 │   - 実行モード(バックグラウンド/フォアグラウンド)
 │
 ├─ research-worker を直接起動(複数並列・バックグラウンド可)
 │      ├─ Worker 1: 公式ドキュメント検索
 │      ├─ Worker 2: 技術ブログ検索
 │      └─ Worker 3: 日本語情報検索
 │
 └─ 完了後、メインセッションが結果を評価・レポート作成
 └─ docs/research/YYYY-MM-DD-topic.md に保存

ポイント
判断が必要な作業(計画・評価・レポート作成)はメインセッションの Opus が担当し、定型的な作業(検索実行)は Worker の Sonnet に任せること。


Claude Code サブエージェントの設定方法

実際の設定ファイルを共有します。完全版は GitHub Gist で公開しています。.claude/ ディレクトリに配置すればすぐに使えます。

サブエージェントの公式ドキュメントも参考にしてください。

Skill(エントリーポイント)

# .claude/skills/research/SKILL.md

---
name: research
description: 調査して、リサーチして、/research [トピック]
allowed-tools: Task, AskUserQuestion, Read
---

Skill の役割は3つ。ユーザーへの質問、検索クエリの設計、Worker の起動です。

Worker(検索実行担当)

# .claude/agents/research-worker.md

---
name: research-worker
tools: [WebSearch, WebFetch, Read]
model: sonnet
permissionMode: acceptEdits
---

model: sonnet でコスト効率を重視。検索と情報収集に特化しています。

ポイントは、Worker はファイル出力をしないこと。結果はメインセッションに返して、最終的なレポート作成はメインセッションが担当します。

バックグラウンド実行

サブエージェントをバックグラウンドで動かすには、Task tool を呼び出す際にバックグラウンド実行を明示的に依頼します。

// Skill から Worker をバックグラウンドで起動
Task({
  subagent_type: "research-worker",
  description: "Research Worker: バックグラウンドで実行",
  prompt: "..."
})
// → Claude に「バックグラウンドで実行して」と依頼、または Ctrl+B でバックグラウンド化

バックグラウンド実行中も他の作業ができ、完了すると自動で通知されます。詳しくは サブエージェントの公式ドキュメント を参照してください。


実際に使ってみた感想

しばらく使ってみての体験談です。

調査中も他の作業ができる

バックグラウンド実行で待ち時間ゼロ。「これ調べておいて」と言ったら、すぐ次の作業に移れます。コードを書きながら裏で調査が走っている感覚、なかなか快適です。

メインの会話が軽いまま

検索結果が親コンテキストに積まれないので、長時間の作業でもメイン会話がサクサク。以前は調査後に「なんか重いな…」と感じることがありましたが、それがなくなりました。

複数調査を同時に回せる

「これとこれ、並行で調べておいて」ができるようになりました。別々のトピックを同時に調査できるのは地味に便利。

Opus との会話時間が増えた

検索実行は Sonnet に任せて、判断・対話は Opus と。Opus のトークンを本当に必要なところに集中できるようになりました。


注意点・制限事項

実装上、いくつかの制約があります。

サブエージェントはネストできない(再掲)

今回の最大のポイント。サブエージェントとして起動されたエージェントは Task tool を使えません。Skill やメインセッションから直接 Worker を起動する設計にしましょう。

エラー時は1回リトライ後、部分結果で続行

Worker の WebSearch/WebFetch がエラーを返した場合、代替クエリで1回だけ再試行します。それでも失敗した場合は、取得できた部分結果でレポートを作成します。完璧な結果を待つより、得られた情報で先に進むほうが実用的です。

Worker はファイル出力しない

Worker は検索結果をメインセッションに返すだけ。ファイル書き込みはメインセッションが一括で行います。これにより、レポートの一貫性が保たれます。

ユーザー対話は Skill に集約

調査パラメータの確認は Skill が担当し、Worker はユーザーに質問しません。Skill をインターフェースにすることで、Worker のプロンプトから対話処理の指示を省けます。

数値的な検証はこれから

正直なところ、トークン消費量や処理時間の定量的な比較はまだできていません。ただ、使用感としては非常に良いです。バックグラウンドで調査が回っている間に他の作業ができるのは、体感でかなり快適になりました。継続的に使いながら数値を取っていく予定です。(便利になるってのは確かなのでモチベがわけば測定します…)


まとめ

/research を Skill + サブエージェント構成に移行しました。

ネスト制限への対応:

  • サブエージェントからサブエージェントは起動できない
  • Skill から直接 Worker を起動する設計に

構成:

  • 計画・評価・レポート作成 → メインセッション(Opus)
  • 検索実行 → Worker(Sonnet)

効果:

  • バックグラウンドで調査可能
  • 親コンテキストを消費しない
  • 並列実行でスピードアップ

トークン削減シリーズの流れ

内容
1AIフレンドリーなドキュメント管理(基盤設計)
2静的情報活用で実行速度改善(トークン削減)
3Opus で考え、Sonnet で動かす(サブエージェント分業)
4今回: 調査も分業体制に

調査も「Opus で考え、Sonnet で動かす」。

サブエージェントのネスト制限という制約がありますが、むしろシンプルな構成に落ち着きました。制約があるからこそ、クリーンな設計になることもあるんですね。

分業できるところは分業して、Opus との会話を長く楽しみましょう。

ではまた!


関連記事

参考リンク

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。
エンジニア募集中!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です