チュートリアル
なぜ AI エージェントは Tool Calling から Skills + Plugins へ移るのか:2026 年のアーキテクチャ変化と JSON データ流
Tool Calling は廃れていない。廃れたのは、全部のツール Schema と手引きを一度のリクエストに詰めるやり方だ。
すでに エージェント循環とは何か、MCP のこの hop で arguments をどう検証するか、Skills / MCP / Plugin の選び方 を書いた。今日はこの三本を繰り返さない。レビューでよく出る別の一言がある。「もう Tool Calling があるのに、なぜ Skills と Plugins か」。フィールドの埋め方ではなく、アーキテクチャがなぜ変わるかの問いだ。理由は具体的だ。ツールが増えると、全表の Schema が先に窓を食う。流れが長くなると、システムプロンプトの SOP が切られる。クライアントを替えると、説明書と手が分岐する。Agent Skills は漸進開示で発見面を name + description に縮める。Agent Plugins 1.0.0 が決めるのは箱であり、呼び出しではない。Google も、単一スキル、単一 MCP、単一クライアントなら箱は要らないと言う。本稿は旧リクエストと新トレースを JSON として並べる。
壊れるのは呼び出しではなく発見面
Tool Calling は、モデルが関数名と arguments を選ぶ hop のままだ。2026 年に退役宣言は出ていない。退役したのは詰め方だ。起動時に五十件の inputSchema を tools[] へ流し、「先にプロジェクトを確認し、次に billing、週報は経理の型で」を system に貼る。十個までは耐える。三つめの業務域で、リクエスト自体が誰も diff しない巨大 JSON になる。誤ったツールは幻覚に見える。根はだいたい発見面が広すぎ、説明書が切れていることだ。呼び出し hop は壊れていない。発見まで同時にやらせた。
窓は第一刀に過ぎない。第二刀は変更だ。経理が週報の節順を変えると、システムプロンプト、内部 wiki、三つの IDE に貼った規則を同時に直す。diff できる SKILL.md が無ければ、その変更は PR に入らない。第三刀はクライアント横断だ。Cursor の MCP 方言、Claude Code のスキルディレクトリ、Antigravity のプラグイン配置。包装が三通り。ツールは同じなのに箱が先に分岐する。痛みは tools/call の封筒ではない。封筒の外、「いつ使うか、誰と一緒に行くか」の層だ。
だから「Skills + Plugins へ向かう」はスローガンの入れ替えではない。発見と包装を呼び出しリクエストから外に出す。呼び出し hop は残る。詳しくは MCP と JSON Schema。エージェント循環も残る。定義の記事を見てほしい。今日見るのは、外に出したあと JSON がどう流れるかだけだ。インストール後にクライアントが何を持つかは Plugin Manifest 実戦 の五 hop。本稿はその五 hop がなぜ現れたかだ。
| この層 | 古いやり方 | 2026 年のやり方 |
|---|---|---|
| ある流れをいつ使うか | システムプロンプトの長い段落 | Skill の description(約百トークン) |
| どの手があるか | リクエスト内の全表 tools[] | Plugin 導入または MCP 接続のあと tools/list |
| 実際の呼び出し | モデルの arguments → ランタイム | 変わらない。parse + Schema のまま |
置き換えではない。呼び出し層は残り、上に一層乗る
Skills を「次世代の Tool Calling」と呼ぶと、ログで層を間違える。Skill に tools/call は無い。説明書だ。起動時はメタデータだけ入れる。モデルが引き金に当たってから本文と scripts/ を読む。手が MCP。Plugin はディレクトリ。三つは呼び出しの上に乗る。arguments の hop を置き換えない。正直なトレースには、合法な tools/call が一度は残る。残らなければ、発見層がモデルを止めたのであり、呼び出し層が消えたのではない。
漸進開示は Agent Skills 仕様の核であり、宣伝の形容詞ではない。name は最大 64、description は最大 1024、三人称で、何をするかといつ使うかを書く。内部コード名や一人称のスローガンだと発見面はゼロになる。ツールはあるのにモデルが選ばない。本文を必要になってから読むのは、ランブックと五十件の Schema が同じ窓を奪い合わないためだ。スクリプトは今まで通り argv であり、tools/list の一等ツールではない。安定した JSON 入力が要るなら、やはり MCP だ。
Plugin はさらに薄い。ツール一覧を埋め込めず、SOP を plugin.json のトップに書けない。箱は「この説明書とこの手があるか」に答える。呼び出しは「この hop の arguments が合法か」に答える。JSON は二枚、仕事は二つ。四つの判断は 選択の記事、インストール後の五 hop は Manifest の記事。今日描くのは、流れが平坦から厚くなった経路だけだ。
旧データ流:巨大な tools 配列ひとつ
旧リクエストはメニューと店の規則を足した形だ。tools の各項に完全な inputSchema が付く。system に流れを詰める。ユーザーの一文で、モデルは全メニューから注文する。短いメニューなら速い。メニューが請求書 + 経費 + 権限 + デプロイ + 文書検索になると、注文自体が先に失敗する。似たツールが奪い合い、SOP は「秘密をコミットするな……」の途中で切れる。チケットには「モデルが暴れた」と書く。diff を見ると、先に暴れたのはリクエスト本体だ。
この JSON には隠れたコストがある。ランタイムが組み立てるので、リポジトリに入らないことが多い。誰かが send_slack を足しても、Schema がどれだけ膨らんだかを示す PR が無い。レビューはログの巨大な本体を見るしかない。予算が無ければ、「発見層を分けるべき」という信号も無い。平坦な構成は道徳の失敗ではない。計器の無い膨張だ。
下は潰した旧 fixture だ。本番はもっと長い。まず parse させ、tools.length とリクエストバイトに CI 予算を付ける。予算超えは「プロンプトをもう一行足す」ではない。SOP と全 Schema を起動リクエストから出す合図だ。
{
"era": "flat-tool-calling",
"system": "Always check the billing project first. Never commit secrets. Write the weekly invoice summary the finance team actually reads.",
"tools": [
{
"name": "query_invoices",
"inputSchema": {
"type": "object",
"required": ["week"],
"properties": {
"week": { "type": "string", "pattern": "^[0-9]{4}-W[0-9]{2}$" },
"status": { "type": "string", "enum": ["open", "paid", "overdue"] }
}
}
},
{
"name": "export_csv",
"inputSchema": {
"type": "object",
"required": ["week"],
"properties": { "week": { "type": "string" } }
}
},
{
"name": "send_slack",
"inputSchema": {
"type": "object",
"required": ["channel", "text"],
"properties": {
"channel": { "type": "string" },
"text": { "type": "string" }
}
}
}
]
}
新データ流:メタデータ → 本文 → ツール契約
新しいトレースは必要になってから厚くなる。起動:文脈にあるのはスキルメタデータだけ(箱を入れたなら Plugin の身元も)。マッチ:そこで SKILL.md の本文を読む。手が要る:このラウンドの inputSchema を tools/list から窓へ入れる。呼び出し:arguments は今までと同じ Schema 検査を通る。窓に同時に載るものは、「全メニュー + 全規則」から「索引一枚 + 今開いた一冊」に変わる。トークンの請求は起動一括から、マッチ単位へ移る。
tools[] は消えていない。後ろへ下がった。下がった代償は、握手が一度増え、マッチ失敗の道が一本増えることだ。description が弱いとモデルは第三 hop に届かず、利用者は「Plugin を入れてもできない」と言う。発見面のバグであり、Tool Calling の回帰ではない。逆に、トレースにすでに inputSchema があるのにランブックを system へ流し込むのは、新構成の逆戻りだ。窓の請求が戻る。
下は同じ任務の新 fixture だ。仕様ファイルではない。レビュー用のトレースだ。旧リクエストと並べて diff すると、SOP は system から skills[].description へ、Schema は起動から afterMatch.tools へ移っている。呼び出し層の query_invoices 契約は、同じ canonical Schema のままにする。「新構成用」に二組目のフィールドを作るな。
{
"era": "skills-plus-plugins",
"startup": {
"plugin": "invoice-ops",
"skills": [
{
"name": "write-weekly-summary",
"description": "Turn invoice query results into the weekly summary finance reads. Use when the user asks for a week-end report.",
"loaded": "metadata"
}
]
},
"afterMatch": {
"skillBodyLoaded": true,
"tools": [
{
"name": "query_invoices",
"source": "mcp:invoice-tools",
"inputSchema": {
"type": "object",
"required": ["week"],
"properties": {
"week": { "type": "string", "pattern": "^[0-9]{4}-W[0-9]{2}$" },
"status": { "type": "string", "enum": ["open", "paid", "overdue"] }
}
}
}
]
}
}
なぜ Plugin がまだ要るのか。説明書と手は一緒に旅する
SOP を Skill に、API を MCP に収めるだけでもリクエストは痩せる。クライアントが二台になると、ディレクトリ配置と MCP 方言がまた分岐する。Plugin が値を持つのは、説明書と手が一緒に旅しなければならないときだ。Google Cloud Developer Plugin が gcloud のガードレールスキルと Developer Knowledge MCP を一包みにする理由はそこだ。Tool Calling が弱いからではない。箱はツールを実行しない。Antigravity、Claude Code、Cursor で発見パスが分岐しないことだけを保証する。
クライアント一台、サーバ一台なら、そのクライアントの素の MCP 設定でよい。「先進的」だから Plugin を先に作ると、Manifest が一枚増えるだけだ。判断記事の第三問と第四問は今も使える。アーキテクチャの移行は「全員が Plugin に上がる」ではない。「呼び出し層は安定させ、痛みが出た層に発見と包装を足す」だ。二台目が無く、説明書と手が互いに依存しないなら、Skill か素の MCP で止めるのが正しい 2026 年の構成だ。
A2A との境界をもう一度引く。別のエージェントをどう見つけるかは Agent Card であり、相手を tools[] に詰め込むことではない。平坦な Tool Calling が膨らむもう一つの道は、遠隔エージェントを関数ひとつにすることだ。arguments の形が壊れる。横方向の委譲は今日の流れの外だ。今日扱うのは、この一台がメニューを減らし、索引を増やす方法だけだ。
| 症状 | 先に動かす層 | やってはいけないこと |
|---|---|---|
リクエスト 200KB、tools が 40 件 | 発見:Skill メタデータ + 必要になってからの Schema | システムプロンプトをさらに長くする |
| IDE を替えたら説明書と手が食い違う | 包装:Plugin ディレクトリ | 別クライアントの方言をもう一枚写す |
| ツールは当たるが週報の型が乱れる | 説明書:SKILL.md 本文 | 空の format_report ツールを足す |
二つの fixture を並べて diff
レビュー fixture は少なくとも三枚。上の旧リクエスト、新トレース、本物の query_invoices arguments 一回。前二枚は「膨張をどの層から外したか」を持つ。三枚目は呼び出し層が書き換わっていないことの証明だ。inputSchema は同じ canonical のまま。Plugin の name をツール arguments へ写した、あるいは inputSchema を plugin.json へ写した、は diff で一目で分かる。
負例を二枚足す。新トレースの skills が空なのに era が skills-plus-plugins と名乗っている。旧リクエストの tools.length が予算超えなのに分割記録が無い。前者はスローガンだけ変わって発見面が変わっていないことを掴む。後者は「プロンプトを長くして耐える」を掴む。リポジトリに入れる fixture に秘密を書くな。
ブラウザで足りる。JSON 整形で旧リクエストと新トレースが parse できるか見る。JSON Schema 検証で inputSchema と arguments を見る。JSON Diffで旧 system / tools と新 skills / afterMatch を並べる。データはマシンから出ない。続きはMCP と JSON Schema、選択の判断、Manifest の五 hop。
関連:AI Agent とは何か、MCP と JSON Schema、Skills vs MCP vs Plugins、Plugin Manifest 実戦。
よくある質問
Tool Calling は消すべきか
消さない。モデルは関数名と arguments を選び、ランタイムは tools/call を出す。消すのは起動時の全メニューであり、呼び出し hop ではない。トレースに合法な呼び出しが無ければ、先に発見面を見、それからランタイムを見る。
Plugin 無し、Skill だけでも新構成か
発見層までは来ている。SOP がシステムプロンプトを離れ、必要になってから載る。リクエストは痩せる。包装層ではない。クライアント一台で足りるならそこで止める。二台目が出て、説明書と手が一緒に行かなければならないなら Plugin を足す。
全部の Schema を起動リクエストに残す方が速くないか
メニューが短く、ツールが安定し、クライアントが一台なら速いし単純だ。件数かバイトで予算を超えると、誤ったツール選択が稼いだ遅延を食う。感覚より先に予算を置け。
Programmatic Tool Calling と衝突するか
しない。Programmatic Tool Calling は呼び出し層のプログラム構造だ。モデルが手順に沿って連続でツールを呼ぶ。Skills + Plugins は発見と包装だ。どの説明書を読むか、どの手をつなぐか。先に索引、それから連続呼び出し。
まとめと次の一手
2026 年に「Tool Calling から Skills + Plugins へ」と言うなら、一行で足りる。呼び出し hop は残す。発見と包装は巨大なリクエストから外へ出す。モデルは注文する。開席時に全メニューを卓へ載せない。
出す順はこうだ。旧リクエストの tools.length とバイトに予算を付ける。SOP を description に収める。全 Schema はマッチのあとに移す。クライアントが二台になったら plugin.json を足す。旧リクエストと新トレースは JSONVue で並べる。循環の定義は Agent の記事、arguments は MCP の記事、箱にするかは判断の記事。