weken.news
claude codecontext 管理agent 工程memoryprompt engineering

Claude Code 記憶肥大實測:吃掉 context 的不是 memory,是 rules(我數了 1067 行)

直接回答

Claude Code 吃掉開場 context 的通常不是 memory 而是 rules。實測我自己的設定:每次開場固定載入 1067 行,其中 rules 佔 779 行、CLAUDE.md 187 行、MEMORY.md 索引只佔 101 行,而 384 個檔案、2.7MB 的 memory 資料夾因為是索引加按需讀取,開場一行都不佔。解法是速記加全文分離:規則本體留在常載檔,來源故事、完整對照表、正反例搬到觸發時才讀的全文檔。三份檔案實測從 368 行降到 51 行,常載 rules 從 779 行降到 462 行,內容零丟失。

週末哥 ·

看到一則討論在問:大家都怎麼防止記憶 md 肥大。底下 80 則留言,講的大多是分層、路由、主檔只當索引、重複流程抽成 skill。

這些我 2 個月前就做完了。所以我沒急著回,先做一件更基本的事:把我自己的設定實際數一遍。

數完發現,我一直在防的地方,根本不是肥的地方。

先分清楚:哪些是開場全載,哪些是按需讀

這是整件事的關鍵,也是最多人搞錯的地方。

Claude Code 的設定檔分兩種載入方式。一種是每次開場無條件塞進 context,另一種是需要的時候才去讀。防肥大只需要管第一種。

我的實際數字:

CLAUDE.md 187 行,每次全載。 rules 資料夾常載的 15 份,779 行,每次全載。 MEMORY.md 索引 101 行,每次全載。 合計 1067 行。

然後是重點:我的 memory 資料夾有 384 個檔案、2.7MB,開場佔 0 行。因為 MEMORY.md 只是一頁式索引,每條記憶一行標題加一句提要,其他檔案問到才撈。

實測 Claude Code 設定:常載 1067 行中 rules 佔 779 行、CLAUDE.md 187 行、MEMORY.md 索引 101 行。memory 資料夾 384 檔 2.7MB 因為採索引加按需讀取,開場佔 0 行。

所以「防止記憶 md 肥大」這個題目本身就問偏了。memory 只要做成索引,它多大都不佔開場。我 2.7MB 的記憶躺在那裡完全沒有成本。

真正每次開場無條件全載的,是 rules 的 779 行。那才是要動刀的地方。

同一個資料夾裡,兩種寫法差 16 倍

繼續往下數,發現更尷尬的事。

我的 rules 資料夾裡,同時存在兩種完全不同的寫法:

threads-writing.md,10 行。內容是 6 條底線速記,加一行「寫 Threads 前先讀全文,路徑在這」。 communication.md,165 行。整份全文常駐,包含每條規則的來源故事、20 幾個禁用詞的完整對照表、正反例。

同一個資料夾,同一個人寫的,差 16 倍。

瘦身的做法我早就發明出來了,也在 5 份檔案上用了。我就是沒把它套到最肥的那幾份。

這件事本身有點好笑:我的 meta-bias 規則裡第 4 條寫的就是「規則寫了不代表會生效,每次要主動想起來才會用」。而那條規則,正躺在一份 123 行、從來沒被自己套用過的檔案裡。

判斷標準:這條規則的觸發是什麼

真正卡住我的不是怎麼壓縮,是「哪些能壓,哪些不能」。

我看到有人主張全部搬走,開場什麼都不載,問到才撈。這對一半。

分界線是:這條規則的觸發是什麼。

有明確觸發詞的規則,可以拆。寫 Threads 貼文前才要知道字數限制,改 CSS 前才要知道 box model 怎麼算。這種常載只留速記加路徑,觸發到再讀全文,一行成本都不浪費。

沒有觸發詞的規則,不能拆。「不准用某個符號」的觸發是每一則訊息,「訊息進來先回應」的觸發是每一次接收。這種規則如果搬到「問到才撈」,等於沒有規則,因為它永遠不會被問到。

但它們還是能瘦。因為一條規則裡有兩種東西:

要執行的(做什麼、不做什麼、送出前檢查什麼)。 要查的(這條為什麼存在、完整對照表、當初踩了什麼坑)。

第一種必須常駐,第二種是給查的,不是給載的。

