如何跨儲存庫共享 Agent 技能並避免版本分歧
複製貼上 Agent 技能會導致各儲存庫版本悄然分歧。本文介紹如何將技能視為相依性管理,透過單一儲存庫與版本鎖定機制,確保各專案使用一致的技能版本,並建立完整的審核流程。
如何跨儲存庫共享 Agent 技能
若要跨儲存庫共享 Agent 技能,請停止複製檔案,改為採用相依性管理。請維護單一技能儲存庫,為其加上標籤(tag),並讓各專案鎖定特定標籤。接著,為每項技能新增冒煙測試(smoke test),並比照相依性更新的審核流程來審核每次的版本升級。
這包含四個部分:單一真實來源、各儲存庫的鎖定版本、各技能的冒煙測試,以及審核路徑。以下內容將說明各部分存在的原因、2026 年發布的工具如何處理這些問題,以及如何在不依賴外部服務的情況下,於自架 git 遠端伺服器上建構整套機制。
Agent 技能是一個包含 SKILL.md 檔案的資料夾,以及該技能所需的任何指令碼與參考檔案。若您對此單元感到陌生,請先閱讀 什麼是 Agent 技能以及 SKILL.md 的運作方式。本頁面將探討圍繞該單元的供應鏈管理。
技能存放位置與分享困難的原因
Claude Code 會從三個位置載入技能,技能說明文件中列出了各個路徑。
~/.claude/skills/<skill-name>/SKILL.md為個人層級。它會載入至您所有的專案中,且不會影響他人。.claude/skills/<skill-name>/SKILL.md為專案層級。任何簽出該儲存庫的人都會載入此技能。<plugin>/skills/<skill-name>/SKILL.md隨外掛程式一同發布。只要啟用該外掛程式,它就會在任何地方載入。
中間的路徑對團隊而言最為實用,因為它會被提交至版本控制,所有複製(clone)該儲存庫的人都能取得。這也是問題所在。位於 .claude/skills/ 的技能僅屬於單一儲存庫。若您有 8 個儲存庫,該技能就必須被複製 8 次。
檔案的前言(frontmatter)無法提供協助。Agent Skills 規格僅允許 6 個鍵值,若您使用了其他鍵值,發布路徑會強制列出允許的清單:
Unexpected key(s) in SKILL.md frontmatter: argument-hint. Allowed properties are: allowed-tools, compatibility, description, license, metadata, name請注意缺少的項目:其中沒有 version 鍵。檔案內沒有任何記錄能標示哪個副本較新。這很合理,因為技能本質上是文件而非套件。這確實意味著版本控制必須由檔案所在的層級來處理,而該層級的管理正是您的職責。
問題一:八份副本悄然分歧
複製貼上在第一天運作正常。到了第六十天就會失效。有人修正了 payments 儲存庫中的錯誤指令,卻未更動其他七份副本。另一個人則在 orders 中新增了關於分頁的規則。現在,同一個技能名稱會根據代理程式啟動所在的目錄,產生兩種不同的審查結果,而開發人員對此一無所知。
這種失敗是靜默的,因為不存在錯誤狀態。技能本質上是散文。過時的指令會產生自信但錯誤的答案,這類錯誤代價高昂。代理程式中沒有任何機制會比對你的副本與其他人的差異,因此唯一的訊號就是有人發現兩個儲存庫的內容不一致。
問題二:版本未鎖定
即使團隊將技能集中在同一處,常見的共享方式仍是複製步驟:安裝腳本、說明文件中的 curl 指令,或是同步資料夾的 shell alias。這些方法都會安裝當前分支最新版本的內容。
這意味著兩位開發者即使在同一個應用程式的相同 commit 上,也可能因為在不同日期執行同步,而運行不同的指令。這也導致在發生錯誤的代理執行後,無法回答關鍵問題:究竟是哪個版本的技能產生了此結果?若無記錄修訂版本,執行結果便無法重現,導致錯誤報告無法處理。
問題三:技能失效卻無人察覺
技能沒有編譯器。它是一組針對模型的指令,因此即使檔案內容完全未變,技能仍可能失效。模型升級會改變模型對長指令的遵循程度;技能所呼叫的命令列工具可能會變更旗標名稱;參考檔案中的 URL 可能會回傳 404 錯誤,導致代理程式誤將錯誤頁面內容當作回應來源。
在上述情況中,系統都不會發出明顯的失敗警示。代理程式依然會給出回應,只是回應品質較上個月下降。這種細微的品質衰退,在每次僅進行單一 Pull Request 的開發流程中極難察覺。
2026 年發布的工具解決了什麼問題
目前已有數種解決方案,但對於版本資訊應存放於何處,各方意見尚未統一。
鎖定檔 (Lockfiles)。 來自 Vercel Labs 的 skills 命令列工具(參見 vercel-labs/skills,採用 MIT 授權,截至 2026 年 8 月 5 日版本為 v1.5.22)能將技能從 git 儲存庫安裝至代理程式指定的目錄,且支援超過 70 種代理程式的配置格式。npx skills add <repo> 用於安裝,npx skills update 用於升級,npx skills list 則用於檢視已安裝項目。目前的安裝紀錄是按使用者而非按儲存庫儲存,該專案目前有一項待處理請求(issue 283),要求新增 skills install 指令,以便從鎖定檔重新安裝所有已追蹤的技能,確保第二台機器能擁有完全相同的環境。該請求可視為目前的進度報告。鎖定檔的概念已定案,但針對「每個專案」的實作部分仍在開發中。
規格與測試。 SkillSpec 採取了不同的切入點。它將 SKILL.md 視為一份需驗證的合約,而非僅供參考的說明文件,其目標是讓技能具備「可追蹤、可測試與可驗證」的特性。skillspec doctor <path> 會回報代理程式可能中斷執行緒的位置。skillspec boundary map <path> 會回報該技能可存取的範圍,skillspec boundary assess <path> 則會根據風險對這些發現進行排序。這是一個以 Rust 編寫的 crate,採用 MIT 或 Apache 2.0 雙重授權,截至 2026 年 7 月 29 日版本為 0.2.2。請安裝指定版本而非最新版:
cargo install skillspec --version 0.2.2 --locked
skillspec --version--locked 會使用該 crate 發布時的相依套件版本進行建置,確保建置過程不會因版本漂移而失效。skillspec --version 應輸出 0.2.2。若顯示其他數字,代表您的 PATH 中有更舊的二進位檔優先被執行。
供應商實務。 Google 在 google/skills 的文章 如何建置、測試並擴展代理程式技能 中描述了其建置方式。撇開規模不談,其機制本質上就是一般的持續整合 (CI)。每項技能在合併前都必須通過針對 frontmatter 中繼資料、程式碼行數、目錄結構與命名規範的 linter 檢查。連結檢查器若發現任何回傳 404 的 URL 就會導致建置失敗,這能有效攔截代理程式虛構出的合理連結。作者必須隨技能提供評估提示詞套件與評分標準。排程評估作業會每週針對整個函式庫執行以偵測回歸問題,且每項技能皆有指定負責人,當品質下降時,負責人需負責修復。
三種解答背後的模式
您不必從中擇一。這些解答的底層是一個單一架構,而標準的 git 即可提供完整功能。
- 單一事實來源。該技能僅有一個歸屬地,每個儲存庫皆參照該歸屬地,而非儲存副本。
- 每個儲存庫鎖定特定版本。每個專案都會記錄其使用的確切修訂版本,因此升級動作即為該專案中包含作者與日期的一次 commit。
- 每個技能執行冒煙測試。透過一個可執行的檢查,證明該技能仍能產生預期的結果。
- 審查路徑。對共享技能的變更必須經過審查,且每個使用者在採用前都能看到差異比對(diff)。
這就是依賴關係的架構。技能成為共享產物的速度快於圍繞其發展的工具,因此,您現有且信任的工具即為最安全的選擇。
適用於小型團隊的自架 Git 遠端儲存庫配置
單一儲存庫存放所有技術文件。該儲存庫不包含其他內容,因此其提交歷史即為一份指令變更日誌。
agent-skills/
skills/
api-review/
SKILL.md
release-notes/
SKILL.md
tests/
api-review.sh
release-notes.sh
CHANGELOG.md軟體發布以標籤(tags)管理。請使用附註標籤(annotated tags),因為它們包含訊息與日期。請在訊息中說明使用者需要升級的原因:
git tag -a v1.4.0 -m "api-review: require pagination on list endpoints"
git push origin v1.4.0無論您的遠端伺服器是 Gitea、Forgejo、GitLab,或是透過 SSH 連線至 VPS 上的裸儲存庫(bare repository),以下內容皆適用。此處的所有操作僅涉及 git 與符號連結(symlink)。
使用 git submodule 進行鎖定
submodule 會在您的儲存庫中記錄另一個儲存庫的特定 commit。該記錄即為鎖定(pin)。在每個使用該模組的專案中:
git submodule add https://git.example.com/team/agent-skills.git vendor/agent-skills
git -C vendor/agent-skills fetch --tags
git -C vendor/agent-skills checkout v1.4.0
mkdir -p .claude/skills
ln -s ../../vendor/agent-skills/skills/api-review .claude/skills/api-review
git add .gitmodules vendor/agent-skills .claude/skills/api-review
git commit -m "Pin shared agent skills to v1.4.0"符號連結(symlink)是實現此功能的關鍵。專案層級的 skill 項目可以是指向磁碟其他位置目錄的符號連結,Claude Code 會追蹤該連結並讀取目標位置的 SKILL.md。因此,該 skill 會以一般專案 skill 的形式載入,而實際的位元組則儲存在您所選定 commit 的 submodule 中。
檢查鎖定狀態:
git submodule status正常的輸出列開頭為一個空格,接著是 commit、路徑,最後是最近的標籤(tag):
4d1a7c2f0b93e5a1c8d6f2b40e7a95c3d1f8b602 vendor/agent-skills (v1.4.0)開頭若為 -,表示該 submodule 未經初始化,因此 .claude/skills/api-review 指向空值,且該 skill 會在無提示的情況下無法載入。請執行 git submodule update --init 來修正此問題。開頭若為 +,表示目前簽出的 commit 與記錄的版本不符,這代表該開發者正在執行其他人未曾見過的指令。新複製的儲存庫需要執行 git clone --recurse-submodules,且此指令應寫入 README 中,因為一般的 clone 指令會使 vendor/agent-skills 保持為空且不會顯示任何錯誤訊息。
升級是經過審慎考量的行為,這正是此機制的重點所在:
git -C vendor/agent-skills fetch --tags
git -C vendor/agent-skills diff v1.4.0 v1.5.0 -- skills/
git -C vendor/agent-skills checkout v1.5.0
git add vendor/agent-skills
git commit -m "Bump shared agent skills to v1.5.0"diff 這一行是審查路徑。它顯示了其他所有使用該儲存庫的專案將會看到的相同變更,且適合放入 pull request 中。
改用外掛市集進行鎖定
若您不想要求每位開發者都學習使用 submodules,Claude Code 的外掛系統可為您處理發布作業,且適用於自架的遠端儲存庫。請在技能儲存庫的 .claude-plugin/marketplace.json 放置目錄檔案:
{
"name": "acme-agents",
"owner": { "name": "Platform team", "email": "platform@example.com" },
"plugins": [
{
"name": "team-skills",
"description": "Shared review and release skills",
"version": "1.4.0",
"source": {
"source": "url",
"url": "https://git.example.com/team/agent-skills.git",
"ref": "v1.4.0",
"sha": "4d1a7c2f0b93e5a1c8d6f2b40e7a95c3d1f8b602"
}
}
]
}此處涉及兩個不同的來源,混淆兩者是常見的錯誤。市集來源(即獲取目錄本身的來源)僅接受 ref 指定分支或標籤,不接受 sha。目錄內部的外掛來源則兩者皆可接受;若兩者皆有設定,則以 sha 為準。因此,確切的 commit 鎖定應設定在目錄項目中。
接著,每個取用該技能的儲存庫需在已提交的 .claude/settings.json 中宣告此市集:
{
"extraKnownMarketplaces": {
"acme-agents": {
"source": {
"source": "url",
"url": "https://git.example.com/team/agent-skills.git",
"ref": "v1.4.0"
}
}
},
"enabledPlugins": {
"team-skills@acme-agents": true
}
}當團隊成員信任該專案資料夾時,系統會提示其安裝市集,外掛將自動啟用,無需透過 wiki 頁面說明操作步驟。隨後,技能將回應 /team-skills:api-review,因為外掛技能是以其名稱進行命名空間隔離,不會與同名的專案技能發生衝突。在您推送新的標籤後,使用者可透過 /plugin marketplace update acme-agents 重新整理,若安裝摘要有要求,則執行 /reload-plugins。
為單一技能編寫冒煙測試
冒煙測試是針對具有已知錯誤的測試裝置(fixture)所執行的腳本化代理程式,並包含一項斷言。Claude Code 透過 -p 以非互動方式執行,使用者呼叫的技能亦可在此運作:將 /skill-name 置於提示字串中,它會在執行開始前展開。
#!/usr/bin/env bash
set -euo pipefail
claude -p "/api-review Read fixtures/orders-api.md and list the rule ids it breaks." \
--allowedTools "Read" \
--output-format json \
--json-schema '{"type":"object","properties":{"rule_ids":{"type":"array","items":{"type":"string"}}},"required":["rule_ids"]}' \
| jq -e '.structured_output.rule_ids | index("pagination-required")' > /dev/nullfixtures/orders-api.md 是一個包含一個刻意錯誤的短檔案。斷言的內容是該技能必須指出此錯誤。當篩選器產生 null 時,jq -e 會以非零值退出,因此若技能停止捕捉該預設錯誤,腳本即會失敗。claude 本身在執行失敗時會以非零值退出,而 set -euo pipefail 則會將任何失敗轉變為測試失敗。
模型在不同執行間會重寫其回答,因此切勿對整個句子進行斷言。請針對技能應輸出的識別碼,或您所要求架構中的某個欄位進行斷言,並保持測試裝置精簡,以降低執行成本。
在 CI 中,請加入 --bare。若無此參數,claude -p 會載入與互動式工作階段相同的內容,包含來自執行機器上的掛鉤(hooks)、外掛程式以及 CLAUDE.md,這可能導致同事的個人設定影響測試結果。裸機模式(bare mode)會跳過所有自動探索,這意味著它也會跳過您正在測試的技能,因此請務必明確載入該技能。裸機模式也不會讀取您的訂閱登入資訊,因此請先在環境變數中設定 ANTHROPIC_API_KEY:
claude --bare -p "/team-skills:api-review Read fixtures/orders-api.md and list the rule ids it breaks." \
--plugin-dir vendor/agent-skills \
--allowedTools "Read" \
--output-format json透過 --output-format stream-json,執行的第一個事件會回報已載入的外掛程式,並針對未載入的外掛程式提供一個 plugin_errors 陣列。若 plugin_errors 不為空,請讓 CI 作業失敗。這能捕捉到指向已不存在之修訂版本的鎖定(pin),否則該情況會表現為代理程式默默忽略您的內部規則。
共享技能即為可執行指令
兩項功能使上述定義成為現實,且當檔案來自其他團隊時,這兩點至關重要。
首先,SKILL.md 可以在模型讀取任何內容前執行 shell 指令。在主體中加入如下行即為前處理:
- Current branch: !`git rev-parse --abbrev-ref HEAD`該指令會在載入技能的機器上執行,其輸出會取代模型接收到的文字中的預留位置。以三個反引號後接 ! 開啟的區塊,能以相同方式執行多條指令。執行期間不會有任何審核機制。讀取共享技能即代表讀取其指令替換內容。
其次,前言(frontmatter)可以預先核准工具。allowed-tools 會授權所列工具,且在呼叫該技能的對話中不會出現權限提示。對於專案技能,一旦使用者接受該資料夾的 workspace trust 對話框,此授權即生效。Claude Code 文件明確指出其後果:在信任儲存庫前請務必審查專案技能,因為技能可能會自行授予廣泛的工具存取權。
因此,處理技能更新應比照相依套件更新。只要機制允許,請鎖定至確切的 commit,因為標籤(tag)可以被移動,而分支(branch)定義上本就會變動。在受限的機器上,設定中的 "disableSkillShellExecution": true 會將所有指令替換改為顯示字面文字 [shell command execution disabled by policy],而非實際執行;若透過受管設定套用,使用者將無法覆寫此項。內建與受管技能不受此設定限制。
同樣的謹慎態度也適用於技能讀取的內容。執行 env 或開啟設定檔的技能,會將找到的任何內容拉入模型的 context 中,這正是 避免將機密洩漏給您執行的代理程式 中所涵蓋的失敗案例。抓取網頁或執行查詢的技能,則是將相同的暴露風險指向外部,因為擷取到的文字進入 context 後,看起來會與您撰寫的指令完全相同。在您 將代理程式指向您自己的 SearXNG 執行個體進行網頁搜尋 之前,建議先閱讀關於此邊界條件的說明。
版本更新時的檢查重點
- 檢查每個
SKILL.md主體的差異(diff),因為該內容即為您的代理程式將遵循的指令。 - 檢查所有指令替換(command substitution),因為這些指令會在技能載入時於您的機器上執行。
- 檢查對
allowed-tools的任何變更,因為該行設定會直接授予工具存取權限而無需提示。 - 檢查標籤(tag)背後的測試執行結果。若共享儲存庫在 CI 中執行自有的冒煙測試(smoke tests),您所鎖定的標籤應具備綠色的測試通過紀錄。
若審閱者無法在 10 分鐘內讀完所有差異,代表該技能已過於龐大。請將其拆分。同樣的原則也適用於代理程式讀取的儲存庫文件:請將持久性規則保留在 AGENTS.md 與 HUMAN.md 拆分 中描述的檔案內,並將架構邏輯記錄在 專為代理程式編寫的 DESIGN.md 中,讓技能維持在狹窄且具體的程序。
當模型或工具變更導致技能失效
即使未經編輯,技能底層的環境仍可能發生變動。模型升級會改變其遵循長指令的可靠性,導致原本能執行到第九步驟的技能可能中斷。命令列工具若重新命名旗標,代理程式會執行舊旗標、讀取錯誤訊息並嘗試即興修正。若參考的 URL 回傳 404 錯誤,也會導致失敗。代理程式的調度機制若改變了技能選擇邏輯,原本能勝出的 description 可能不再被選中。當程序開始提前終止時,單純的版本更新無法解決問題,指令本身需要具備強制執行最後步驟的結構,這正是 unlazy skill 與其 Depth Tree 方法 背後的設計思路。
這就是為什麼在此架構中,冒煙測試(smoke test)至關重要。請排程執行每項技能的測試,並在每次推送程式碼時同步觸發。Google 基於此原因,每週針對整個函式庫執行評估作業;對於擁有十項技能的團隊而言,在小型 VPS 上設定每週一次的 cron job 即已足夠。這是開發者察覺損壞前,唯一能獲取通知的管道。
可攜性也有所幫助。Agent Skills 規範將前言(frontmatter)限制為六個鍵值,因此符合該規範的技能可載入至您編寫時所用的工具以外的環境;反之,您新增的每個特定於調度工具的鍵值,都是對單一供應商的押注。編寫能適應模型更換的技能是一門專業,相關內容請參閱 讓技能在任何模型上運作。
FAQ
如何在多個儲存庫之間共用代理程式技能?
將技能放入專屬的 git 儲存庫,並為其標記版本(tag),讓每個使用的專案參照該標記,而非複製檔案。有兩種機制可行。git submodule 可記錄確切的 commit,透過從 .claude/skills/<name> 建立符號連結(symlink)至該 submodule,即可將其視為一般專案技能載入。外掛市集(plugin marketplace)則透過 /plugin 達成相同目的,並在消費端儲存庫的 .claude/settings.json 中宣告鎖定版本。兩者皆會將版本資訊寫入 git 歷史紀錄,以便追蹤特定代理程式執行時所使用的指令版本。
我可以將代理程式技能鎖定在特定版本嗎?
無法直接在 SKILL.md 內部執行,因為該 frontmatter 沒有 version 鍵值。鎖定版本必須由檔案外部的層級處理。git submodule 設計上即會鎖定確切的 commit。在 Claude Code 外掛市集中,外掛來源接受 ref 指定分支或標記,以及 sha 指定確切 commit;若兩者同時存在,則以 sha 為準。市集來源本身僅接受 ref。建議優先使用 commit 鎖定,因為標記在審核後仍可能被移動。
技能冒煙測試(smoke test)應該驗證什麼?
請驗證穩定的項目。在非互動模式下,針對包含已知錯誤的測試夾具(fixture)執行技能,接著檢查輸出中是否出現特定識別碼,例如該技能應回報的規則 ID。透過 --output-format json 與 --json-schema 要求結構化輸出可使檢查更精確,若數值缺失,jq -e 會導致腳本失敗。切勿驗證完整句子,因為模型在不同執行間可能會改寫回答。
安裝其他團隊儲存庫的共用技能安全嗎?
請將其視為程式碼相依性,因為它屬於可執行指令。SKILL.md 可透過 ! 指令替換形式在載入時執行 shell 指令,而 frontmatter 的 allowed-tools 欄位可在未經提示下預先核准工具。請在每次版本更新時閱讀差異(diff),鎖定確切的 commit 而非分支,並優先使用貴團隊可控的來源。在受管機器上,設定中的 "disableSkillShellExecution": true 可完全禁止執行指令替換。
共用技能能在 Claude Code 以外的代理程式運作嗎?
這取決於您使用的 frontmatter。Agent Skills 規範定義了六個鍵值:name、description、license、compatibility、metadata 與 allowed-tools。僅限於這些鍵值的技能可在實作該規範的工具中載入,且無需修改即可在 Claude Code 中運作。特定於執行環境(harness-specific)的鍵值與超出規範的內容功能將會被忽略或拒絕,因此若您打算廣泛共用技能,請避免使用這些功能。