MCP ツール設計:実践的アプローチとトレードオフ
本文の状態
日本語全文を表示中
詳細モードで約20分の本文を読めます。
同じ出来事の情報源
この情報源を基点に整理
AWS Machine Learning Blog
AWS は、MCP ツールの設計における「肥大化」と「混乱」が LLM の推論能力を低下させる要因であると指摘し、文脈工学を用いた実用的な解決策とトレードオフについて解説する。
AI深層分析を開く2026年8月2日 20:33
AI深層分析
キーポイント
MCP ツール失敗の根本原因
既存 API をそのまま公開する設計は不十分であり、「肥大化(bloat)」によるコンテキストの過剰消費と「混乱(confusion)」による誤ったパラメータ選択が主要な問題である。
文脈工学による解決アプローチ
ツール定義を単純に拡張するだけでなく、LLM が何をいつ見るかを制御する文脈工学の手法を用いて、推論能力の低下を防ぎつつパフォーマンスを向上させる必要がある。
実証例とトレードオフの提示
AWS は K-12 コンテンツ検索 API を模した事例を通じて、ツールレベルでの改善アプローチとそのトレードオフを実践的に示し、Kiro CLI によるローカル実行を推奨している。
記述とレスポンスの最適化
ツールが何を返すかが振る舞いに影響するため、意思決定に必要な数値に絞ったデフォルト応答とし、詳細はオンデマンドで取得する設計が有効である。
スキーマ制約による推測の排除
列名をLLMが理解しやすい用語へ変更し、デフォルト値を設定、有限値には列挙型(enum)を用いることでモデルの推測コストを削減できる。
重要な引用
When Model Context Protocol (MCP) tools underperform, the cause is rarely the protocol itself but the tool design.
Two problems are behind most of these failures. The first is bloat... The second is confusion.
Shifting to an on-demand approach for detailed output cuts response tokens by roughly two-thirds
A response that says 'search requires 2 or more terms in query' tells the LLM exactly what to change.
編集コメントを表示
編集コメント
AWS は、MCP という新しいプロトコルが普及する中で、単なる API の公開ではなく、LLM の挙動特性に合わせた設計思想の転換を求めている。これは実務レベルでの AI エージェント構築において、即座に適用可能な重要な知見である。
Source Article
元記事を日本語で読む
本文に関係しない購読案内、埋め込み通知、サイト内プロモーションは除いています。
Model Context Protocol (MCP) ツールが期待通りに動作しない場合、その原因はプロトコル自体ではなく、ツールの設計にあることがほとんどです。多くのチームは、既存の API をそのまま公開し、エージェントに残りの部分を考えさせることから始めます。これは、API をエージェントシステムや生成 AI によるコーディングツールへ拡張する自然な方法ですが、単純なユースケースでは機能するものの、必ずしも成功するとは限りません。
LLM(大規模言語モデル)やエージェントシステムの動作特性に合わせたツール設計が不可欠です。これを怠ると、ツールの呼び出し失敗、パラメータ値の誤り、コンテキストを浪費してパフォーマンスを低下させる再試行といったリスクが生じます。本稿では、MCP ツール設計でよく起こるミスを解説し、実践的な コンテキストエンジニアリング のアプローチを用いた解決策を示します。
これらの失敗の背景には主に 2 つの問題があります。1 つ目は「肥大化(bloat)」です。ツール定義は、そのツールが実際に使用されるかどうかに関わらず、すべての呼び出しで LLM のコンテキストに読み込まれます。複数の MCP サーバーを接続している場合、ユーザーがまだ質問もしていない段階で、すでに大量のコンテキストを消費してしまいます。コンテキストが飽和すると、LLM の 推論能力が低下 し、セッション全体の生産性が損なわれる原因となります。
2 番目の問題は「混乱」です。推論能力が低下すると、LLM は不適切な選択を行い、誤ったツールを呼び出したり、間違ったパラメータを選択したりします。その後の再試行は問題をさらに悪化させ、コンテキストの肥大化(ブloat)に拍車をかけます。ツール間の意味的な類似性、選択肢が多すぎる点、曖昧な名前付けも 混乱の一因となります。一般的な対策として、ツールの説明をより明確な定義や自然言語によるマッピング、使用例で補強する方法があります。これは確かに混乱の解消に役立ちますが、追加される情報はすべてコンテキストの肥大化を悪化させ、解決しようとしている問題自体をさらに複雑にするリスクがあります。
このパターンはよく見られます。エージェントが予期せぬ選択を行い、コンテキストが想定より早く埋まり、セッションの有用性が急速に低下します。コンテキストの肥大化と混乱への対処は、本質的に「コンテキストエンジニアリング」の問題です。コンテキストエンジニアリングとは、LLM が何を、いつ見るかを設計するものであり、これによってモデルの出力品質を向上させます。このうちいずれか、あるいは両方を改善することは、非常に複雑なバランス感覚が求められる作業です。
以下のセクションでは、これらの課題に対処するためのアプローチとトレードオフについて探ります。具体例として、MCP プロトコルを使用してシミュレーションされた K-12 向けコンテンツ検索 API を公開したサンプルをいくつか作成しました。これらをローカルで実行し、Kiro CLI を用いて対話しながら、違いを実際に比較することができます。
アプローチとトレードオフ
今回紹介するアプローチは、ツールレベルでこれらの課題に対処するものです。LLM が見る内容やそのタイミングを調整するものもあれば、ツールの構造自体を変えるものもあります。これらを実践する際は、情報の膨張(ブロー)と混乱のバランスをどう取るか、それぞれの影響を理解しておく必要があります。
説明とレスポンス設計
MCP ツールの動作を改善するための最初のステップは、その説明を充実させることです。混乱を防ぐ確実な方法は、値の意味や自然言語との対応関係、そしてツールの目的を明確にすることです。ただし、やりすぎると逆に情報が膨らんでしまいます。クライアントに複数の MCP サーバーを読み込む場合、コンテキストの量とコストはあっという間に増大します。
ツールが返すデータの内容も動作に影響を与えます。1 件の結果で 50 フィールドを返すようなツールだと、すぐにコンテキストがいっぱいになってしまいます。意思決定に 5 つのフィールドだけで十分なら、デフォルトではその 5 つだけを返し、詳細な表示が必要になった場合に別途リクエストできるオプションを用意しましょう。詳細出力はオンデマンド方式に切り替えることで、レスポンスに必要なトークン数を約 3 分の 1 に削減できます(Anthropic の研究による)。
適切なエラーメッセージも効率化の重要な手段です。ツール呼び出しが失敗した際、役立つエラーメッセージがあれば次の試行を導くことができます。「検索にはクエリに 2 つ以上の用語が必要です」というレスポンスなら、LLM は何を修正すべきかが明確になります。一方、「結果なし」だけ返される場合、LLM は何も手がかりを得られず、諦めるか根拠のない推測を繰り返すことになります。
スキーマ制約
LLM が正しい値を導き出すために記述や適切なエラーが役立つ一方で、列挙型(enum)やデフォルト値といったスキーマ制約を使えば、推測の余地そのものをなくすことができます。一般的なスキーマの問題に対処するには、以下の点を考慮してください。
- パラメータ名は、データベースが列をどのように呼んでいるかではなく、LLM がドメインを理解しそうな表現に合わせて改名します。「Student Resource」や「Teacher Support」といった値を持つ
resource_classというパラメータの方が、LLM にとっては明確です。一方、content_bucketカラムでは、LLM が内部の規約を知っている必要があります。
- デフォルト値は最も一般的な値に設定し、LLM が指定するのは変化する部分だけで済むようにします。
- 有限の値を持つフィールドには列挙型(enum)を適用して、スキーマ自体が LLM に有効な値を示すようにします。
- ほとんど使われないフィールドや、LLM が効果的に利用できないフィールドは削除します。AWS の MCP ストラテジーに関する推奨ガイド では、ツールのパラメータ数は 8 つ以下に抑えることを推奨しています。
ツールの再構成とオンデマンドコンテキスト
汎用的なツールを複数の特定のツールに分割することで、モデルへの明確さを与え、より細粒度の結果を得ることができます。例えば、遅延読み込み型の発見ツールがあります。常に読み込まれるコンテキストから複雑なツールの説明を削除し、オンデマンドでの取得専用のツールを提供できます。LLM はタスクが必要になった時だけこのコンテキストを取得します。これにより、コンテキストは軽量で焦点が絞られた状態を保たれます。
Anthropic の Tool Search Tool や Amazon Bedrock AgentCore Gateway では、これらの概念が大規模に適用されています。Anthropic によると、関連する時だけツールの定義を読み込むことで、トークン使用量を最大 85% 削減できるそうです。
Skills も遅延読み込みの一例ですが、こちらはクライアント側で実装されています。これらのローカルファイルにはツールの有用なコンテキストが含まれていますが、関連する時だけコンテキストに読み込まれます。これにより、実装と配布の手間を減らすことができます。ただし、必要な時にスキルが確実に読み込まれる保証や、インストール後に不変である保証はありません。
サーバーサイド推論
どのモデルが自分の指示を解釈するかを制御できない場合、コンテキストエンジニアリングは困難を極めます。また、デプロイ後には、どの LLM が MCP ツールを呼び出すかを完全に制御できないこともあります。あるモデル向けに調整した説明が、別のモデルでは混乱を招く可能性があります。クライアントが使用する可能性のあるすべての潜在的なモデルを完全にテストするのは現実的ではありません。
この課題への対処法の一つとして、外部の LLM を直接呼び出す「自己分析ツール(introspection tool)」を追加する方法があります。クライアントは自然言語でこの自己分析ツールに問い合わせ、他のツールの使い方を示す具体的な指示を受け取ります。モデルを自分で選べるため、このツールに対して適切なプロンプトエンジニアリングを行い、正解となるクエリでテストすることも可能です。最終的なツール呼び出し自体はクライアント側の LLM が行いますが、必要な処理の解釈と正しい値の提供は、こちらの LLM が担当します。対象とするユースケースが明確であるため、小さく高速なモデルでもこのタスクを十分にこなせ、スケールしてもコストを適切に抑えることができます。
Agentic tools(エージェント型ツール)
精度と完全な制御が必要になる場合、次の論理的なステップは、MCP サーバー全体を自前のエージェントで支えることです。先ほどの自己分析の例では単一の解釈ステップしか処理できませんが、エージェント型ツールは対話全体を担います。ツール自体がクライアント向けの自然言語エンドポイントとなり、「何が必要か」を宣言するだけで、残りの処理はエージェントが行います。これまで紹介した他の手法も引き続き有効です。トレードオフはすべて自らが引き受けることになりますが、自己分析の場合と同様に、好みのモデルを用いて振る舞いを完全に設計・制御することが可能です。
次のセクションでは、これらのアプローチを同じバックエンドとテストクエリに適用する実装コードを紹介し、それぞれの挙動を直接比較できるようにします。
6 つのバージョンは、すべて同じ K-12 向けコンテンツ検索バックエンドを異なる MCP ツール設計でラップしています。このバックエンドには、教科目・学年・フォーマット・基準適合性・言語・リソースクラスなど、制御された語彙を持つ 14 のフィルタリング可能なフィールドがあります。
LLM が直面する課題は、教師がリクエストを表現する方法と、各フィールドが受け付ける正確な値との間のギャップを埋めることです。V1 はこのギャップを放置した生きたパススルーから始まります。その後の各バージョンは、それぞれ異なる方法でこのギャップを解消します。
前提条件
サンプルコードを実行するには、以下の準備が必要です。
- Python 3.10 以上
- SQLite(Python に同梱されています)
- Kiro(無料枠あり)またはその他の MCP クライアント
- Amazon Bedrock モデルへのアクセス権限を持つ AWS アカウント(V5 と V6 のみ必要):Amazon Nova 2 Lite および Anthropic’s Claude Sonnet 4.6
サンプルコードリポジトリ をクローンし、詳細な前提条件、インストール手順、サーバー起動方法についてはリポジトリの README に従ってください。以下の解説では、すべての 6 つのバージョンが実行されていることを前提としています。
AWS へのインフラ構築は不要です。すべてのコードをローカルで実行します。コストが発生するのは、コーディングクライアントの使用と Amazon Bedrock への推論呼び出しのみです。最新の料金は Amazon Bedrock の料金ページ をご確認ください。
このチュートリアルでは、Kiro を使用し、リポジトリから python scripts/setup_agents.py を実行済みであることを前提としています。
テストクエリ
以下のクエリはサンプルデータベースから実際の結果を返します。各バージョンで試してみてください。
- "7 年生向けの分数のクイズを探して"
- "中学校でのスペイン語教授法に関するレッスン資料はありますか?"
- "中学校で割り算に取り組む児童向けに、TEKS に準拠したコンテンツが必要です"
- "検索できるコンテンツの種類は何ですか?"
- "n-sc-1096 の詳細情報を取得できますか?
各バージョンを実行する際は、以下の点を確認してください。
- LLM が最初の呼び出しで適切なフィルタ値を選択できたかどうか
- 完了までにツール呼び出しが何回必要だったか
- 回答に LLM が不要な情報を含んでいないか
- コンテキストウィンドウがいかに早く埋まるか。Kiro の表示パーセンテージを確認するか、
/context showコマンドで詳細内訳をチェックしてください。

