Home 論文解説: MCP-Zero — MCPエージェントのための能動的ツール発見フレームワーク
投稿
キャンセル

📄 論文解説: MCP-Zero — MCPエージェントのための能動的ツール発見フレームワーク

本記事は MCP-Zero: Active Tool Discovery for Autonomous LLM Agents (arXiv:2503.23278) の解説記事です。

論文概要(Abstract)

MCP-Zero は、Model Context Protocol (MCP) 環境において LLM エージェントが利用可能なツール数が大規模(100件以上)になった場合に発生するプロンプト肥大化問題を解決するフレームワークである。全ツール定義をコンテキストに含める代わりに、タスクの現在の状態に基づいて embedding ベースのセマンティック検索で上位 $k$ 件のツールのみを動的に取得する。著者らの報告によると、StressTestBench(100以上のツール)において prefill レイテンシを 73% 削減しつつ、タスク成功率を 52.3% から 71.8% に改善している。

この記事は Zenn記事: LangGraph×MCPツール呼び出しレイテンシ最適化:社内検索エージェントの応答を5倍速くする の深掘りです。

情報源

背景と動機(Background & Motivation)

MCP の普及に伴い、単一のエージェントが接続する MCP サーバ数が増加している。各サーバが複数のツールを公開するため、エージェントが利用可能なツールの総数は容易に 100 件を超える。

全ツール定義をナイーブにコンテキストウィンドウに含めると、以下の 3 つの問題が発生する。

  1. コンテキストウィンドウの溢れ: 100 ツールのスキーマは約 8,000-15,000 トークンを消費し、コンテキストの大部分がメタデータで占有される
  2. prefill レイテンシの増大: LLM の prefill 計算量はプロンプト長に比例するため、ツール定義が長いほど推論開始までの待ち時間が増加する
  3. ツール選択精度の低下: 無関係なツール定義が注意を分散させ、適切なツールを選択する確率が低下する

Zenn 記事で紹介した「動的ツールローディング」パターンは、キーワードベースのルーティングで必要なツールカテゴリを判定していた。MCP-Zero はこれをセマンティック検索に拡張し、より汎用的かつ高精度なツール取得を実現している。

主要な貢献(Key Contributions)

  • 貢献1: MCP 環境に特化した Active Tool Discovery パイプラインを提案し、エージェントの各推論ステップでタスク文脈に基づくツール動的取得を実現している
  • 貢献2: 100以上のツールを持つ環境(StressTestBench)で、prefill レイテンシ 73% 削減、タスク成功率 37% 改善を達成している
  • 貢献3: ツール取得オーバーヘッドがステップあたり約 20ms と実用上無視可能であることを実証している

技術的詳細(Technical Details)

2段階パイプライン

MCP-Zero は以下の 2 段階で動作する。

Stage 1: Tool Discovery(ツール発見)

軽量な embedding モデル(例: text-embedding-3-small)を用いて、現在のタスク状態とツール説明文のセマンティック類似度を計算し、上位 $k$ 件を取得する。

ツール取得のスコアリングは以下の式で定義される。

\[s(q, t_j) = \cos(\mathbf{e}_q, \mathbf{e}_{t_j}) = \frac{\mathbf{e}_q \cdot \mathbf{e}_{t_j}}{||\mathbf{e}_q|| \cdot ||\mathbf{e}_{t_j}||}\]

ここで、$\mathbf{e}q$ は現在のタスク状態のクエリ embedding、$\mathbf{e}{t_j}$ は $j$ 番目のツール説明文の embedding である。上位 $k$ 件のツールが選択される。

\[\mathcal{T}_{\text{active}} = \text{top-}k \left( \{ s(q, t_j) \}_{j=1}^{|\mathcal{T}|} \right)\]

Stage 2: Active Invocation(能動的呼び出し)

LLM は取得された $k$ 件のツール定義のみをコンテキストとして受け取り、最適なツールを選択・呼び出す。ツール実行後、タスク状態が更新され、次のステップで Stage 1 が再トリガーされる。

トークン節約の定量分析

