GitHub Copilot の runSubagent を検証してみた:コンテキスト分離の効果と限界

に公開

GitHub Copilot のエージェントモードを使っていると、調査や分析といった複雑なタスクでチャットのコンテキストがどんどん膨らんでいく経験はないでしょうか。ファイルを読み込み、Web ページを取得し、その内容を処理していくうちに、メインセッションが情報過多になってしまう。そんな課題を解決するために登場したのが runSubagent ツールです。

この記事では、runSubagent の仕組みと使い方を解説し、実際に調査タスクで検証した結果を共有します。

runSubagent とは

runSubagent は、メインのチャットセッション内から独立したセッション(サブエージェント)でタスクを遂行する機能です。

サブエージェントは自分専用のコンテキストウィンドウを持ち、タスクを自律的に実行します。処理が完了すると、最終結果だけをメインセッションに返します。公式ドキュメントでは Asking GitHub Copilot questions in your IDE のサブエージェントのセクションで解説されています。

https://docs.github.com/en/copilot/how-tos/chat-with-copilot/chat-in-ide#using-subagents

たとえば「この 8 つの URL を調査して要約して」と依頼した場合、通常であればすべての URL の内容がメインセッションのコンテキストに蓄積されていきます。runSubagent を使うと、各 URL の調査を独立したサブエージェントに委譲できます。サブエージェントがページ内容を読み込んで要約を作成し、その要約だけがメインセッションに戻ってくる形です。

ポイントは「コンテキストの分離」にあります。実はこれ、最近 AI エージェント界隈で注目されている「コンテキストエンジニアリング」のベストプラクティスそのものです。LangChain のブログでは、エージェントのコンテキスト管理を 3 つのカテゴリに分類しています。コンテキストを保存する「Writing」、必要なときに取り出す「Selecting」、そしてタスクごとに分割する「Isolating」。runSubagent はまさにこの「Isolating」を実現するツールだといえます。

ツール定義から見る特徴

内部的なツール定義を覗いてみると、runSubagent の設計思想がよく見えてきます。定義には次のような記述があります。

Launch a new agent to handle complex, multi-step tasks autonomously. This tool is good at researching complex questions, searching for code, and executing multi-step tasks.

ツールの完全な定義
{
  "function": {
    "name": "runSubagent",
    "description": "Launch a new agent to handle complex, multi-step tasks autonomously. This tool is good at researching complex questions, searching for code, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries, use this agent to perform the search for you.\n\n- Agents do not run async or in the background, you will wait for the agent's result.\n- When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.\n- Each agent invocation is stateless. You will not be able to send additional messages to the agent, nor will the agent be able to communicate with you outside of its final report. Therefore, your prompt should contain a highly detailed task description for the agent to perform autonomously and you should specify exactly what information the agent should return back to you in its final and only message to you.\n- The agent's outputs should generally be trusted\n- Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent",
    "parameters": {
      "type": "object",
      "properties": {
        "prompt": {
          "type": "string",
          "description": "A detailed description of the task for the agent to perform"
        },
        "description": {
          "type": "string",
          "description": "A short (3-5 word) description of the task"
        }
      },
      "required": ["prompt", "description"]
    }
  },
  "type": "function"
}

複雑な調査やコード検索、複数ステップのタスクを自律的に処理させることを想定したツールだとわかります。

動作の特性についても明記されています。

  • Agents do not run async or in the background, you will wait for the agent's result.
  • Each agent invocation is stateless.

サブエージェントは非同期やバックグラウンドでは動作せず、呼び出し元は結果を待つ必要があります。また、各呼び出しはステートレスで、サブエージェントとの追加のやり取りはできません。一度きりのタスク実行と結果の返却という、シンプルな構造になっています。

呼び出し時のパラメータは 2 つだけです。prompt にはサブエージェントに実行させたいタスクの詳細な説明を、description には 3〜5 語程度の短い説明を指定します。シンプルなインターフェースですが、prompt の書き方次第でサブエージェントの動作は大きく変わってきます。

使い方

runSubagent を使うには、まずツールピッカーで有効化する必要があります。VS Code のチャットビューでツールピッカーを開き、runSubagent にチェックを入れてください。

