CLAUDE.md 你只寫過一次。半年後筆電裡有十八份,而你說不出哪一份才是對的。
這不是假設。我掃過自己的機器,結果就是這樣。以下講的是它為什麼會發生,以及那個看起來理所當然的解法為什麼解不掉。
每個代理程式都從它自己認定的路徑讀指令。
| 工具 | 路徑 |
|---|---|
| Claude Code | CLAUDE.md、~/.claude/CLAUDE.md |
| Cursor | .cursor/rules/*.mdc |
| GitHub Copilot | .github/copilot-instructions.md |
| Codex / 其他 | AGENTS.md |
你沒有決定要留四份副本。你決定的是用四種工具。副本是跟著工具一起來的。
有三種機制在製造它,沒有一種需要誰馬虎。
在用的地方就地改。 代理程式在任務中途跑掉了。你順手改掉眼前開著的那個指令檔。那個檔案只是四份裡的一份,修正也只落在那一份。
簽出目錄不是單位。 同一個儲存庫你複製了兩份 —— 一份跟著主分支,一份跟著長期分支。兩邊都帶著指令檔。只要有一邊被動過,它們當下就分家了。
家目錄裡的規則是看不見的。 ~/.claude/CLAUDE.md 不屬於任何儲存庫。它不進任何 CI。那些你不想在 code review 上爭論的規則,最後都落在這裡。
順著想下來的反應是別再留副本:AGENTS.md 只寫一次,其餘都產生出來。
這個我做了。它會動。就是 agent-fanout —— 單檔 Python,零相依套件,MIT。
python3 agent_fanout.py
create CLAUDE.md
create .cursor/rules/from-agents-md.mdc
create .github/copilot-instructions.md
產生出來的檔案都帶一行標頭,免得有人直接去改;CI 裡加上 --check,誰手動改了衍生檔,建置就亮紅燈。
這涵蓋的是這個儲存庫,而且是在有跑 CI 的地方。 聽起來像是全都涵蓋了,直到你把漏在外面的部分列出來:
預防是制度。偵測是量測。制度會以你看不見的方式被繞過去,除非你去量。
agent-drift 掃的是路徑而不是儲存庫,分組依據是內容相似度而不是檔名:
python3 agent_drift.py ~/work ~/side-projects
Scanned 47 instruction files.
DRIFT: 2 documents, 5 distinct versions between them.
claude-code:CLAUDE.md
6 copies, 3 versions
9b01aeaa204d 3 files, 406 lines
2dc3c616c279 2 files, 411 lines
在這裡用檔名比對是沒用的。互不相干的專案有不一樣的 CLAUDE.md,這本來就是對的,把這個報成偏移的工具沒人會用第二次。把它指向你整個工作目錄,而不是某一個專案 —— 有價值的結果都是跨儲存庫的那些。
| 範圍 | 它回答的問題 | |
|---|---|---|
| agent-fanout | 單一儲存庫 | 衍生檔是不是最新的 |
| agent-drift | 整台機器、多條路徑 | 副本是在哪裡分家的 |
產生消掉的是副本存在的理由。偵測抓的是那些因為你沒預料到的理由而存在的副本。只做一件,你會覺得自己蓋住了,這比知道自己沒蓋住更糟。我自己就踩過。
老實說,終點是這兩支腳本都不再需要 —— 資產不再以檔案的形式散在一台台機器上,一份審過的內容自己抵達每一台機器。這就是我在 untactit 做的事,目前尚未正式發表。
這兩支腳本不靠它。哪一部分用得上就拿哪一部分。