100 ツール環境におけるステップあたりのトークン消費を比較する(論文 Section 4 より)。

\[C_{\text{naive}} = \sum_{j=1}^{|\mathcal{T}|} \text{tokens}(t_j) \approx 8{,}000 \text{ tokens}\] \[C_{\text{MCP-Zero}}(k) = \sum_{j=1}^{k} \text{tokens}(t_j) \approx k \times 80 \text{ tokens}\]

$k = 5$ の場合、$C_{\text{MCP-Zero}} \approx 400$ トークンとなり、ナイーブ手法の $8{,}000$ トークンに対して 95% 削減される。ただし、著者らは実測のトークン節約を「平均 3,200 トークン/ステップ」と報告しており、これはツール説明文の長さのばらつきを反映している。

レイテンシ内訳

MCPベースのエージェントにおいて、prefill レイテンシはプロンプト長に比例する。

\[L_{\text{prefill}} \propto |\text{prompt}| = |\text{system}| + |\text{tools}| + |\text{history}| + |\text{input}|\]
MCP-Zero はこの中の $\text{tools}$ 項を大幅に削減する。100 ツール環境での prefill レイテンシは以下の通り(論文 Table 1 より)。
手法ツールトークン数Prefill レイテンシ
Naive MCP(全ツール)~8,0004,820ms
MCP-Zero ($k=5$)~4001,300ms
MCP-Zero ($k=10$)~8001,980ms

ツール取得自体のオーバーヘッド(embedding 計算 + cosine similarity + top-k 選択)は約 20ms であり、prefill 削減量(3,520ms)に対して無視可能である。

ハイパーパラメータ $k$ の選択

著者らは、利用可能なツール数 $\mathcal{T}$ に応じた $k$ の推奨値を以下のように報告している。
ツール数推奨 $k$理由  
$\mathcal{T}< 10$全件含める取得オーバーヘッドが prefill 削減を上回る
$10 \leq\mathcal{T}< 50$$k = 5$十分なカバレッジと低レイテンシのバランス
$50 \leq\mathcal{T}< 200$$k = 10$広いツール空間でのカバレッジ確保
$\mathcal{T}\geq 200$$k = 15$大規模環境での安全マージン

アルゴリズム

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from typing import TypedDict
import numpy as np

class MCPZeroState(TypedDict):
    query: str
    tool_registry: list[dict]  # 全ツールメタデータ
    tool_embeddings: np.ndarray  # 事前計算済み
    k: int  # 取得ツール数

def active_tool_discovery(
    state: MCPZeroState,
    embed_model,
) -> list[dict]:
    """タスク状態に基づきtop-kツールを動的取得"""
    # Step 1: クエリ embedding 計算
    query_emb = embed_model.encode(state["query"])

    # Step 2: cosine similarity 計算
    similarities = np.dot(
        state["tool_embeddings"], query_emb
    ) / (
        np.linalg.norm(state["tool_embeddings"], axis=1)
        * np.linalg.norm(query_emb)
    )

    # Step 3: top-k 選択
    top_k_indices = np.argsort(similarities)[-state["k"]:][::-1]

    return [state["tool_registry"][i] for i in top_k_indices]

実験結果(Results)

StressTestBench(100+ ツール環境)

著者らの実験結果(論文 Table 1 より):

手法タスク成功率ツール選択精度Prefill レイテンシE2E レイテンシ
Naive MCP52.3%61.4%4,820ms8,940ms
MCP-Zero ($k=5$)71.8%84.2%1,300ms5,820ms
MCP-Zero ($k=10$)74.1%85.9%1,980ms6,340ms

注目すべき点: MCP-Zero は精度とレイテンシの両方を同時に改善している。これは無関係なツール定義を排除することで、LLM の注意が適切なツールに集中するためである。

τ-Bench(標準ツール使用ベンチマーク)

手法タスク成功率E2E レイテンシ
Naive MCP68.4%7,210ms
MCP-Zero ($k=5$)76.2%4,890ms

標準的なベンチマークでも 32% のレイテンシ削減と 11.4% の成功率改善が確認されている。

実装のポイント(Implementation)

