examhub .cc 用最有效率的方法,考取最有價值的認證
Vol. I
本篇導覽 約 32 分鐘

大型 Codebase 探索的 Context 管理

6,400 字 · 約 32 分鐘閱讀

大型程式碼庫探索的 Context Management 是 Claude Certified Architect — Foundations(CCA-F)考試 Domain 5.4 的核心主題。任務說明 5.4——「在大型程式碼庫探索中有效管理 context」——是 Context Management & Reliability 領域(佔比 15%)六項任務之一,但其架構影響力延伸至六個評分情境中的三個:Code Generation with Claude Code、Developer Productivity with Claude,以及 Claude Code for Continuous Integration。任何觸及真實程式碼庫(數萬個檔案、數百萬行程式碼、數百個模組)的 Claude Code 部署,在執行第一個自主任務時,若 agent 不刻意選擇要讀取哪一塊程式庫、以何種順序、何種粒度,以及哪些留在磁碟不讀,context window 就會超出兩到三個數量級。任務 5.4 就是訓練這種紀律的主題。

這份學習筆記涵蓋 CCA-F 考生在架構層級須具備的大型程式碼庫探索 Context Management 完整面向:為什麼整個程式碼庫無法放入 context window、lazy-loading 原則如何主導工具選擇、規範的 Glob → Read pipeline、symbol 驅動探索的 Grep-first 方法、將狀態外部化的 scratchpad file 模式、遞進式相依圖譜映射紀律、選取進入點與設定檔(而非隨機瀏覽檔案)的優先排序啟發法、丟棄已萃取檔案內容的 context hygiene、跨 session 持續存在的高層 repo map、讀取大型檔案前的 context budget 追蹤、供後續參考的逐檔筆記,以及考試常見的 Grep vs Glob 混淆與全檔讀取陷阱。本主題刻意不重複任務 5.1 的對話 context 內容(該任務聚焦案例事實區塊、漸進式摘要風險,以及對話式 agent 的迷失中段效應),而是專注於程式碼庫特有的機制:Explore agent 模式、Grep、Glob、Read、階層式讀取策略、scratchpad files,以及 Claude Code 內建工具介面。

大型程式碼庫挑戰 — 整個程式碼庫超出 Context Window 數個數量級

生產環境的程式碼庫並不是 Claude 可以直接讀入的文件。一個有 2,000 個檔案、每個檔案平均 200 行的小型微服務程式碼庫,包含行號、import 和注解後,就已超過四百萬個 token——比任何 Claude context window 大了數個數量級。即使是相對集中、只有 300 個檔案的服務,通常也會達到數十萬 token。大型程式碼庫探索的 Context Management 從一個公理出發:你無法讀取所有內容,因此架構問題從來不是「如何把程式碼庫塞進 context」,而是「如何讀取最少的切片,讓 Claude 能做出下一個正確的動作」。

考試把這個公理視為不可妥協的前提。任何提出「載入整個程式碼庫」、「遞迴讀取所有檔案」或「把整個程式碼庫串接成單一 context prompt」的選項,無論周圍包裹多少支撐文字,都是干擾選項。CCA-F 的 Code Generation with Claude Code 情境尤其是圍繞這個陷阱設計的:直覺上伸手做批量讀取的考生,在選擇性的 symbol 驅動探索才是正確答案的題目上就會落敗。

大型程式碼庫 context 問題是程式碼庫規模(通常是數千個檔案、數百萬個 token)與 Claude context window(一個有限的工作記憶預算,同時被系統提示、CLAUDE.md 內容、工具定義、對話歷史、累積的工具結果與當前使用者訊息消耗)之間的結構性落差。由於整個程式碼庫無法放入,Claude Code 中每個程式碼庫探索架構都必須把 context 當作要分配的預算,而不是要對抗的限制:決定載入哪些檔案、以什麼粒度、什麼順序,以及哪些留在磁碟,等到有證據顯示它們重要時再讀。 Source ↗

為什麼這對 CCA-F 很重要

Code Generation with Claude Code 情境和 Developer Productivity with Claude 情境,都會向考生呈現需要長時間執行的任務——bug 調查、多檔案重構、測試撰寫、導覽程式碼庫——其中 agent 在第一次工具呼叫之前無法預先規劃完整的讀取順序。相反地,agent 必須反覆發現、縮小範圍、再讀取,同時為任務末尾真正的程式碼修改保留足夠的 context 空間。社群考試通過報告一再指出,把檔案讀取視為免費的考生在 Domain 5.4 題目上會失敗;把讀取視為 agent 最昂貴動作的考生,往往能選出正確的 lazy-loading 架構。

Lazy Loading 策略 — 只讀相關檔案,不讀整個程式碼庫

大型程式碼庫探索 Context Management 的核心原則是 lazy loading:把讀取檔案的成本推遲到有證據顯示該檔案與當前任務相關為止。Lazy loading 把「先讀完所有東西、之後再縮小」的預設行為,翻轉為「先縮小、只讀通過篩選的內容」。Claude Code 的內建工具介面——Read、Write、Edit、Bash、Grep、Glob——正是圍繞這個翻轉設計的。

Lazy Loading 的三條法則

  1. 發現比讀取便宜。 Glob(路徑發現)和 Grep(內容搜尋)回傳輕量的結構性訊號——檔案路徑、行數匹配——所消耗的 token 只是完整 Read 的一小部分。先把發現的預算花完。
  2. 讀取比編輯便宜。 Read 讓 Claude 在不提交修改的情況下檢查檔案。在 Edit 之前,務必先 Read 目標區域並確認前提條件。
  3. 每個載入的檔案都會排擠其他東西。 Context window 是共享的預算;一個在任務早期載入的 3,000 行檔案,會擠掉原本應該驅動下一個決策的測試檔。