カスタムエージェントで使う場合は、YAML フロントマターの tools プロパティに追加します。

---
name: ResearchAgent
tools: ["fetch", "runSubagent"]
---

プロンプトでサブエージェントを呼び出すには、自然言語で指示するだけで十分です。Copilot はこの指示を解釈し、適切にサブエージェントを起動(作成)してくれます。

例)各 URL に対して #tool:runSubagent を使ってページ内容を取得し、要約してください。

検証: 調査エージェントでの比較

実際に runSubagent のあり/なしでどのような違いが出るのか、検証してみました。

検証内容

資源エネルギー庁のエネルギー白書から原子力政策に関する 8 つの URL を読み込み、日本のエネルギー政策についてのレポートを作成するタスクです。それなりに長いコンテンツを扱うため、メインセッションのコンテキストが膨らみやすい状況です。

また、出力で差が出ないようにするため、「現状」「課題」「展望」をそれぞれ 100 文字以内でまとめるという軽量な出力を求めるようにコントロールしました。

結果: サブエージェントなしの場合

まずは通常の方法で、同じセッション内ですべての URL を取得して処理しました。

エージェント定義
research.agent.md
---
name: Research
tools: ["fetch"]
---

あなたは、日本のエネルギー政策を調査するエージェントです。下記のステップに従って、レポートを報告してください。

1. 各調査対象 URL に対し、下記を実行する。

- #tool:fetch でページの内容を取得する。
- 情報を要約する。

2. すべての URL の調査が完了したら、以下の内容を含むレポートを作成する。

- 日本のエネルギー政策の現状: 100 文字以内で
- 主な課題: 100 文字以内で
- 今後の展望: 100 文字以内で

## 調査対象 URL 一覧

https://www.enecho.meti.go.jp/about/whitepaper/2025/html/2-4-1.html
https://www.enecho.meti.go.jp/about/whitepaper/2025/html/2-4-2.html
https://www.enecho.meti.go.jp/about/whitepaper/2025/html/2-4-3.html
https://www.enecho.meti.go.jp/about/whitepaper/2025/html/2-4-4.html
https://www.enecho.meti.go.jp/about/whitepaper/2025/html/2-4-5.html
https://www.enecho.meti.go.jp/about/whitepaper/2025/html/2-4-6.html
https://www.enecho.meti.go.jp/about/whitepaper/2025/html/2-4-7.html
https://www.enecho.meti.go.jp/about/whitepaper/2025/html/2-4-8.html

## 出力フォーマット

- 日本のエネルギー政策の現状: {現状}
- 主な課題: {課題}
- 今後の展望: {展望}

それ以外の情報は出力しないでください。

結果は、以下の通りです。

  • トークン使用量: 33,241 トークン
  • 実行時間: 約 4.8 秒

8 ページ分のコンテンツがすべてメインセッションのコンテキストに蓄積されたため、トークン使用量が大きいことがわかります。

結果: サブエージェントありの場合

次に、各 URL の取得をサブエージェントに委譲する方法で実行しました。

エージェント定義
research-subagent.agent.md
---
name: ResearchSubagent
tools: ["fetch", "runSubagent"]
---

あなたは、日本のエネルギー政策を調査するエージェントです。下記のステップに従って、レポートを報告してください。

1. 各調査対象 URL に対し、#tool:runSubagent を使用して下記を実行するサブエージェントを呼び出す。

- #tool:fetch でページの内容を取得する。
- コンテンツを要約する。

2. すべての URL の調査が完了したら、以下の内容を含むレポートを作成する。

- 日本のエネルギー政策の現状: 100 文字以内で
- 主な課題: 100 文字以内で
- 今後の展望: 100 文字以内で

## 調査対象 URL 一覧

https://www.enecho.meti.go.jp/about/whitepaper/2025/html/2-4-1.html
https://www.enecho.meti.go.jp/about/whitepaper/2025/html/2-4-2.html
https://www.enecho.meti.go.jp/about/whitepaper/2025/html/2-4-3.html
https://www.enecho.meti.go.jp/about/whitepaper/2025/html/2-4-4.html
https://www.enecho.meti.go.jp/about/whitepaper/2025/html/2-4-5.html
https://www.enecho.meti.go.jp/about/whitepaper/2025/html/2-4-6.html
https://www.enecho.meti.go.jp/about/whitepaper/2025/html/2-4-7.html
https://www.enecho.meti.go.jp/about/whitepaper/2025/html/2-4-8.html