バージョンを切り替えるには、/agent swap を使用してください(例:/agent swap v1-passthrough)。バージョン間で結果が混在しないよう、各バージョンの前後に /clear を実行してコンテキストをクリアしてください。
次の処理に影響を与える。
V1:生パストスルー
v1_passthrough.py
最初のバージョンは、典型的なアンチパターンである基本モデルです。これはバックエンドの API をそのまま公開する形式で、ツール定義には 14 のパラメータが含まれています。discipline や media_type、content_bucket など内部実装に依存した名称が使われており、ドキュメント文字列も「教育リソースのグローバル検索を実行します」という一行の説明のみです。有効な値のリストも、自然言語によるマッピングも存在しません。
ガイダンス。
MCP ツールの設計では、実用的なアプローチとトレードオフのバランスが重要です。単に機能を追加するだけでなく、システムの安定性と拡張性を考慮した設計が必要です。
ツール定義は簡潔ですが、LLM にはどの値が有効かを示す指針がありません。最初のクエリを試すと、media_type の正当な値が「Assessment」や「Math」であるにもかかわらず、「quiz」や「math」といった誤った値を返してしまう可能性があります。各誤選択は再試行を引き起こし、より多くのコンテキストを消費します。問題が発生したことを示す唯一の手がかりは空の結果だけです。LLM は次の試行で何を修正すべきか推測するしかありません。混乱によって実際のコストが増大する場合、低バラインコストは誤解を招くものです。