何時打破 Lazy Loading 的預設

Lazy loading 是預設行為,不是禁令。少數小型且至關重要的檔案——最上層的 CLAUDE.md、服務的主要進入點、測試設定——是合理的即時讀取,因為它們能影響後續每一個決策。考試區分合理的即時讀取(小型、資訊密度高、事先已知)和不合理的「讀取整個程式碼庫」模式(批量、每 token 訊號低、推測性)。啟發法與資深工程師相同:你會即時讀 README 和主要進入點;你不會在確認自己關心測試之前就讀取每個測試檔。

Lazy loading 是大型程式碼庫探索 Context Management 中每個考試正確答案背後的第一原則。Code Generation with Claude Code 情境中的干擾選項頻繁地提出「預先讀取所有相關檔案以建立完整 context」——這是錯的,因為它消耗了必須保留給後續推理和編輯步驟的預算。正確的架構只讀當前步驟所需的內容,萃取相關片段、將其摘要進 scratchpad 或簡短筆記,並捨棄原始檔案內容。 Source ↗

Glob → Read Pipeline — 在選擇性載入前先發現候選檔案

Claude Code 中規範的 lazy-loading pipeline 是 Glob 接著對少數子集進行選擇性 ReadGlob 依路徑模式(src/**/*.ts**/auth/*.pyapps/*/config/*.yaml)走訪檔案系統,只回傳匹配路徑的清單——不含任何檔案內容。該路徑清單比相同檔案的內容便宜了數個數量級,讓 Claude 在花費讀取預算之前就能做出有依據的選擇。

Pipeline 的逐步運作方式

  1. 形成路徑假設。 根據任務,哪些目錄或命名模式應該包含相關檔案?「身份驗證功能可能在 **/auth/****/login/**。」
  2. 對假設執行 Glob 工具回傳路徑清單(可能有數百個),不讀取任何內容。
  3. 縮小清單。 利用檔名線索(*.test.tsindex.**.config.*)挑出最可能包含相關程式碼的少數幾個檔案。
  4. 只讀縮小後的集合。 對每個存活的路徑呼叫 Read。理想上使用行範圍參數,讓只有相關區域進入 context。
  5. 若假設失敗則迭代。 若第一次 Glob 沒有產生有用的結果,精煉模式;不要擴大到遞迴的 **/* 全掃。

Glob 是路徑工具,不是內容工具

CCA-F 上 GlobGrep 之間最常被測試的區別是:Glob 只匹配路徑模式,不開啟任何檔案。它回答的是「哪些檔案符合這個路徑模式?」——永遠不是「哪些檔案提到了這個 symbol?」如果你的問題是內容導向的(「哪些檔案 import 了 AuthService?」),Glob 無法回答;你需要 Grep

Glob tool 是 Claude Code 的內建工具,走訪檔案系統並回傳符合指定 glob 模式(***、字元類別、副檔名過濾)的路徑清單。它不讀取任何檔案內容——只讀取目錄結構——因此是最便宜的程式碼庫發現形式。用 Glob 回答「這個路徑形狀下存在哪些檔案?」並建立候選清單,讓後續的 ReadGrep 進一步縮小。任何把 Glob 用來「搜尋程式碼」的做法都是誤用;內容搜尋是 Grep 的職責。 Source ↗

Grep-First 方法 — 在讀取完整檔案前先搜尋相關 Symbol

GrepGlob 的 symbol 驅動對應工具。Glob 依名稱找檔案,Grep 依內容找檔案——類別宣告、函式名稱、設定鍵值、字串常數。對於大多數真實的程式碼庫探索任務,Grep-first 是考試正確的模式:在讀取完整檔案之前,先對任務提到的確切 symbol 或文字執行 Grep,並用匹配的行號對那些行進行精準的 Read

Grep-First 工作流程

  1. 從任務中萃取搜尋詞。 若任務提到 processRefund,第一步是對 processRefund 執行 Grep,而不是對一個可能包含它的目錄執行 Read
  2. 解讀匹配清單。 Grep 回傳帶有匹配行號的檔案路徑。少數幾個命中通常會揭示定義位置(symbol 宣告處)和呼叫位置(symbol 被使用處)。
  3. 精準讀取。 對每個值得調查的命中,用包含匹配行加上小範圍前後文(例如各 20 行)的行範圍執行 Read。避免對任何超過數百行的檔案執行沒有行範圍的 Read
  4. 只在必要時追蹤相依。 若精準讀取顯示函式委派給另一個 symbol,對那個 symbol 重複 Grep-first 模式,而不是讀取整個委派檔案。

為什麼 Grep-First 能保留預算

一個函式的典型定義位置佔 20–60 行。對相同函式的完整檔案讀取可能載入 800 行的周邊程式碼——膨脹了 20 倍。在多步驟任務中,差距會複利累積:Grep-first 的 agent 可以在全檔讀取 agent 調查兩個 symbol 的預算內,調查十個不同的 symbol。

Grep-first pattern 是在開啟任何檔案之前,先用 Grep tool 解決「這個 symbol 在哪裡?」和「它在哪裡被使用?」的紀律。Grep 以遠低於底層檔案的 token 成本回傳帶有匹配行號的檔案路徑,讓 Claude 能精準地對恰好相關的區域進行行範圍讀取。這個模式是大型程式碼庫探索 Context Management 中最高槓桿的單一動作,因為它把開放式的「找到程式碼」步驟,轉化為有邊界、預算可預測的查找。 Source ↗

Grep vs Glob — 考試的區別

  • Glob 搜尋檔案路徑。 輸入:路徑模式。輸出:檔案清單。不讀取任何檔案內容。
  • Grep 搜尋檔案內容。 輸入:regex 或字面字串。輸出:匹配的 path:line:content 命中。

混淆這兩個工具的考生,要嘛在 Glob 就夠用的地方執行 Grep(昂貴,因為 Grep 會讀取它掃描的每個檔案),要嘛在需要 Grep 的地方執行 Glob(無用,因為 Glob 無法找到檔案內部的 symbol)。兩種錯誤都以干擾選項的形式出現在 CCA-F Code Generation 情境題目中。

Scratchpad Files — 將探索筆記寫入外部檔案以持久化狀態

scratchpad file 是一個存在磁碟上的檔案(慣例命名為 NOTES.mdSCRATCH.md.claude/scratchpad/task-<id>.md 或類似名稱),agent 在探索過程中寫入中間發現——發現的檔案路徑、萃取的函式簽名、待驗證的假設、待辦事項。Scratchpad 是程式碼庫探索版本的案例事實區塊(對應任務 5.1):它們把持久性狀態從 context window 移出,放到磁碟上,之後可以透過短短的 Read 精準引用,而不必重播多輪的對話歷史。

為什麼 Scratchpad Files 優於對話中的筆記

對話中的筆記——agent 打出「我已確認 processRefund 位於 billing/refunds.ts 第 42 行,它委派給 refundGateway.submit」——受到大型程式碼庫探索 Context Management 所有病態的影響。這條筆記必須在後續每一輪都重播。它與實際的程式碼內容爭奪顯著性。當對話成長,它容易受到迷失中段效應的影響。scratchpad file 避免了全部三個成本:它存在磁碟上、零持續性 token 成本;需要時可以以可預測的成本重新讀取;agent 可以附加新發現而不必重寫歷史。

Scratchpad 內容模式

結構良好的 scratchpad 記錄:

  • 已確認的事實。processRefund 定義於 billing/refunds.ts:42。」
  • 待驗證的假設。 「退款金額可能在 billing/policy.ts 中被限制——尚未確認。」
  • 已排除的線索。legacy/old-refund.ts 無人使用——import 圖顯示無呼叫者。」
  • 決策記錄。 「選擇重構 refundGateway.submit 而非取代它;原因:三個下游呼叫點依賴當前簽名。」
  • 待辦清單。 「1. 確認 refundGateway.submit 的測試覆蓋率。2. 執行遷移腳本。」

跨 Session 邊界的存活

Scratchpad files 在 Claude Code session 結束後仍然存在,這意味著它們在使用者隔天繼續作業、或有 subagent 以 scratchpad 作為主要輸入被啟動時,也能作為交接文件。這個特性將大型程式碼庫探索 Context Management 與 session-state-resumption-and-forking(任務 1.7)連結起來:scratchpad 是探索狀態的持久載體。

Scratchpad files 是程式碼庫探索版本的對話式 agent 案例事實區塊。在 CCA-F 上,每當某個答案選項把長時間執行的探索框架為「把所有發現保存在對話中,並在每一輪重播」,那就是錯的。考試正確的架構是把持久性發現外部化到磁碟的 scratchpad,需要時透過精準的 Read 引用,讓對話歷史保持空閒,專注於當前步驟的主動推理。 Source ↗

遞進式探索 — 在深入讀取檔案前先映射相依圖譜

資深工程師以由上而下的方式探索陌生程式碼庫:先了解模組邊界,再了解公開介面,最後才看任務實際觸及的那個模組的內部實作。遞進式探索是 Claude Code 的對應做法。agent 不是深入單一檔案,而是先在淺層映射相依圖譜——有哪些模組存在、哪個依賴哪個——然後只鑽入任務的輸入到輸出之間路徑上的模組。

遞進式探索協定

  1. 第 0 層:程式碼庫形狀。 Glob 最上層目錄,Read 根目錄的 README.mdpackage.json / pyproject.toml,以及最上層的 CLAUDE.md。總成本:幾百個 token。回報:專案技術棧與模組邊界的地圖。
  2. 第 1 層:公開介面。 對任務相關的每個模組,Globindex.* 或等效的公開介面檔案,並只 Read 那些檔案。這些檔案通常列出模組匯出的內容——實際上是模組公開 API 的目錄。
  3. 第 2 層:定義位置。 Grep-first 找任務提到的特定 symbol,並對匹配的行範圍進行精準 Read
  4. 第 3 層:實作細節。 只有在前三層有充分理由的情況下,agent 才應對大型實作檔案進行完整讀取。

跳過層次——例如從「使用者想改變退款流程」直接跳到完整讀取 billing/ 目錄中的每個檔案——是考試測試的失敗模式。分層探索把便宜、訊號高的讀取放在前面,把昂貴、邊際訊號低的讀取推遲到證據累積之後。

相依圖譜 vs 呼叫圖譜

相依圖譜是粗粒度的結構地圖(模組 A 依賴模組 B)。呼叫圖譜是細粒度的 symbol 地圖(函式 foo() 呼叫函式 bar())。遞進式探索通常在第 0 和第 1 層依賴相依圖譜,在第 2 和第 3 層依賴 Grep-first 的呼叫圖譜查找。

優先排序啟發法 — 以進入點、設定檔、測試檔作為起點

當任務模糊或程式碼庫陌生時,agent 需要確定性的起點啟發法,而不是隨機漫走。CCA-F 要求認識四個規範起點,依訊號密度排序。

進入點

主要二進位檔的進入檔(main.tsindex.tsapp.pycmd/*/main.go)揭示服務的最上層組合:哪些模組被串接在一起、有哪些背景工作存在、有哪些 HTTP 路由被註冊。進入檔幾乎總是值得即時讀取,因為它影響後續每個關於程式碼位置的決策。

設定檔

package.jsontsconfig.jsonpyproject.tomldocker-compose.yml.env.exampleCargo.toml 及等效檔案,描述了專案的相依套件、建置工具和執行環境。這些檔案體積小、資訊密度高,幾乎從不偏題。早期讀取它們,能讓 agent 免於後來對適用哪個測試執行器、linter 或套件管理工具的困惑。

測試檔

測試檔通常包含受測程式碼最高品質的可執行規格。當任務是「了解這個函式應該做什麼」時,最近的測試檔通常是建立正確心智模型的最快路徑——而且它也雙重作為 agent 所做任何更改的驗證工件。把 *.test.**_test.*spec/**tests/** 當作與進入點和設定檔並列的一線起點。

CLAUDE.md 檔案

CLAUDE.md 的層次結構(全域、專案、目錄)是專門為 Claude 策劃的起點。路徑特定的 CLAUDE.md 指令根據 agent 觸及哪些檔案而條件式載入——它們編碼了專案慣例、禁止編輯的清單和架構不變量。在每個探索步驟讀取最近的 CLAUDE.md,是 CCA-F 的預期反射動作。

當 Code Generation with Claude Code 情境在陌生程式碼庫中呈現一個任務時,考試正確的前四次讀取是:(1)最上層的 CLAUDE.md、(2)主要語言的根設定檔、(3)主要進入點、(4)可能目標目錄路徑上最具體的 CLAUDE.md。只有在這四次讀取之後,agent 才應開始 Grep 找 symbol。沒有先建立程式碼庫形狀就直接深入 Grep 的考生,往往會誤判目標模組,浪費後續預算。 Source ↗

Context Hygiene — 萃取所需資訊後捨棄不相關的檔案內容

讀取檔案是生命週期的開始,不是結束。一旦 agent 從 600 行的檔案中萃取了它需要的兩三個事實,全部 600 行就不應該繼續在後續每一輪佔用 context window。Context hygiene 是壓縮或捨棄已挖掘完畢的檔案內容的紀律,讓後續步驟保留它們的預算。

三個 Hygiene 動作

  1. 萃取並改寫。 讀取檔案後,在 scratchpad 中寫一兩句話——「refundGateway.submit(amount, orderId) 發 POST 到 /v1/refunds,回傳 {status, traceId}」——並把該摘要視為往後的規範引用。原始檔案內容變成可拋棄的。
  2. 壓縮或清除過時的工具結果。 Claude 4 支援刪除已被取代的工具結果的 context 編輯功能;對已完全挖掘的檔案讀取刻意使用這個功能。
  3. 不要重新讀取同一個未更改的檔案。 若上次 Read 後檔案沒有被編輯,先前萃取的事實仍然有效;重新讀取只是在不增加資訊的情況下加倍成本。

Hygiene vs 摘要

Hygiene 是比通用摘要更強的動作。Hygiene 說的是「我已萃取這個檔案的貢獻;我不再需要原始內容。」摘要說的是「這是原始內容的壓縮版本。」Hygiene 是考試獎勵的動作——摘要通常是以架構解決方案形式包裝的干擾選項,而更難的決策(完全捨棄內容)才是正確答案。

Repo Map 模式 — 維護高層索引檔以便導覽

repo map 是一個手動策劃或由 agent 維護的檔案(通常是 REPO_MAP.md.claude/REPO_MAP.md,或嵌入在 CLAUDE.md 中),以密集、可導覽的形式摘要程式碼庫的模組邊界、公開 API 和跨模組相依。一個好的 repo map 讓 Claude 不用執行任何 GlobGrep 就能回答「身份驗證在哪裡?」或「帳單模組的公開介面有哪些?」

Repo Map 中應包含的內容

  • 模組清單。 每個最上層模組一行,附一句描述。
  • 公開介面索引。 每個模組的公開匯出名稱,以及宣告位置的指標。
  • 相依箭頭。 粗粒度的「模組 X 依賴模組 Y」連結,讓 Claude 能推斷影響範圍。
  • 已知不變量。 「所有金額都是整數分位值;浮點數金額是 bug。」
  • 禁止編輯清單。 是生成的、第三方的或以其他方式禁止修改的檔案或目錄。

維護紀律

過時的 repo map 比沒有 repo map 更糟,因為它會誤導 agent。規範的紀律是在任何觸及模組邊界的 PR 中一併更新 repo map,把 map 視為審查工件,並加入版本或「最後驗證時間」時間戳。Claude Code 本身可以在重整架構任務之後被指派更新 repo map,從而讓探索與持久知識形成閉環。

Repo Map vs Scratchpad vs CLAUDE.md

這三個工件有各自明確的角色:

  • CLAUDE.md — 專案規則、慣例、禁止編輯清單、提示提示。跨任務穩定。
  • Repo map — 模組、介面和相依的結構索引。跨任務穩定;在結構變更時更新。
  • Scratchpad — 暫時性發現、待驗證假設、任務特定的決策記錄。每個任務重置。

混淆這些工件——例如把暫時性任務狀態放進 CLAUDE.md,或把結構性架構放進 scratchpad——是真實的考試陷阱。

Context Budget 追蹤 — 在載入大型檔案前估算剩餘 Context

每個自主的 Claude Code agent 都應把 context window 當作有可觀察剩餘餘額的預算。Context budget 追蹤是估算剩餘空間並在大型讀取前把它當作閘門的紀律。這是防止 agent 在多檔案重構進行到一半時耗盡預算的架構習慣。

為預算提供資訊的訊號

  • 迭代計數。 每一輪至少增加兩條訊息(assistant + tool_result);深層迴圈累積很快。
  • 累積工具結果大小。 大型 ReadBash 的輸出,主導長 session 的 token 用量。
  • CLAUDE.md + 工具定義的額外負擔。 這些在每一輪都會重播,設定了一個永久的下限。
  • 模型公告的 context window。 衡量其他一切的上限。

風險讀取前的預算感知閘門

在對大型檔案發出 Read 之前,agent(或一個 hook)應確認:

  1. 估算的檔案大小。 Glob 回傳的路徑,或快速的 Bash wc -l,可以提供大小估算。
  2. 當前剩餘預算。 從先前工具結果大小的總和粗略估算。
  3. 替代方案。 若檔案很大且特定區域已知(來自先前的 Grep 命中),只讀行範圍。若區域未知,先花一次 Grep。

不檢查大小就總是讀取完整檔案的 agent,會定期在單個超大檔案上耗盡預算。對超過某個門檻(例如 500 行)的檔案總是先做 Grep 或行範圍讀取的 agent,能夠順暢地執行更長的 session。

Developer Productivity with Claude 情境題中,常見的干擾選項建議「讀取完整檔案,以確保 agent 在編輯前擁有完整的 context」。當檔案很大時,這幾乎總是錯的。考試正確的做法是對相關 symbol 執行 GrepRead 精準的行範圍,進行編輯,若編輯的驗證需要看到更多內容,再事後進行第二次精準讀取。完整檔案讀取應該是例外,而不是預設,只保留給小型檔案(幾百行)或對任務至關重要的檔案。 Source ↗

已探索檔案的摘要 — 建立逐檔簡短筆記供後續參考

隨著 agent 探索,它應建立一個逐檔筆記索引——每個已探索的檔案一兩句話,記錄在 scratchpad 中——這樣後續步驟就可以問「我們對 billing/refunds.ts 學到了什麼?」而不必重新讀取那個檔案,或重播 600 行的 Read 工具結果。

逐檔筆記的內容

  • 一行用途說明。 「包含 processRefund 處理器;協調退款計算並呼叫 refundGateway.submit。」
  • 關鍵 symbol 或行號。processRefund 在第 42 行;clampRefundAmount 在第 118 行。」
  • 已知的特殊之處。 「金額是分位值,不是元;processRefund 期望正整數。」
  • 狀態。 「在第 5 輪審查;無待處理的編輯。」

逐檔筆記 vs Repo Map vs Scratchpad 決策記錄

scratchpad 存放了全部三者——但每個服務不同的功能。逐檔筆記是個別讀取的提煉輸出。決策記錄記錄跨檔案做出的選擇。repo map(若在專案層級維護)是結構性的,跨 session 存活。混用沒關係;混淆它們——例如把任務特定的逐檔筆記提升到全域 repo map——則不行。

為什麼這個模式對 CCA-F 很重要

Developer Productivity 情境中的考試題,固定會測試考生是否認識到,在長任務的第 15 輪,agent 不應重新讀取它在第 4 輪就已探索過的檔案。正確的架構只引用一次那個檔案,把簡短筆記寫進 scratchpad,現在以那條筆記——而不是原始的 600 行讀取——作為真理來源。讓 agent 在每個後續輪次重新讀取每個先前探索過的檔案的干擾答案,描述的是失敗模式,不是解決方案。

Explore Agent 模式 — 用於程式碼庫調查的唯讀 Subagent

大型程式碼庫探索中反覆出現的一個模式,是指定一個唯讀的 Explore subagent,其職責是調查程式碼庫、產出發現的 scratchpad,然後結束——從不編輯任何檔案。協調者 agent 接著消費 scratchpad,並決定主要 agent 是否應該繼續進行編輯。這個模式清晰地分離了發現與變更,而且由於 subagent 在隔離的 context 中運作,協調者的 context 不會被暫時性的原始檔案內容污染。

何時啟動 Explore Subagent

  • 任務需要在可以安全規劃第一次編輯之前讀取大量檔案。
  • 探索將產出數萬個 token 的原始檔案內容,而協調者不需要直接看到這些內容。
  • 協調者剩餘的 context 預算受限,而光是探索就會耗盡它。
  • 探索輸出可以序列化為 scratchpad file,讓協調者以有邊界的成本讀取。

Subagent 工具許可清單紀律

Explore subagent 的工具許可清單應包含 ReadGrepGlob,以及 Write(用於 scratchpad)——且不應包含 Edit 或破壞性的 Bash 工具。限制許可清單既是安全措施(subagent 無法意外修改程式碼庫),也是 context 措施(subagent 無法被誘導偏離探索角色)。

Explore subagent 是考試正確答案,當 Code Generation 情境在任何編輯開始之前呈現深入的多檔案調查。這個模式把探索的原始檔案內容隔離在 subagent 的 context 中,只把 scratchpad 摘要傳回給協調者,讓協調者的剩餘預算可用於規劃和編輯。讓協調者自己做所有讀取、或讓單一有 Edit 權限的 agent 執行探索的干擾選項,對大型程式碼庫任務而言是較低品質的架構。 Source ↗

白話說明

抽象的 context budget 紀律,一旦錨定在工程師已經熟悉的具體情境上就會變得直觀。以下三個類比——刻意選自截然不同的領域——涵蓋了大型程式碼庫探索 Context Management 的完整面向。

類比一:傳統市場採買 — 貨單、貨攤,而非掃遍整個市場

想像一位總鋪師助手要去傳統市場備料。市場裡有數百個攤位,賣的東西從海鮮到香料應有盡有——遠比辦一桌宴席需要的多得多。新手助手可能一頭衝進市場,逐攤掃視,把每個攤位的商品都搬一些回來再說。有經驗的助手做法大相徑庭:他先看菜單和貨單(Glob——知道自己要找哪一類的攤位),接著在攤位前問老闆有沒有今天要的那個食材(Grep——按內容搜尋),確認有貨才拿那個品項(行範圍 Read),用隨身的採買本記下每個攤位的特色和備料位置(scratchpad),而市場入口的「本日市況看板」則是 repo map,讓他不用繞一圈就知道各類食材分佈在哪個區。

跳過貨單和採買本,把整個市場的商品都搬回來「以備不時之需」的助手,回到廚房時桌子已經堆滿、根本找不到真正要用的食材。這正是跳過 GlobGrep、對大型程式碼庫預設全檔讀取的 Claude Code agent 的下場。

類比二:開卷考試 — 預算,不是圖書館

想像一位考生正在進行一場八小時的開卷大考,考的是一本厚重的參考書。他可以帶著書、一本空白筆記本和無限的筆——但桌面上同時能翻開的頁數有限。桌面就是 context window;參考書是程式碼庫;筆記本是 scratchpad。

一下子把所有章節都攤開在桌上的考生根本找不到東西;桌面雜亂無章,做到第三題就已沒有空間。反過來,先做索引、把到處都出現的三個公式抄在筆記本上、每道題各自翻到特定頁面、看完就合起來的考生,輕鬆在時限內答完考卷。

考生那個「抄下兩句重點、合上書本繼續」的習慣,就是 context hygiene。考生翻書先找索引而不是直接翻第一頁的反射,就是 Grep-first pattern。考生接受自己無法讀完全書、並願意規劃哪些頁面不讀,就是 lazy loading 落地於日常的具體體現。

類比三:工地木工 — 工作台 vs 倉庫

想像一位木工在工廠裡的工作台前打造一件訂製木櫃,工廠後頭接著一座巨大的倉庫,裡面存放著木料、五金、工具。工作台放著正在使用的幾塊木板、幾樣工具、眼前這個部件的圖紙。倉庫裡存放著其他一切:數千塊木料、數百套工具組、幾十年份的存檔。

把整個倉庫都拖到工作台的木工根本無法工作;台面被壓垮了。從不進倉庫的木工,一個小時內就會耗盡材料。正確的工作紀律是:查閱倉庫盤點表(repo map)了解有什麼存貨、取出當前步驟需要的特定木料和工具(精準 Read)、在工作台旁的剪貼板上做裁切清單(scratchpad)、用完的放回倉庫(context hygiene),並保持工作台夠空曠,足以做真正的工作。

考試正確的 Claude Code agent 就是這位木工。考試錯誤的 agent,是那個把整個倉庫搬到工作台上「以免萬一需要」、然後困惑地發現榫接根本切不準的人。

考試當天哪個類比對應哪個考點

  • Glob/Grep/Read pipeline、Grep-first pattern、lazy loading → 傳統市場採買類比。
  • Context budget 追蹤、context hygiene、hygiene vs 摘要 → 開卷考試預算類比。
  • Scratchpad files、repo map、Explore subagent 隔離 → 木工的工作台與倉庫類比。

與對話 Context Management(任務 5.1)的對應

任務 5.4 和任務 5.1 共享一個 context window 的基底,但處理的是不同的內容類型。任務 5.1 聚焦對話內容——使用者輪次、助手回覆、案例事實、承諾——其失敗模式是交易事實的摘要漂移。任務 5.4 聚焦檔案內容——原始碼、設定、記錄——其失敗模式是不加區別讀取導致的預算耗盡。

這些架構上的對應是刻意設計的。任務 5.1 的案例事實區塊,對應任務 5.4 的 scratchpad file:兩者都把持久性狀態外部化到由機器維護的工件,以有邊界的成本重播。任務 5.1 的工具輸出修剪,對應任務 5.4 的 Grep-first 精準讀取:兩者都阻止冗長內容進入 context window。任務 5.1 的章節標題,對應任務 5.4 的 repo map:兩者都對大型、非結構化的酬載提供導覽鷹架。已內化任務 5.1 的考生,會發現任務 5.4 主要是把相同原則重新部署到不同的內容領域。

Code Generation with Claude Code 和 Developer Productivity with Claude 情境中的考試題,經常把任務 5.1 和任務 5.4 的關切合在一起:與開發者進行多天配對工作的 session,其中 agent 必須同時保留對話承諾和程式碼庫發現。考試正確的架構,對互動層使用對話層級的案例事實區塊,並且對程式碼庫層使用磁碟常駐的 scratchpad。把任一個當作另一個的替代品,是常見的干擾選項。 Source ↗

常見考試陷阱

CCA-F Domain 5.4 利用了六個與大型程式碼庫探索 Context Management 相關的反覆出現陷阱模式。每個陷阱都有社群通過報告記錄在案,是聽起來合理、直到你套用 lazy-loading 公理才會看穿的干擾選項。

陷阱一:「預先讀取整個相關檔案」

干擾選項的措辭:「為確保 Claude 在編輯前擁有完整 context,請先讀取整個檔案。」對任何超過幾百行的檔案而言,這是錯的。精準的 Grep 加上行範圍 Read 能以一小部分的 token 成本提供相同的決策品質。考試把大型檔案的完整讀取視為預設的壞行為,而不是預設的安全行為。

陷阱二:「Grep 搜尋檔案路徑」

干擾選項的措辭:「使用 Grep 發現 src/auth/ 下有哪些檔案。」這把 GrepGlob 混淆了。Grep 搜尋檔案內容Glob 搜尋檔案路徑。任何交換這兩者的答案都是錯的,而社群一致指出這是 Domain 5.4 中最常答錯的單一區別。

陷阱三:「把所有發現保存在對話中」

干擾選項的措辭:「把探索發現保存在對話歷史中,讓 Claude 能跨輪次引用。」這對短任務有效,但在規模化時會失敗。考試正確的做法是把持久性發現外部化到 scratchpad file,它以有邊界的成本跨輪次存活,並對迷失中段效應免疫。

陷阱四:「更大的 Context Window 是解方」

干擾選項的措辭:「切換到擁有更大 context window 的模型以容納整個程式碼庫。」更大的 context window 並不能消除結構性落差——程式碼庫仍然比任何可用的 context window 大了數個數量級,而且臃腫的 context window 會惡化位置顯著性效應。解方是架構性的(lazy loading、Grep-first、scratchpad),而不是容量擴張。

陷阱五:「讓 Claude 在提示中自行維護 Repo Map」

干擾選項的措辭:「在系統提示中指示 Claude 在探索時建立並維護 repo map。」模型在提示中維護的狀態容易漂移和摘要損失——與導致對話案例事實沉船的失敗模式相同。考試正確的架構讓 Claude 把 repo map(或 scratchpad)寫入一個檔案,而不是寫入持久性的提示區段。

陷阱六:「永遠為探索啟動 Subagent」

干擾選項的措辭:「對任何程式碼庫調查都永遠使用 Explore subagent。」Subagent 在探索深度足以排擠協調者 context 時很有價值——但對於短小的、精準的任務(單檔編輯、快速 Grep 查找)而言,啟動 subagent 增加了開銷而沒有收益。考試獎勵選擇能解決問題的最輕量模式。

練習錨點 — 任務 5.4 情境題模板

CCA-F 與大型程式碼庫探索 Context Management 相關的練習題,在 Code Generation with Claude Code、Developer Productivity with Claude,以及 Claude Code for Continuous Integration 情境中,集中呈現為五種反覆出現的形狀。詳細題目存放在 ExamHub CCA-F 題庫;以下模板訓練導航這些題目所需的模式識別能力。

模板 A:Symbol 查找

agent 被要求更改 2,000 個檔案的程式碼庫中 processRefund 的行為。提出的架構包括:(a) Glob 所有路徑中包含 refund 的檔案;(b) Read src/billing/ 中的每個 *.ts 檔案;(c) GrepprocessRefund,並在每個命中處 Read 行範圍;(d) 啟動一個讀取所有帳單檔案的 Explore subagent。第一步正確的做法是什麼?

  • 正確做法: (c) Grep-first。symbol 明確,任務精準;Grep 加上行範圍讀取,以有邊界的成本給出定義位置和呼叫位置。選項 (a)、(b)、(d) 讀取過多。

模板 B:陌生程式碼庫

使用者把 Claude 從未見過的程式碼庫交給 Claude,並用一句話描述任務:新增一個功能。正確的探索順序是什麼?

  • 正確順序: (1) 最上層的 CLAUDE.md;(2) 主要語言的設定檔(package.json / pyproject.toml / 等效);(3) 主要進入點;(4) 可能目標目錄路徑上最具體的 CLAUDE.md。只有在這四次讀取之後,才開始 Grep-first 探索。不先建立程式碼庫形狀就直接跳進 Grep 的考生,往往會誤判目標模組,浪費後續預算。

模板 C:長期重構

agent 已進行多檔案重構 20 輪。早期的輪次讀取了不再需要的完整檔案。剩餘預算很緊,而 agent 還必須完成關鍵的編輯並執行測試。正確的 hygiene 動作是什麼?

  • 正確做法: context hygiene——把已挖掘完畢的檔案壓縮成簡短的 scratchpad 筆記,並捨棄或壓縮原始的完整檔案讀取。不要試圖重新讀取所有內容;不要切換到有更大 context window 的模型;不要在假設剩餘預算足夠的情況下繼續而不做任何 hygiene。

模板 D:Glob vs Grep 干擾選項

以下哪個是找到每個 import AuthService symbol 的檔案的正確方式?

  • 正確: GrepAuthService(或 import.*AuthService)遍歷整個程式碼庫,並讀取匹配的命中。
  • 錯誤: Glob**/*AuthService*——這只匹配路徑中包含該字串的檔案,而不是內容中 import 了該 symbol 的檔案。

模板 E:探索 Subagent 的決策

任務是在計劃進行重大重構之前進行深入的多檔案調查。協調者的 context 預算很緊,而光是調查就會產生數萬個 token 的原始檔案內容。協調者應該自己探索,還是啟動 Explore subagent?

  • 正確做法: 啟動一個有 ReadGrepGlobWrite(scratchpad)但沒有 Edit 的 Explore subagent。subagent 的隔離 context 吸收原始檔案內容;只有 scratchpad 摘要回傳給協調者。這讓協調者的預算可用於規劃和編輯。

大型程式碼庫探索 Context Management(Domain 5.4)的七步驟劇本:

  1. 永遠不要載入整個程式碼庫。 程式碼庫比任何 context window 大了數個數量級。
  2. Glob 找路徑,Grep 找 symbol。 兩個不同的工具;混淆它們是最常見的考試陷阱。
  3. Grep-first。Read 任何大型檔案之前,先解決「這個東西在哪裡?」
  4. 讀取行範圍,不讀整個檔案。 精準讀取優於超過約 500 行的全檔讀取。
  5. 把持久性狀態外部化到 scratchpad。 磁碟,而不是對話,才是探索發現的家。
  6. 在深入鑽研之前建立程式碼庫形狀。 CLAUDE.md → 設定檔 → 進入點 → 最近的目錄 CLAUDE.md,然後再 Grep。
  7. 實踐 context hygiene。 在萃取一個檔案的貢獻之後,讓原始內容從 context 中消失。

干擾線索:若某個答案提出讀取整個程式碼庫、依賴更大的 context window,或把所有發現保存在對話中,那就是錯的。 Source ↗

大型程式碼庫探索 Context Management — 常見問題

為什麼在任務開始時把整個程式碼庫載入 Claude 的 context 是錯的?

生產環境的程式碼庫通常跨越數千個檔案、數百萬個 token——比任何 Claude context window 大了兩到三個數量級。即使是一個小型服務,通常在讀取幾百個檔案後就已超出可用預算。更重要的是,每個花在載入推測性 context 上的 token,都是任務真正需要的後續推理和編輯所無法使用的 token。正確的模式是 lazy loading:用幾次精準讀取建立程式碼庫形狀(CLAUDE.md、設定檔、進入點),然後 Grep-first 找任務提到的 symbol,再行範圍 Read 存活下來的候選檔案,再把發現萃取到 scratchpad 並捨棄原始檔案內容。

Claude Code 上的 GlobGrep 有什麼差異,為什麼這個區別很重要?

Glob 匹配檔案路徑模式——src/**/*.ts**/auth/*.py——並回傳匹配的檔案路徑清單,不讀取任何內容。Grep 搜尋檔案內容中的 regex 或字面字串,並回傳它掃描的檔案中匹配的 path:line:content 命中。當問題是「這個路徑形狀下存在哪些檔案?」時用 Glob;當問題是「哪些檔案包含這個 symbol 或字串?」時用 Grep。混淆它們是 CCA-F 上最常答錯的 Domain 5.4 區別:在 Glob 就夠用的地方用 Grep,會在不必要的內容掃描上燒掉預算;而在需要 Grep 的地方用 Glob,根本無法找到檔案內部的 symbol。

什麼是 scratchpad file,為什麼它比把發現保存在對話中更好?

scratchpad file 是一個磁碟常駐的檔案(慣例命名為 NOTES.mdSCRATCH.md.claude/scratchpad/task-<id>.md),agent 在探索過程中寫入累積的發現——已確認的事實、待驗證的假設、已排除的線索、決策記錄、逐檔筆記。它優於對話式筆記的原因是:對話中的持久性狀態必須在每一輪重播,與主動推理爭奪顯著性,且容易受到迷失中段效應的影響。磁碟上的持久性狀態在不引用它的輪次中零成本,需要時可以以有邊界的成本重新讀取,並跨 session 邊界存活,使其成為程式碼庫探索版本的任務 5.1 案例事實區塊。

什麼時候應該啟動 Explore subagent 而不是在主要 agent 中進行調查?

當調查的深度足以讓其原始檔案內容排擠關鍵的協調者 context 時,啟動 Explore subagent。明確的觸發條件:調查觸及數十個檔案、產出數萬個 token 的原始內容、在計劃重大重構之前進行,或協調者的剩餘預算已受限。給 subagent ReadGrepGlobWrite(用於 scratchpad),但不給 Edit——subagent 的職責是發現,不是變更。對於短小的、精準的調查,subagent 增加了開銷而沒有收益;能解決問題的最輕量模式,就是考試正確的模式。

在陌生的程式碼庫中開始任務時,如何決定即時讀取哪些、懶惰讀取哪些?

即時讀取體積小、資訊密度高、能影響後續每個決策的檔案:最上層的 CLAUDE.md、主要設定檔(package.jsonpyproject.tomlCargo.toml 等)、主要進入點,以及可能目標目錄路徑上最具體的 CLAUDE.md。這四次讀取通常花費幾千個 token,給 agent 一張專案技術棧、模組邊界和慣例的地圖。懶惰讀取其他所有內容:先用 GlobGrep 縮小,讀取行範圍而非完整檔案,並在繼續前把發現萃取到 scratchpad。

在需要讀取 agent 在 session 早期已檢查過的檔案的長任務中,應如何管理 context?

不要重新讀取未更改的檔案。若 agent 在早期讀取時已萃取了相關事實,並把它們記錄在 scratchpad 中,那麼一次精準的 scratchpad Read 就能以原始檔案成本的一小部分取回摘要。重新讀取一個未更改的 600 行檔案,只是為了取回 scratchpad 中已有一行摘要的兩個事實,在不增加資訊的情況下加倍了 token 成本。紀律是:第一次讀取時萃取,摘要進 scratchpad,把 scratchpad 視為往後的規範引用,只有在檔案已更改或現在需要更深入的區域時才重新讀取原始檔案。

什麼是 context hygiene,它和摘要有什麼不同?

Context hygiene 是主動捨棄或壓縮已從其相關事實中完全挖掘的檔案內容——讓原始內容從 context window 中消失,讓後續步驟保留預算。摘要產生保留在 context 中、成本降低的原始內容壓縮版本。Hygiene 更進一步:萃取的事實存在 scratchpad 中,原始檔案內容被視為完全可拋棄。在 CCA-F 上,當 hygiene 是正確動作時,提出摘要的答案選項是常見的干擾選項,因為摘要仍然支付持續的 token 成本,而 hygiene——結合磁碟常駐的 scratchpad——則不。

延伸閱讀

Related ExamHub topics: Managing Conversation Context Across Long Interactions, Built-in Tools Selection and Application, Path-Specific Rules and Conditional Convention Loading, Session State, Resumption, and Forking.

官方資料來源