## 出力フォーマット

- 日本のエネルギー政策の現状: {現状}
- 主な課題: {課題}
- 今後の展望: {展望}

それ以外の情報は出力しないでください。

結果は、以下の通りです。

  • メインセッションのトークン使用量: 8,854 トークン
  • 各サブエージェントのトークン使用量: 4,000 ~ 10,000 トークン (記事の長さによる)
  • 実行時間: 約 71 秒

メインセッションは非常にコンパクトに保たれました。各 URL のページ内容はサブエージェント内で処理され、要約だけが戻ってきたためです。

比較まとめ

項目 サブエージェントなし サブエージェントあり
メインセッションのトークン 33,241 8,854
サブエージェントを含めた総トークン数 33,241 約 40,000
実行時間 約 5 秒 約 71 秒

興味深い結果がいくつかあります。

まず、総トークン数ではサブエージェントありの方が約 1.3 倍多くなりました。当然といえば当然ですが、サブエージェントの生成や、サブエージェント内での活動で追加のトークンが消費されるためです。

ただし、これは今回のタスク セッティングの影響も大きいです。全タスク ボリュームが小さいのにも関わらず頻繁にサブエージェントを呼び出しているため、オーバーヘッドが相対的に大きくなっています。通常、サブエージェントを利用するタスクは複雑なものが想定されるため、本来オーバーヘッドはそこまで気にならないはずです。

また、約 1 分以上かかった実行時間も注目すべき点です。サブエージェントは直列に実行されるため、8 つの URL を順番に処理していくとどうしても時間がかかってしまいます。これは、サブエージェントの生成と終了に要する固定オーバーヘッドが大きく関係していて、各サブエージェントが独立して動作する以上、避けられない制約です。

並列実行は可能か

前述の「サブエージェントを使うと直列実行になって遅くなる」問題が痛いので、なんとか並列化できないか試してみました。

プロンプトで並列実行を指示する

まず試したのは単純に「並列で処理して」と指示する方法です。

  1. 各調査対象 URL に対し、#tool:runSubagent を使用して下記を実行するサブエージェントを並列に呼び出す (全 URL を同時に処理)。

結果は期待通りにはいきませんでした。Copilot は指示を無視して、8 つのサブエージェントを順番に起動していきます。プロンプトで強調しても、ツールの仕様上の制約は超えられないようです。

補足: 表面上は「並列に実行します」という返事を返してきましたが、実際には直列に処理されていました。

複数のエージェントに分散させる

次に試したのは、事前に定義したエージェントを複数用意して、明示的に分散させる方法です。別のエージェントにハンドオフするモデルをサブエージェント機能でもできないか試してみました。

まず、以下の二つのエージェントを用意します。

fetcher-gpt-4.1.agent.md
---
tools: ["fetch"]
model: GPT-4.1 (copilot)
---

与えられた URL を #tool:fetch で取得して、その内容を要約してください。
fetcher-gpt-5-mini.agent.md
---
tools: ["fetch"]
model: GPT-5 mini (copilot)
---

与えられた URL を #tool:fetch で取得して、その内容を要約してください。

そして、この fetcher エージェントに、URL を半分ずつ振り分けるようプロンプトで指示しました。

  1. サブエージェントに依頼して、調査対象 URL の情報を取得する。8 つの URL を下記 2 つのサブエージェントに分散依頼し、並列で処理してください。
  • subagentType=fetcher-gpt-4.1 -> 2-4-1.html, 2-4-2.html, 2-4-3.html, 2-4-4.html
  • subagentType=fetcher-gpt-5-mini -> 2-4-5.html, 2-4-6.html, 2-4-7.html, 2-4-8.html

こちらも結果は同じで、直列実行になってしまいました。また、エージェントを指定するようなやり方はうまくいかず、結局オーケストレーター(メインセッション)がエージェントを作ってしまうようです。