Embedding インデックスの事前構築

ツール説明文の embedding はサーバ起動時に一度計算し、メモリに保持する。MCPサーバがツールを動的に追加・削除する場合は、インデックスの差分更新が必要である。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class ToolEmbeddingIndex:
    """MCPツール説明文のembeddingインデックス"""

    def __init__(self, embed_model: str = "text-embedding-3-small"):
        self.model = embed_model
        self._embeddings: dict[str, np.ndarray] = {}

    def register_tool(self, tool_name: str, description: str) -> None:
        """ツール登録時にembeddingを計算"""
        self._embeddings[tool_name] = self._encode(description)

    def unregister_tool(self, tool_name: str) -> None:
        """ツール削除時にインデックスから除去"""
        self._embeddings.pop(tool_name, None)

    def search(self, query: str, k: int = 5) -> list[str]:
        """クエリに最も関連するk件のツール名を返却"""
        query_emb = self._encode(query)
        scores = {
            name: float(np.dot(emb, query_emb) / (
                np.linalg.norm(emb) * np.linalg.norm(query_emb)
            ))
            for name, emb in self._embeddings.items()
        }
        return sorted(scores, key=scores.get, reverse=True)[:k]

LangGraph との統合パターン

Zenn 記事の DynamicSearchState パターンと MCP-Zero を組み合わせる場合、キーワードルーティングを embedding 検索に置き換えることで、より汎用的なツール選択が実現できる。

MCP トランスポートとの互換性

MCP-Zero は stdio および StreamableHTTP の両方のトランスポートと互換であると報告されている。ツール取得はクライアント側で行われるため、サーバ側のトランスポート方式に依存しない。

実運用への応用(Practical Applications)

大規模 MCP 環境でのスケーリング: 企業環境では Slack、Confluence、JIRA、社内 Wiki、ベクトル DB 等、10 以上の MCP サーバが接続されることが想定される。MCP-Zero のアプローチにより、ツール数の増加に対してプロンプトサイズを一定に保てる。

コスト最適化: トークン消費の 95% 削減は、API 課金ベースの LLM を使用する場合に直接的なコスト削減につながる。月間 10 万リクエスト、ステップあたり 3,200 トークン削減の場合、Claude Sonnet($3/MTok)で月額約 $960 の節約に相当する。

制約と注意点: ツール説明文の品質が低い場合、embedding ベースの検索精度が低下する。MCP サーバ開発者はツールの description フィールドに十分な情報を記載すべきである。

関連研究(Related Work)

  • Gorilla (arXiv:2305.11554): 大規模 API セット(1,600以上)での function calling 精度を改善するファインチューニング手法である。MCP-Zero が推論時のツール取得に焦点を当てるのに対し、Gorilla はモデル自体のツール使用能力を向上させるアプローチである
  • FlexTool (arXiv:2502.10055): RAG ベースのツール選択モジュールと CoT 推論を組み合わせたフレームワークである。MCP-Zero と類似の課題を解決するが、MCP プロトコルに特化していない
  • MCPBench (arXiv:2506.03233): MCP サーバのレイテンシ実測値を提供するベンチマークであり、MCP-Zero の最適化効果を検証する際の基準データとして活用できる

まとめと今後の展望

MCP-Zero は、MCP 環境での大規模ツール空間における 3 つの問題(コンテキスト溢れ、prefill レイテンシ増大、ツール選択精度低下)を Active Tool Discovery により同時に解決するフレームワークである。embedding ベースの取得は 20ms のオーバーヘッドで 73% の prefill レイテンシ削減を実現し、実用的な最適化手法として位置づけられる。

今後の課題として、ツール説明の品質改善による取得精度向上、マルチステップでの文脈を活用した適応的な $k$ 値の動的調整が挙げられている。

参考文献

この投稿は CC BY 4.0 でライセンスされています。

論文解説: CoRAG — 反復的検索クエリ連鎖で知識集約型QAの精度を大幅向上

Google解説: Gemini 3 API主要アップデート — thinking_level・media_resolution・Thought Signaturesの技術詳細