部落格

CLAUDE.md 在每台機器上都不一樣,不是因為誰不小心

2026年8月13日untactit

CLAUDE.md 你只寫過一次。半年後筆電裡有十八份,而你說不出哪一份才是對的。

這不是假設。我掃過自己的機器,結果就是這樣。以下講的是它為什麼會發生,以及那個看起來理所當然的解法為什麼解不掉。

副本是工具生出來的,不是你生出來的

每個代理程式都從它自己認定的路徑讀指令。

工具路徑
Claude CodeCLAUDE.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 的地方。 聽起來像是全都涵蓋了,直到你把漏在外面的部分列出來:

  • 家目錄裡的全域設定 —— 沒有儲存庫,也沒有 CI
  • 兩次產生之間的空窗 —— 檔案一改,代理程式立刻就讀到;CI 要等推送才會發現,前提是有人推送
  • 沒有 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 做的事,目前尚未正式發表。

這兩支腳本不靠它。哪一部分用得上就拿哪一部分。

本文也發在 DEV。

相關文章

你的代理在跑什麼,不必再用猜的。

連接一個工作區,大約十分鐘,團隊實際在用的每一項技能、規則與記憶就全部看得到。

免費開始 與我們談談

免信用卡,直接搭配你現有的工具。