補足: こちらも表面上は「2 つのエージェントで並列に実行します」という返事を返してきましたが、実際には直列に処理されていました。

現状の仕様

2025 年 12 月時点では、runSubagent の並列実行はサポートされていません。ツール定義で明記されている通りです。

Agents do not run async or in the background, you will wait for the agent's result

また、サブエージェントへのハンドオフ先を既存エージェントにするようなモデルもサポートされていないことがわかりました。サブエージェントの定義もメインのオーケストレーター側に書いておくのがよさそうです。

このあたりは将来のアップデートに期待ですね。

いつ使うべきか

検証結果からもわかる通り、runSubagent は「時間の効率化」のためのツールではなく「コンテキスト管理」のためのツールです。どんな場面で活用されているのか、いくつか事例を見てみましょう。

コミュニティでの活用事例

Reddit での事例では、ESLint のエラーを各ファイルごとにサブエージェントで修正するという使い方が紹介されていました。3 つの TypeScript ファイルにエラーがあった場合、それぞれ独立したサブエージェントが修正を担当します。

より高度な例として、GitHub Copilot Orchestra というワークフローがあります。Conductor エージェントがユーザーの指示を受け取り、Planning サブエージェントで計画を立て、Implementation サブエージェントで実装し、Code Review サブエージェントでレビューするという構成です。各フェーズをサブエージェントに分離することで、メインセッションには計画と最終結果だけが残ります。

GitHub Community での実験では、複数のモデルをサブエージェントとして起動し、それぞれが独立した git worktree で作業するというアプローチも試されています。同じタスクを異なるモデルに解かせて、結果を比較するという使い方です。

効果的な場面

検証結果とコミュニティ事例から、次のような場面で効果を発揮しそうです。

  • 長いセッションの途中で発生する調査タスク: 機能実装の途中で「このライブラリの使い方を調べて」といった依頼が発生した場合、調査内容をメインセッションに残さずに済む
  • ログファイルの調査: 大量のテキストを読み込むためコンテキストが汚染されやすいログ・メトリック調査をサブエージェントに委譲すれば、数千行のログ内容はサブエージェント内で処理され、結論だけが返ってくる
  • 独立して処理できるファイル単位の作業: ESLint エラーの修正事例のように、ファイルごとに独立した作業をさせる場面。各ファイルの詳細なコード内容はサブエージェント内で閉じ、メインセッションには結果だけが残る
  • フェーズが明確に分かれるワークフロー: 計画 → 実装 → レビューのように段階が分かれている場合、各フェーズをサブエージェントに委譲することで、メインセッションをオーケストレーション層として使える

避けた方がよい場面

一方で、次のような場面では逆効果になりかねません。

  • 結果を深掘りしたい場合: サブエージェントはステートレスなので、「もう少し詳しく教えて」といった追加のやり取りができない
  • タスクが軽量すぎる場合: 各サブエージェントの起動には固定のオーバーヘッドがある。処理自体が軽いのに頻繁に呼び出すと、オーバーヘッドばかりが目立つ
  • コンテキストの蓄積が必要なタスク: 前のステップの詳細な情報を次のステップで参照したい場合、サブエージェントに分けるとその情報が失われる

まとめ

runSubagent は、メインセッションのコンテキストを「汚さない」ための機能です。検証では、8 つの URL を処理するタスクでメインセッションのトークン数を 33,000 から 9,000 に削減できました。一方で、総トークン数は約 1.3 倍に増え、実行時間も 5 秒から 71 秒へと大幅に伸びています。

この結果が示すのは、runSubagent が「時間短縮」ではなく「コンテキスト管理」のためのツールだということです。長いセッションの途中で発生する調査、大量のログ解析、フェーズごとに分かれたワークフローなど、メインセッションをクリーンに保ちたい場面で真価を発揮します。逆に、単純に速く終わらせたいタスクや、結果を対話的に深掘りしたいケースには向いていません。

まだ発展途上の機能で、並列実行がサポートされていないなど制約もあります。しかし、コンテキストウィンドウの肥大化に悩んでいるなら、試してみる価値はあるでしょう。

参考リンク

Discussion