規則拆分判斷標準:有明確觸發詞的(寫某類貼文前、改某類程式碼前)改成速記加全文分離;沒有觸發詞、每則訊息都要跑的,規則本體留常載,只把來源故事與完整對照表搬到全文檔。

實測結果:368 行變 51 行,內容零丟失

按這個標準動手,三份最肥的檔案:

communication.md:165 行變 14 行。8 條規則全留,每條壓成一句可執行的指令,來源故事和完整禁用詞表搬到全文檔。 meta-bias-classification.md:123 行變 28 行。5 個偏見和它們的剎車條件全留,案例敘事搬走。 iteration-discipline.md:80 行變 9 行。規則加品檢三關全留,2 個月前那次爆氣的案例搬走。

368 行變 51 行。常載的 rules 從 779 行降到 462 行。

做法很單純,但順序不能反:先把整份原文複製到全文資料夾,跑 diff 確認兩邊一模一樣,確認完才回頭改常載那份。先砍再說「應該有備份」就是在賭。

每份速記的開頭第一行寫清楚兩件事:全文在哪,什麼時候該去讀。少了第二句,那份全文等於死檔,因為沒有人知道什麼時候該打開它。

沒做的事:向量資料庫

那串留言裡有幾個人建議上 RAG、裝向量資料庫、把記憶全部 token 化。

我沒做,因為規模對不上。他們有 90 萬字的 markdown,我的整個記憶庫 2.7MB。向量檢索解的是「量大到關鍵字查不到」的問題,我現在還沒有那個問題。

判斷時機很簡單:等驗收題開始查不到東西,再升級。在那之前,索引加關鍵字檢索夠用,而且沒有多一層依賴要維護。

回頭看,這件事真正的教訓不是「記憶要分層」,那是常識。是我花了 2 個月防守一個不存在的問題,而真正的肥點就躺在隔壁資料夾,用著我自己發明、卻沒套完的解法。

先量,再修。憑感覺挑的那個,通常不是它。

常見問題

Claude Code 的 memory md 肥大怎麼辦?
先量再修,不要憑感覺砍。多數人以為肥的是 memory,但 memory 只要做成一頁式索引加按需讀取,實際佔開場的就只有索引那幾十行。我的 memory 資料夾有 384 個檔、2.7MB,開場佔 0 行,因為 MEMORY.md 只有 101 行索引,其他檔案問到才撈。真正每次開場無條件全載的是 CLAUDE.md 和 rules 資料夾,那才是要動刀的地方。
CLAUDE.md、rules、memory、skills 差在哪,各該放什麼?
差在載入時機。CLAUDE.md 每次開場全載,只放跨情境的硬規則和高層路由,越薄越好。rules 資料夾預設也是全載,但可以加 paths 設定變成只在特定路徑載入,適合放主題型規則。skills 完全按需召喚,適合多步驟流程。memory 靠索引載入加按需讀取,適合放具體踩坑和專案脈絡。判斷順序:always-on 的走 CLAUDE.md 或 rules,多步驟流程走 skill,特定情境的學習走 memory。
規則要不要拆成速記加全文兩份?判斷標準是什麼?
看這條規則的觸發是什麼。有明確觸發詞的(例如寫 Threads 貼文前、改 CSS 前),拆:常載只留 5 到 10 行底線速記加一行全文路徑,觸發到才讀全文。沒有觸發詞、每一則訊息都要跑的(例如不准用某個符號、訊息進來先回覆),規則本體必須留在常載,不能改成觸發才讀,但它的來源故事、完整對照表、正反例可以搬走。我實測這樣拆,一份 165 行的規則剩 14 行,該擋的還是擋得住。
Claude Code 記憶管理需要用 RAG 或向量資料庫嗎?
多數個人使用者不需要。向量資料庫解的是「幾十萬字、關鍵字查不到」的問題,如果你的知識庫是幾 MB 的 markdown,grep 加一份關鍵字索引就能撐很久,而且沒有額外依賴。判斷時機:等驗收題開始查不到東西再升級,不要一開始就裝。我的 memory 是 2.7MB,目前用索引加關鍵字檢索完全夠。
檔案大小可以直接當 token 用量的指標嗎?
不能直接換算,但是同趨向的指標。中文一個字通常吃掉的 token 比一個英文單字多,實際數字要看 tokenizer。實務上用行數和檔案大小挑「值得檢查的檔案」很有效,但不要拿它當「這個該砍」的證據,還是要看那份檔案是不是每次開場都載、內容是不是查的時候才需要。