最近翻 Google Cloud 的開發環境設定文件, 在一堆 gcloud CLI、Cloud Shell、Cloud Workstations 中間,多了一段以前沒有的東西:
agy plugin install https://github.com/google/skills/plugins/cloud/google-cloud-developer
agy 是 Google Antigravity CLI。但真正讓我停下來的不是這個新 CLI,而是後面那串網址:
Google 開始把自家的產品知識,包成 agent plugin 放在 GitHub 上發佈。
結果我打開自己的 Claude Code 一看,這個 plugin 早就裝在機器上了。所以這篇不用先裝 Antigravity CLI, 直接拿現成的來實測,看看它到底做了什麼。
這個 plugin 裡面裝了什麼
先把它拆開看。整包其實不大,5 個 skill、1 份路由規則、1 個 MCP server,全部加起來 1549 行 markdown,沒有任何程式碼:
skills/gcloud/ # gcloud 指令的安全護欄與語法驗證(272 行 + 340 行參考文件)
skills/retrieving-developer-knowledge/ # 查官方文件(103 行 + 182 行參考文件)
skills/finding-google-skills/ # 按需從遠端目錄撈技能(134 行)
skills/google-cloud-recipe-onboarding/ # 新手開第一個專案(228 行)
skills/google-cloud-recipe-auth/ # 憑證與 ADC 選擇(260 行)
rules/google-cloud-discovery.md # 技能路由表(30 行)
有趣的是同一個目錄底下塞了四套 manifest:
.claude-plugin/plugin.json # Claude Code
.codex-plugin/plugin.json # Codex
gemini-extension.json # Gemini CLI / Antigravity
plugin.json # 通用格式
那份通用的 plugin.json 開頭是這樣:
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "google-cloud-developer",
"version": "1.1.2",
"author": { "name": "Google LLC" },
"license": "Apache-2.0"
}
agent-plugins.org 是個跨工具的 plugin schema。Google 沒有為自己的 Antigravity 做一份專屬格式,
而是同一包東西讓四種 agent 都吃得下去。換句話說,你不裝 Antigravity CLI 也用得到這包東西。
安裝:三條路挑一條
Antigravity CLI(文件上寫的)
agy plugin install https://github.com/google/skills/plugins/cloud/google-cloud-developer
Claude Code
claude plugin marketplace add google/skills
claude plugin install google-cloud-developer@google-plugins
通用
npx skills add google/skills
裝完後要開 API:
gcloud services enable developerknowledge.googleapis.com --project=YOUR_PROJECT_ID
確認裝到哪:
$ ls ~/.claude/plugins/cache/google-plugins/google-cloud-developer/
1.1.2
實測一:護欄擋不擋得住亂掰的 flag
這個 plugin 最核心的是 gcloud 這個 skill。它開頭第一段話講得很直白:
All pre-existing knowledge of
gcloudcommands, flags, flag values, and positional argument syntax is stale and prone to hallucination.
翻成白話:你(模型)記得的 gcloud 語法都是過期的,不准憑記憶寫。
所以它訂了一條硬規則:動手之前一定要先跑 gcloud help <leaf command>,而且父層的 help 不算數,
要驗到最底層的子指令。它甚至明文禁止用網路搜尋來查語法,gcloud help 是唯一權威。
這條規則有沒有必要?拿 Cloud Run 的 scaling flag 來測:
$ for f in --min-scale --max-scale --min-instances --max-instances; do
gcloud help run deploy | rg -q -- "$f" && echo "$f 存在" || echo "$f 不存在"
done
--min-scale 不存在
--max-scale 不存在
--min-instances 存在
--max-instances 存在
--min-scale / --max-scale 是 Knative 和早期 Cloud Run 的寫法,現在已經不是了。
但這兩個字串在網路上的舊文章、舊 Stack Overflow 回答裡到處都是,
所以模型非常容易吐出一個看起來很合理、跑起來直接報錯的指令。
先跑一次 gcloud help,這個問題就消失了。
順帶一提,gcloud run deploy 其實沒有 --dry-run,只有 --async。
skill 的規則是「help 輸出裡有列 --dry-run 或 --validate-only 就一定要先跑一次」:
有列才跑,沒列就算了。
實測二:盲目 list 到底會吃掉多少 context
skill 裡有一條規則我一開始覺得有點囉嗦:
DO NOT execute any
listcommand without including at least one data reduction flag (--limit,--filter, or--format).
實際量一下就知道為什麼了。我手上有個 project 跑著 52 個 Cloud Run 服務:
# A. 盲目 list
$ gcloud run services list --project=YOUR_PROJECT_ID --format=json | wc -c
281918
# B. 只投影需要的兩個欄位(同樣 52 個服務,一個都沒少)
$ gcloud run services list --project=YOUR_PROJECT_ID \
--format="json(metadata.name,status.url)" | wc -c
7963
281,918 bytes 對 7,963 bytes,差 35 倍。換算成 token 大約是 70k 對 2k。
也就是說,一個沒加 --format 的 list,就要吃掉 70k tokens,
而被砍掉的那 97% 是 annotations、conditions、revision template 和一堆時間戳。
skill 還教了一招我覺得很實用的「先探 schema 再查全量」:
gcloud <GROUP> <RESOURCE> list --limit=1 --format=json
先抓一筆看 JSON 長什麼樣,確認欄位路徑之後,再去組 --filter 和 --format。
其他幾條執行規則也都是同一個思路:
- 一次只跑一個指令,不准
&&串接 - 禁止 pipe、
$( )、重導向(理由是讓人類 review 指令時看得懂) - 一律加
--project=<PROJECT_ID>,不准依賴 active config 的預設值 - 一律加
--quiet,避免在沒有 TTY 的環境卡在互動式確認
實測三:哪些指令它不准自己跑
這是我覺得最值得抄的一段。skill 裡有一份明確的 denylist, 列出沒有人類明確授權就絕對不能自動執行的操作:
- 任何 IAM policy / role / binding 的異動(權限提升、把自己鎖在門外的風險)
gcloud * delete(不可逆的資源銷毀)gcloud billing *(帳單爆炸的風險)gcloud organizations *(組織層級的設定會影響所有人)gcloud kms *(有機會把資料永久鎖死)gcloud infra-manager deployments apply(自動跑 IaC 可能砍掉一整批資源)- 主動啟用 API 也在名單上,理由是開 API 可能連帶開始計費
最後那條我覺得特別有意思。開個 API 聽起來無害,但 skill 直接寫「assume necessary APIs are enabled」, 要開就回頭問人。這種程度的保守,是有認真想過 agent 接上正式環境會發生什麼事的。
實測四:Developer Knowledge,查文件而不是憑記憶
plugin 附了一個 MCP server:
{
"mcpServers": {
"developer-knowledge": {
"type": "streamable-http",
"url": "https://developerknowledge.googleapis.com/mcp"
}
}
}
這裡遇到第一個坑。MCP server 在設定檔裡宣告了,不代表它真的接得起來。
我這邊列出來的工具只有 authenticate 和 complete_authentication,
文件講的 answer_query、search_documents 根本沒出現,代表還卡在認證流程。
有趣的是 skill 自己早就預期到了,白紙黑字寫著:
A declared server is not always a connected server. Some clients cannot complete the MCP handshake with this server and expose no
answer_query,search_documentsorget_documentstool at all, even though the plugin declares one.
然後它直接給了 REST fallback。用本來就有的 gcloud 憑證就能打,不用另外申請 API key:
curl -s -X POST "https://developerknowledge.googleapis.com/v1:answerQuery" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "X-Goog-User-Project: $(gcloud config get-value project)" \
-H "Content-Type: application/json" \
-d '{"query": "How do I deploy a container to Cloud Run with gcloud?"}'
HTTP 200,而且回來的東西比我預期的講究:
$ jq '.answer | keys' response.json
["answerText", "citations", "references"]
$ jq '.answer.references | length' response.json
10
$ jq -r '.answer.references[].documentReference.documentChunk.document.uri' response.json | sort -u
https://docs.cloud.google.com/run/docs/deploying
https://docs.cloud.google.com/run/docs/quickstarts/deploy-container
https://docs.cloud.google.com/sdk/gcloud/reference/run/deploy
https://docs.cloud.google.com/run/docs/configuring/services/containers
https://docs.cloud.google.com/run/docs/create-jobs
...
不只給答案,還附 10 篇官方文件當出處,而且 citations 是用字元區間對應到 reference index:
{"startIndex": 447, "endIndex": 505, "sources": [{"referenceIndex": 3}, {"referenceIndex": 7}]}
答案裡第 447 到 505 個字是從第 3 和第 7 篇文件來的。這種粒度的引用,要驗證答案真假就容易多了。
查精確語法則用另一個端點,我拿 Cloud Run 的 IAM 權限字串測:
curl -s -G "https://developerknowledge.googleapis.com/v1/documents:searchDocumentChunks" \
--data-urlencode "query=cloud run invoker IAM permission run.routes.invoke" \
--data-urlencode "pageSize=3" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "X-Goog-User-Project: $(gcloud config get-value project)"
撈出來的權限字串:
run.routes.invoke
run.services.create
run.services.delete
run.services.get
run.services.list
run.services.update
這種 service.resource.verb 格式的字串,是模型最容易少一個字或多一個 s 的地方,查一下比猜穩多了。
小坑記一下:skill 自己的 fallback 文件寫回應要從 documentChunks[].content 讀,
但實際回來的欄位是 results[].content。這個小出入本身就很說明問題。
連官方文件都會跟實際 API 對不上,所以「先驗證再動手」這條規則確實有用。
實測五:137 個技能怎麼做到不吃 context
finding-google-skills 解決的是另一個問題:Google 的技能目錄很大,但不可能全部預載。
它的做法是只留一頁路由表,真正要用的時候才去撈遠端目錄:
$ curl -sSL https://raw.githubusercontent.com/google/skills/main/index.json -o index.json
$ jq '.skills | length' index.json
137
$ wc -c index.json
84476
137 個技能,84KB。全塞進 context 太浪費,所以 skill 教你先用 jq 過濾再讀:
$ curl -sSL https://raw.githubusercontent.com/google/skills/main/index.json \
| jq -r '.skills[] | select((.name+" "+.description)|test("cloud run";"i")) | .name'
cloud-run-basics
cloud-run-alert-configuration
cloud-monitoring-metric-selection
google-cloud-global-frontend-configuration
...
選出最多三個最相關的,才去抓它們的 entrypoint。這個「目錄放遠端、按需載入」的模式, 我覺得是目前處理大量 skill 最合理的解法。
還有一個細節:這個 skill 明文禁止在憑證驗證失敗時用 curl -k 繞過,
連 PowerShell 的 ServicePointManager callback 都點名禁止。理由寫得很好:
「你正準備照著抓回來的東西執行指令,一份沒驗證過的目錄比沒有目錄更糟。」
五個實際用得上的場景
場景一:把 agent 接上正式環境,但只准它看不准它動
這是我最想要的一個。以前不太敢把 Claude Code 指到 production project, 因為它可能興致一來就幫你「整理」掉一批資源。有了 denylist 之後,界線變得很清楚。
幫我看一下 production 專案裡有哪些 Cloud Run 服務超過三個月沒有新的 revision
它會去 list、會 filter、會整理成表給你,但碰到 delete 就停下來問。 它省掉的是翻文件和組指令的時間,決定權還在你手上。這個分界抓得很準。
場景二:從零開一個 GCP 專案,把 LINE Bot 丟上 Cloud Run
我要開一個新的 GCP 專案部署 LINE Bot,幫我從建專案、綁帳單、開 API 到部署 Cloud Run 走一遍
google-cloud-recipe-onboarding 會把 billing → project → 啟用 API → 部署整條線帶完。
每個指令動手前先驗語法,開 API 前一定停下來問你(因為在 denylist 上)。
適合久久開一次新專案、每次都要重新 google 一輪的人。
場景三:憑證地獄——本機跑得動,上 Cloud Run 就 403
這大概是 GCP 最常見的鬼打牆。
我的服務本機跑正常,部署到 Cloud Run 之後呼叫 Vertex AI 一直 403,幫我釐清是哪個憑證的問題
google-cloud-recipe-auth 負責釐清 user credential、ADC、service account 三者的關係和適用場合,
Developer Knowledge 負責查到精確的 IAM 權限字串。這兩件事合起來,
比在 Stack Overflow 上翻五年前的答案快多了。
場景四:雲端資源盤點與帳單健檢
列出這個專案所有 Cloud Run 服務的名稱、URL 和最後部署時間,找出可能已經沒在用的
重點在前面量過的那 35 倍。沒有護欄的話,52 個服務的原始 JSON 就足以讓 agent 在真正開始分析之前,
context 已經被垃圾資料塞滿。有了 --format 投影和「先 --limit=1 探 schema」的習慣,
52 個服務只吃 2k tokens,資源再多幾倍也還撐得住。
場景五:問新功能時不要再吃到模型的舊記憶
Gemini API、Cloud Run、Firebase 這種迭代很快的產品,模型的訓練資料一定落後。
Cloud Run 現在要怎麼設定 min instances 和 startup CPU boost?
有了 Developer Knowledge,答案會附上官方文件連結和字元級的引用區間。 更重要的是查不到的時候它會直說:
Presenting recalled documentation as a retrieved result is the worst available outcome, because nothing in the reply distinguishes it from a real lookup.
「我沒查到,這是憑記憶回答的」比一個聽起來很順但是錯的 flag 有價值太多了。
小結
實測下來,讓我印象最深的其實是兩件跟功能無關的事。
第一,它整包就是 1549 行 markdown,沒有半行程式碼。 所有的安全性都靠文字規則實現:先驗語法、限制輸出、明確的 denylist、失敗時誠實說失敗。 這代表你也可以用同樣的方式,把自己團隊的 runbook 和安全規則寫成 skill: 門檻比想像中低很多。
第二,四套 manifest 擠在同一個目錄裡。 Google 沒有為 Antigravity 做專屬格式,而是讓同一包東西在 Claude Code、Codex、Gemini CLI 上都能用。 Skill 正在變成一種不綁定工具的共通格式。
如果你手上有 GCP 專案又在用 coding agent,這個 plugin 裝起來大概五分鐘。 光是不會再亂掰 flag、不會自己去動 IAM 這兩點,就夠划算了。