V2: 詳細な説明
v2_better_descriptions.py
V1 と同じ構造で、バックエンドの改修は不要です。ドキュメント文字列には各フィールドの有効値とシノニムマッピングが記載されています。例えば discipline では「有効値:Math, Science, Literacy/ELA…」、media_type では「'quiz'/'test' → Assessment、'worksheet' → Activity」といった対応関係を示します。また、曖昧検索(keyword)と厳密なフィルタリング(それ以外)の区別も明確にしています。使用頻度の低いパラメータ 3 つを削除し、エラーメッセージでは空の結果を返す代わりに、追加すべきフィルタに関するガイダンスを表示するように変更しました。
同じクエリを再度試してみてください。LLM が有効な値とシノニムマッピングを確認できるため、精度は即座に向上します。その代わり、ツールの定義が明らかに大きくなります。これが「肥大化」のトレードオフです。ツールを使用するかどうかに関わらず、すべての呼び出しでこのコストが発生します。
5 回のクエリ実行後、V1 と比較して消費されたコンテキストの総量を比べてみましょう。1 回あたりのオーバーヘッドは高くなりますが、リトライ回数が減ることで、全体として必要なコンテキスト量はむしろ低くなるケースが多いです。

V3: スキーマとデフォルト値
v3_rethought_schema.py
このバージョンでは、LLM の思考パターンに合わせるようパラメータ名を変更し、スキーマ自体を通じて値の制約を強化しています。具体的には、discipline を subject に、content_bucket を変更しています。
resource_class。各有限値フィールドは、スキーマ内に有効な選択肢を直接列挙した Literal タイプを使用します。
一般的なケースは、structure='Asset'、resource_class='Student Resource'、language='en' といった適切なデフォルト値で処理されます。詳細な情報取得には、別途用意された get_resource_detail ツールを使用します。
このアプローチでは、再構築の手法を適用し、各ツールに明確な役割を与えつつ、検索結果は簡潔に保ちます。
列挙型(Enums)はプロトコルレベルでの誤った値を防ぐのに役立ちます。デフォルト値を設けることで、LLM は変化する部分のみを指定すればよくなります。レスポンスには defaults_applied フィールドが含まれており、LLM が何が無効化されたかを把握できます。定義が V2 よりも小さくなるのは、名前と列挙型が以前は冗長な記述で担っていた役割を果たすためです。
クエリを実行して精度を比較してください。V2 と比べて精度が向上する一方、コンテキスト量は減少します。
V4: レーザーローディング(再構築)
v4_lazy_loading.py
検索ツールに列挙型や詳細な説明を埋め込むのではなく、これらを別個のツールに移すアプローチです。検索ツールには「科目分野(例:数学、科学、読解力)」といった短いヒントの説明のみを残します。
get_taxonomy ツールはフィールド名のリストを受け取り、現在のクエリに関連するフィールドについてのみ、有効な値と自然言語によるマッピングを返します。
今回の検索ツールの定義は、これまでで最も軽量なものです。ツール呼び出しの挙動に注目してください。曖昧なクエリの場合、LLM は検索前に get_taxonomy を呼び出して有効な値を確認します。一方、ヒントが十分で明確なクエリでは、 taxonomy 呼び出しをスキップして直接検索を行うこともあります。
ヒントに含まれる一般的な値は、頻繁に発生するクエリに対してラウンドトリップ(往復通信)なしで処理できるように設計されています。一方、エッジケースにはフルな taxonomy が用意されており、必要に応じて利用可能です。taxonomy は必要な時だけ読み込まれるため、セッション内のそれまでのすべての対話において、その文脈コストを一切負担することなく動作します。
今回の例では節約効果は限定的ですが、接続されるツールが多く、スキーマも複雑な環境では、この効果が蓄積して大きなメリットとなります。

