MapleCheng

在浩瀚的網路世界中無限潛水欸少年郎!

0%

用 Git Submodule 管理 AI Coding Agent 的設定檔,跨專案共用不再複製貼上

最近在整理公司 monorepo 裡 AI coding agent 的設定結構,一個看似簡單的「搬檔案」動作,結果搞了快兩天才定案。但搞完之後回頭看,覺得這個架構值得記錄下來——因為我相信很多團隊正在、或即將遇到一樣的問題。

問題的起點:設定檔開始失控

如果你在用 Claude Code 之類的 AI coding agent,你一定知道專案根目錄下會有一個 .claude/ 資料夾,裡面放著各種設定:

  • skills/:技能定義,告訴 agent 怎麼做特定事情(像是 commit 格式、code review 規範)
  • commands/:自訂指令,讓你在 CLI 裡直接呼叫特定流程
  • agents/:獨立角色 agent,每個有自己的系統提示和行為邊界

一開始一切美好。你在一個專案寫好 skill,agent 就乖乖照做。

但問題來了——當你有五個、十個專案,而且它們共用同一套開發規範的時候怎麼辦?

你開始複製貼上。

第一次複製,沒問題。第二次,小改一下也還行。到第五次的時候,你已經忘了哪個版本是最新的。然後某天你在 A 專案改了 commit 規範,B 專案還是舊的,C 專案改了一半⋯⋯

對,這就是經典的「config drift」問題,只是這次的主角不是 Kubernetes YAML,而是 AI agent 的設定檔。

解法:Git Submodule

想了幾個方案之後,最後選了 git submodule。原因很直覺:

  • 這些設定檔本身就是純文字 + markdown,適合 git 管理
  • 每個「技能包」可以是獨立 repo,有自己的版本歷史
  • 主專案只記錄「我要用哪個版本」,不用管內容
  • 更新的時候 git submodule update 一行搞定

具體做法是把原本直接放在 .claude/skills/.claude/commands/ 裡的內容,拆成獨立的 git repo,然後在主專案裡用 submodule 引入。

1
2
3
4
5
# 把 common commands 加為 submodule
git submodule add git@gitea.example.com:Library/commands-common.git .claude/commands/common

# 把 team workflow agents 加為 submodule
git submodule add git@gitea.example.com:Library/agents-team-workflow.git .claude/agents/team-workflow

其他專案要用?一樣加 submodule 就好:

1
2
cd ~/Projects/另一個專案
git submodule add git@gitea.example.com:Library/commands-common.git .claude/commands/common

從此只有一個 source of truth。改了 commands-common,所有專案 git submodule update --remote 就同步了。

Skills vs Agents:搞清楚本質差異

搬的過程中遇到一個有趣的問題:原本有一組「團隊開發流程」的設定,一開始放在 skills/ 裡。但搬的時候越看越不對——它的內容不是在教 agent「怎麼做某件事」,而是在定義「你是誰、你的職責是什麼」。

這兩者的差別很關鍵:

Skill(技能)是知識導向的。它告訴 agent:

  • commit message 的格式規範是什麼
  • code review 要檢查哪些項目
  • 特定框架的 API 怎麼用

Agent(角色)是身份導向的。它定義:

  • 你是 BA、架構師、開發者、還是 QA?
  • 你的決策權限到哪裡?
  • 你應該產出什麼交付物?
  • 你跟其他角色怎麼協作?

舉個例子,我們的團隊開發流程定義了五個角色:

  • BA(業務分析師):負責需求分析,產出功能規格
  • Architect(架構師):負責技術設計,產出架構決策
  • Developer(開發者):負責實作,遵守 coding standard
  • Reviewer(審查者):負責 code review,確保品質
  • QA(測試工程師):負責測試策略,驗收結果

這些東西放在 skills/ 裡語意不對。它們不是「技能」,是「人格」。所以最後搬到了 .claude/agents/ 下面,每個角色一個 .md 檔案,用 YAML frontmatter 定義角色的基本屬性。

1
2
3
4
5
6
.claude/agents/team-workflow/
├── ba.md
├── architect.md
├── developer.md
├── reviewer.md
└── qa.md

這樣做的好處是,在 Claude Code 裡你可以直接指定要用哪個「角色」來處理當前任務。不同角色有不同的關注點和決策框架,比起一個萬能 agent 來得精準。

最終結構

折騰完之後,.claude/ 目錄長這樣:

1
2
3
4
5
6
7
8
.claude/
├── commands/
│ └── common/ ← submodule:共用指令(commit, format, review)
├── agents/
│ └── team-workflow/ ← submodule:團隊角色(ba, architect, developer, reviewer, qa)
├── skills/
│ └── (專案特有的技能放這裡)
└── settings.json

三層分類的邏輯:

  • **commands/**:觸發動作(「做這件事」)
  • **agents/**:角色定義(「當這個人」)
  • **skills/**:領域知識(「知道這些事」)

其中 commands 和 agents 是 submodule(跨專案共用),skills 裡放的是專案特有的知識(像是特定 DB schema、業務邏輯說明),不需要共用。

實際踩到的坑

1. Submodule 路徑要對

Claude Code 認的是相對路徑。如果你的 submodule 路徑不在 .claude/ 底下,agent 可能找不到。確保 git submodule add 的目標路徑是正確的相對位置。

2. 刪除舊 submodule 不是刪目錄就好

Git submodule 的刪除步驟永遠比你想的多:

1
2
3
git submodule deinit -f .claude/skills/舊的
git rm -f .claude/skills/舊的
rm -rf .git/modules/.claude/skills/舊的

少做任何一步都會留下幽靈紀錄,下次 git submodule update 就會鬧你。

3. Commit message 格式要統一

我們的專案規範是 <type>: <subject>(繁體中文主題),但 submodule 搬遷的 commit 一開始寫成了帶 scope 的格式(build(agents): ...)。這種小事通常不重要,但在團隊裡格式不一致會慢慢累積成技術債。

4. 測試 agent 能不能認到

搬完之後一定要測。在 Claude Code 裡確認每個 agent 都能被正確載入。我們五個角色搬完後全部測試通過,但如果你的 frontmatter 格式不對(少了必要欄位),agent 會安靜地消失——不會報錯,就是不見了。

什麼時候該用這個架構?

老實說,如果你只有一兩個專案,直接把設定檔放在 .claude/ 裡就好,不需要搞 submodule。過度工程化是另一種病。

但如果你符合以下任何一條,就值得認真考慮:

  • 超過三個專案共用同一套開發規範
  • 團隊裡有多人在調整 agent 設定
  • 你已經在複製貼上 skill 檔案,而且開始搞不清楚哪個是最新版
  • 你想要版本控制 agent 的行為變更(誰改了什麼、什麼時候改的)

寫在最後

AI coding agent 的設定管理是一個很新的問題。現在大多數人還在「一個專案一份設定」的階段,但隨著 agent 能力越來越強、使用場景越來越多,設定檔的管理複雜度會指數成長。

用 git submodule 不是唯一解——你也可以用 npm package、symlink、甚至寫個腳本去同步。但 submodule 的好處是零依賴、零額外工具,純 git 操作就搞定。

如果你也在煩惱 AI agent 設定怎麼跨專案管理,希望這篇能給你一些靈感。至少你知道,你不是唯一一個在搞這種事的人 😂