教程
Agent Plugins 如何讓 AI Coding Agent 自動獲得新能力?Plugin Manifest、Skills、MCP 與 JSON 數據結構詳解
裝上插件,Coding Agent 不會突然變聰明。它只是按固定位置多讀了幾份 JSON。
前兩篇分別講了 箱子長什麼樣,以及 何時不該裝箱。今天假設你已經決定發 Plugin。讀者真正想知道的是:Cursor、Claude Code、Antigravity 裝完這個目錄之後,模型怎麼「突然會」查發票、寫週報?答案不是權重更新,也不是系統提示被改寫。規範見 Agent Plugins 1.0.0:客戶端先讀根上的 plugin.json,再按固定位置發現 skills/ 和 mcp.json。Google Cloud Developer Plugin 走的也是這條路。本文把安裝後的 JSON hop 走完,接到 MCP 與 JSON Schema 的校驗鏈。
五跳流水線,不是「自動學會」
「自動獲得新能力」聽起來像模型學會了新技能。工程上它是五跳,一跳都省不了。第一跳:客戶端把目錄落到插件根,解析後的路徑不得逃出根——符號鏈接指向根外,整條路徑拒掉。第二跳:讀 plugin.json,過閉集 Schema,拿到 name 和規範版本。這一跳失敗,整包不加載,後面三跳不會發生。第三跳:若存在 skills/,只看直接子目錄裏恰好叫 SKILL.md 的普通文件,抽出 name 與 description 放進上下文。第四跳:若存在 mcp.json,按每條 type 去連,握手後再 tools/list。第五跳:模型對上描述或工具名,纔讀 Skill 正文,或發起 tools/call。
規範故意不管安裝按鈕長什麼樣。Google Developers Blog 寫得很清楚:安裝、權限、沙箱、確認 UX 是各客戶端的義務。Agents CLI、Cursor、Claude Code 的對話框可以完全不同。可移植的是目錄和兩份閉集 JSON。所以評審不要問「用戶點哪裏」,要問「裝完之後內存裏多了哪幾份對象」。缺 Manifest,後面四跳不會發生。Manifest 過了但 mcp.json 的 $schema 和 plugin.json 對不上,只停 MCP,技能繼續。某一份 SKILL.md 不合 Agent Skills,只跳過那一項。
橫向委託仍不在這條流水線裏。另一個團隊的發票 Agent 怎麼被發現,是 Agent Card 的事,見站內 A2A 文。今天只談:這個 Coding Agent 如何長出一組技能和工具。先承認「新能力」是發現結果,再談每一跳的 JSON。
| 這一跳 | 客戶端此刻持有的 JSON | 模型此刻能做什麼 |
|---|---|---|
讀 plugin.json | 身份對象:name / version / $schema | 還不能做事,只知道箱子合法 |
走 skills/ | 技能元數據數組(尚無正文) | 能選中說明書,正文按需再讀 |
連 MCP 再 tools/list | 工具名加 inputSchema | 能按 Schema 填參,尚未執行 |
先過 Manifest:plugin.json 是身份合同
客戶端必須先讀根上的 plugin.json,再發現組件。不能換文件名,也不能把技能或 MCP 內聯進 Manifest。Schema 是閉集:只允許 $schema、name、version、description、author、homepage、repository、license、keywords、extensions。多出來的頂層鍵,客戶端必須報告並忽略,但不能因此拒載。真正致命的是缺必填、類型錯、或 name 違規——那種情況整包拒絕,不得發現任何組件。1.0.0 的 $schema 必須是 https://agent-plugins.org/schemas/1.0.0/plugin.schema.json。客戶端用它選本地規則,加載時不得去網上拉 Schema。
name 是標識符,不是商店展示名。長度 1–64,只能小寫字母、數字、連字符和點,首尾必須是字母或數字,禁止 -- 和 ..。My-Plugin、-start 會讓整包拒載。版本推薦 SemVer,但「看起來不像 SemVer」不能當拒載理由。作者對象只允許 name / email / url。客戶端私貨放 extensions.com.example.client,或根上的反向域名目錄;不要發明第五個頂層鍵去塞 hooks。把 hooks 寫進 plugin.json 的頂層,規範要求忽略它——你的 IDE 若「剛好能讀」,換一家就丟。
下面是一份可進倉庫的完整 Manifest,比最小兩字段本多了給人看的元數據。先讓它能 parse,且過官方 Schema,再談安裝按鈕。keywords 幫目錄檢索;description 幫人決定要不要裝,不幫模型選工具。模型選技能看的是 SKILL.md 的 description,選工具看的是 tools/list。把 Manifest 描述寫成工具說明書,發現面仍然是空的。
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "invoice-ops",
"version": "1.2.0",
"description": "Invoice query MCP plus the weekly-summary skill, shipped as one directory",
"author": {
"name": "Finance Platform",
"url": "https://docs.example.com/invoice-ops"
},
"homepage": "https://docs.example.com/invoice-ops",
"repository": "https://github.com/example/invoice-ops",
"license": "MIT",
"keywords": ["invoices", "weekly-summary", "mcp"]
}
安裝之後:客戶端手裏的能力快照
規範不要求客戶端導出一份「已安裝能力」文件。但評審需要看見裝完之後內存裏是什麼。把五跳的結果收成一份快照 JSON:plugin 身份、已發現技能(只含元數據)、MCP 連接狀態、tools/list 回來的工具合同。這份快照不是 plugin.schema.json 的實例,不要拿包裝 Schema 去校驗它。它是你們 CI 的夾具:斷言技能數、工具名、inputSchema 的必填項。裝完卻對不上,說明發現或握手出了問題,而不是「模型還沒學會」。
「自動獲得」在這份對象裏看得很清楚。skills[].loaded 是 metadata,不是 body——啓動時大約一百個 token,正文按需再讀。tools[] 來自握手後的 tools/list,不是手寫進 plugin.json。mcpServers[].status 是運行時,不是包裝合同。如果快照裏 tools 爲空,但 MCP 顯示 connected,說明握手過了、Server 沒暴露工具——去查 Server,不要改 Manifest。反過來,Manifest 合法、快照裏技能爲零,去查 skills/ 是不是把 SKILL.md 藏深了一層。
Google Cloud Developer Plugin 裝完之後,客戶端側同樣是:箱子身份 + gcloud 護欄技能的元數據 + Developer Knowledge MCP 的工具清單。用戶感覺「Agent 會查 Cloud 文檔了」,數據上只是 tools 數組多了幾項。把快照和倉庫裏的 plugin.json / mcp.json 並排 diff,能立刻發現有人把運行時狀態寫回了包裝文件——那是 drift,不是規範字段。
{
"plugin": {
"name": "invoice-ops",
"version": "1.2.0",
"spec": "1.0.0"
},
"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.",
"path": "skills/write-weekly-summary/SKILL.md",
"loaded": "metadata"
}
],
"mcpServers": [
{
"id": "invoice-tools",
"type": "streamable-http",
"status": "connected"
}
],
"tools": [
{
"name": "query_invoices",
"server": "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"] }
}
}
}
]
}
技能跳:frontmatter 變成發現面
Agent Plugins 不重寫 SKILL.md。發現規則只有一條:skills/ 的直接子目錄裏,有一份名爲恰好 SKILL.md 的普通文件。藏在 skills/deploy/extra/SKILL.md 不會被看見。不合 Agent Skills 的那一項必須跳過,其他技能和 MCP 繼續加載。客戶端抽進上下文的,是 frontmatter 裏的 name 與 description,外加路徑以便按需再讀正文、scripts/、references/。
description 必須同時寫「做什麼」和「何時用」。寫成 invoice-ops-skill-v2 或第一人稱口號,發現面等於零——箱子裝上了,模型選不中,用戶會以爲插件壞了。其實壞的是說明書。scripts/ 仍是「請用已有 shell 跑這個腳本」,參數走 argv,不是 tools/list 裏的一等工具。快照的 tools[] 裏不要出現腳本名;出現了,說明有人把 Skill 附件誤記成 MCP。
技能正文按需加載,是爲了省窗口。快照保持 loaded: metadata,是爲了抓住「把整本 runbook 注入系統提示」的迴歸。窗口被說明書撐爆,不是 Plugin 格式的鍋,是客戶端加載策略的鍋。規範只保證技能能被發現;怎麼暴露給模型和用戶,仍由客戶端決定。
MCP 跳:連上再 tools/list
mcp.json 必須在根上,不得寫進 plugin.json,也不得換一個核心路徑。頂層只能有 $schema 和 mcpServers。$schema 釘在 https://agent-plugins.org/schemas/1.0.0/mcp.schema.json,且必須和 Manifest 聲明的規範版本一致。對不上,只停該插件的 MCP,技能繼續。每條 server 必須顯式 type:stdio、streamable-http,或可選的遺留 sse。客戶端不得從對象形狀去猜傳輸。streamable-http 的 url 必須是絕對 http/https,非迴環必須 https。headers 是可見的包裝數據,不是密鑰槽。
連上之後的發現面纔是 tools/list。包裝文件回答「去哪連」;工具合同回答「這一跳 arguments 合不合法」。不要把 inputSchema 抄進 plugin.json,也不要把 name / version 抄進 inputSchema。鑑權失敗是那一臺 server 的連接失敗,不是插件配置非法——規範不定義便攜的 OAuth 字段,密鑰仍走客戶端運行時。線協議細節見站內 MCP 是什麼。
下面是遠程 MCP 的可移植片段。倉庫夾具裏不要寫 API Key。連上後,把 tools/list 的結果填進快照的 tools[]。握手失敗只跳過這一條 server,其他 server 和技能繼續——這是規範的失敗邊界,不是產品口號。
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
"mcpServers": {
"invoice-tools": {
"type": "streamable-http",
"url": "https://billing.example.com/mcp"
}
}
}
| 失敗 | 死掉的 | 還活着的 |
|---|---|---|
plugin.json 的 name 含大寫 | 整包,不發現任何組件 | 無 |
mcp.json 的 $schema 與 Manifest 不一致 | 該插件全部 MCP | 技能繼續加載 |
一份 SKILL.md frontmatter 壞了 | 那一項技能 | 其他技能 + MCP |
獨立失敗,夾具留給 JSONVue
評審夾具至少四份:上面的合法 plugin.json、能力快照、可移植 mcp.json、一次 query_invoices 的 arguments。第一份必須過官方 plugin.schema.json。第二份用你們自己的快照 Schema,或只做結構斷言——不要拿包裝 Schema 去套。第三份過 mcp.schema.json。第四份過工具的 inputSchema。四份都叫 JSON,職責差一層:身份、庫存、連接、調用。
再加兩份負例:把 name 寫成 Invoice-Ops;把 mcp.json 某條的 type 刪掉。前者必須整包拒載。後者只跳過那條 server。如果你的 CI 把「多一個未知頂層字段」當成整包失敗,你比客戶端更嚴,要自己知道——規範要求報告並忽略多餘字段,插件仍加載。密鑰不要出現在任何一份進倉庫的夾具裏。
瀏覽器裏即可完成:JSON 格式化看 Manifest、快照與 mcp.json 能否 parse;JSON Schema 校驗核 $schema、name、mcpServers 與 inputSchema;JSON Diff對比快照和倉庫裏的包裝文件,抓把運行時寫回去的 drift;數據不離開本機。延伸閱讀:MCP 與 JSON Schema、Plugins 總覽、以及何時裝箱。
相關文章:Google Agent Plugins 2026、Skills vs MCP vs Plugins、MCP 與 JSON Schema、MCP 是什麼。
常見問題 FAQ
裝上 Plugin,模型是被微調了嗎?
沒有。權重沒變。客戶端多了一份身份對象、一組技能元數據、以及 tools/list 回來的工具合同。用戶感覺「會了」,是因爲發現面變了,不是因爲模型學會了發票業務。
能不能把工具清單寫進 plugin.json,省掉 mcp.json?
不能。Manifest 不能內聯組件,也不能改發現路徑。工具清單來自握手後的 tools/list。寫進 plugin.json 的頂層會被忽略;寫進 extensions 只對那一家客戶端有意義,換一家就丟。
能力快照能用官方 plugin.schema.json 校驗嗎?
不能。官方 Schema 只描述箱子身份。快照是客戶端裝配的庫存,裏面有運行時 status 和工具 inputSchema。給快照另寫一份 Schema,或只在 CI 裏斷言關鍵字段。
各客戶端安裝 UX 不同,Plugin 還算可移植嗎?
包裝可移植,安裝不必可移植。規範把安裝、權限、沙箱明確排除。換客戶端時,目錄和兩份閉集 JSON 不用分叉;確認對話框、企業策略可以完全不同。
總結與下一步
2026 年說「Plugin 讓 Coding Agent 自動獲得新能力」,可以收成一句:新能力是發現結果,不是權重。五跳走完,內存裏多的是身份、技能元數據、工具合同。少一跳,用戶看到的就是「裝了但不會」。
落地順序:先讓 plugin.json 過官方 Schema;再走 skills/ 和 mcp.json;把結果收成快照夾具;第一次 tools/call 用 inputSchema 核 arguments。用 JSONVue 把四份合同留在本地。箱子總覽讀 Plugins 文;要不要裝箱讀決策文;線協議讀 MCP 文。