V5: LLM introspection
v5_llm_introspect.py
今回のアップデートでは、Amazon Bedrock の Amazon Nova 2 Lite をバックエンドに持つ「introspect」ツールが追加されました。この introspect_query ツールは、教師が自然言語で入力した質問を受け取り、各選択肢の根拠を説明しながら推奨されるフィルタ値を返します。例えば、「中学で除算に取り組む児童向けの TEKS 準拠教材」という問いに対しては、「Math」を subject に設定し、対象学年を 6〜8 年生とし、state_standard を指定するといった推奨フィルタが提示されます。
「TX-TEKS」のトピックは「分割(dividing)」および「分割(division)」です。 (原文の技術表記: topic)
Kiro は最終的な検索の判断を下します。Introspect は選択したモデル上で動作するため、プロンプトエンジニアリング とテストが確実に行えます。解釈はサーバー側で処理されるため、コンテキストを軽量に保つことができます。ただし、コストとのトレードオフがあります。サーバー呼び出しには費用がかかりますが、Kiro がどのモデルを使用するかに関わらず結果は一貫します。/model コマンドでモデルを切り替え、V4 と V5 を比較できます。Introspect なしでは弱いモデルでも結果が不安定になりますが、Introspect ありなら結果は安定します。
V6: エージェントをツールとして扱う
v6/app/v6/main.py
最終版では、独自のプロンプトと内部ツールを持つ Strands Agents エージェントをバックエンドに持つ単一の MCP ツールが公開されます。外部インターフェースは 1 つのツールで、パラメータも agentic_search_content(question: str) のみです。分類の検索、検索実行、詳細情報の取得、回答の整形といった処理はすべてエージェント内部で行われ、クライアント側の LLM が直接アクセスできるのはこの単一のツールだけです。
5 つのクエリをすべて実行し、クライアントコンテキストの使用量を他のバージョンと比較してください。クライアント側の LLM が行う処理は最小限です。どのクライアントが接続しても動作は一定で、推論を担当するのはエージェントだからです。会話履歴は呼び出し間でも保持されるため、フォローアップ質問も自然に機能します。その代償として、コストとレイテンシが増加しますが、代わりに動作の直接制御と一貫性を確保できます。Kiro で /model コマンドを使ってモデルを切り替えてみてくださいが、どのモデルを使っても結果は安定していることに気づくはずです。
トレードオフの全体像
各バージョンは、あるコストを別のコストと交換しています。この表で両者を並べて比較します。
バージョン
アプローチ
トレードオフ
V2
リッチな記述
AI算出
技術分析ainew評価標準
AI エージェントの運用効率向上に直結する実装知見を提供しており、新規性としては AWS の独自事例に基づく分析が含まれるが、既存の概念(MCP)の応用である点から novelty は中程度となる。検索意図は「MCP ツール設計」や「コンテキストエンジニアリング」といった具体的な技術キーワードに強く紐付くため高い。
6つの評価軸を見る
- AI関連度
- 75
- 情報源の信頼性
- 100
- 新規性
- 50
- 調べる価値
- 75
- 重複の少なさ
- 100
- 日本での有用性
- 25
関連記事
今日のまとめ
AIデイリーブリーフで今日の重要ニュースをまとめ読み