大型程式碼庫探索的 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 的三條法則
- 發現比讀取便宜。
Glob(路徑發現)和Grep(內容搜尋)回傳輕量的結構性訊號——檔案路徑、行數匹配——所消耗的 token 只是完整 Read 的一小部分。先把發現的預算花完。 - 讀取比編輯便宜。 Read 讓 Claude 在不提交修改的情況下檢查檔案。在 Edit 之前,務必先 Read 目標區域並確認前提條件。
- 每個載入的檔案都會排擠其他東西。 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 接著對少數子集進行選擇性 Read。Glob 依路徑模式(src/**/*.ts、**/auth/*.py、apps/*/config/*.yaml)走訪檔案系統,只回傳匹配路徑的清單——不含任何檔案內容。該路徑清單比相同檔案的內容便宜了數個數量級,讓 Claude 在花費讀取預算之前就能做出有依據的選擇。
Pipeline 的逐步運作方式
- 形成路徑假設。 根據任務,哪些目錄或命名模式應該包含相關檔案?「身份驗證功能可能在
**/auth/**或**/login/**。」 - 對假設執行
Glob。 工具回傳路徑清單(可能有數百個),不讀取任何內容。 - 縮小清單。 利用檔名線索(
*.test.ts、index.*、*.config.*)挑出最可能包含相關程式碼的少數幾個檔案。 - 只讀縮小後的集合。 對每個存活的路徑呼叫
Read。理想上使用行範圍參數,讓只有相關區域進入 context。 - 若假設失敗則迭代。 若第一次 Glob 沒有產生有用的結果,精煉模式;不要擴大到遞迴的
**/*全掃。
Glob 是路徑工具,不是內容工具
CCA-F 上 Glob 和 Grep 之間最常被測試的區別是:Glob 只匹配路徑模式,不開啟任何檔案。它回答的是「哪些檔案符合這個路徑模式?」——永遠不是「哪些檔案提到了這個 symbol?」如果你的問題是內容導向的(「哪些檔案 import 了 AuthService?」),Glob 無法回答;你需要 Grep。
Glob tool 是 Claude Code 的內建工具,走訪檔案系統並回傳符合指定 glob 模式(*、**、字元類別、副檔名過濾)的路徑清單。它不讀取任何檔案內容——只讀取目錄結構——因此是最便宜的程式碼庫發現形式。用 Glob 回答「這個路徑形狀下存在哪些檔案?」並建立候選清單,讓後續的 Read 或 Grep 進一步縮小。任何把 Glob 用來「搜尋程式碼」的做法都是誤用;內容搜尋是 Grep 的職責。
Source ↗
Grep-First 方法 — 在讀取完整檔案前先搜尋相關 Symbol
Grep 是 Glob 的 symbol 驅動對應工具。Glob 依名稱找檔案,Grep 依內容找檔案——類別宣告、函式名稱、設定鍵值、字串常數。對於大多數真實的程式碼庫探索任務,Grep-first 是考試正確的模式:在讀取完整檔案之前,先對任務提到的確切 symbol 或文字執行 Grep,並用匹配的行號對那些行進行精準的 Read。
Grep-First 工作流程
- 從任務中萃取搜尋詞。 若任務提到
processRefund,第一步是對processRefund執行Grep,而不是對一個可能包含它的目錄執行Read。 - 解讀匹配清單。
Grep回傳帶有匹配行號的檔案路徑。少數幾個命中通常會揭示定義位置(symbol 宣告處)和呼叫位置(symbol 被使用處)。 - 精準讀取。 對每個值得調查的命中,用包含匹配行加上小範圍前後文(例如各 20 行)的行範圍執行
Read。避免對任何超過數百行的檔案執行沒有行範圍的Read。 - 只在必要時追蹤相依。 若精準讀取顯示函式委派給另一個 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.md、SCRATCH.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 不是深入單一檔案,而是先在淺層映射相依圖譜——有哪些模組存在、哪個依賴哪個——然後只鑽入任務的輸入到輸出之間路徑上的模組。
遞進式探索協定
- 第 0 層:程式碼庫形狀。
Glob最上層目錄,Read根目錄的README.md、package.json/pyproject.toml,以及最上層的 CLAUDE.md。總成本:幾百個 token。回報:專案技術棧與模組邊界的地圖。 - 第 1 層:公開介面。 對任務相關的每個模組,
Glob找index.*或等效的公開介面檔案,並只Read那些檔案。這些檔案通常列出模組匯出的內容——實際上是模組公開 API 的目錄。 - 第 2 層:定義位置。 Grep-first 找任務提到的特定 symbol,並對匹配的行範圍進行精準
Read。 - 第 3 層:實作細節。 只有在前三層有充分理由的情況下,agent 才應對大型實作檔案進行完整讀取。
跳過層次——例如從「使用者想改變退款流程」直接跳到完整讀取 billing/ 目錄中的每個檔案——是考試測試的失敗模式。分層探索把便宜、訊號高的讀取放在前面,把昂貴、邊際訊號低的讀取推遲到證據累積之後。
相依圖譜 vs 呼叫圖譜
相依圖譜是粗粒度的結構地圖(模組 A 依賴模組 B)。呼叫圖譜是細粒度的 symbol 地圖(函式 foo() 呼叫函式 bar())。遞進式探索通常在第 0 和第 1 層依賴相依圖譜,在第 2 和第 3 層依賴 Grep-first 的呼叫圖譜查找。
優先排序啟發法 — 以進入點、設定檔、測試檔作為起點
當任務模糊或程式碼庫陌生時,agent 需要確定性的起點啟發法,而不是隨機漫走。CCA-F 要求認識四個規範起點,依訊號密度排序。
進入點
主要二進位檔的進入檔(main.ts、index.ts、app.py、cmd/*/main.go)揭示服務的最上層組合:哪些模組被串接在一起、有哪些背景工作存在、有哪些 HTTP 路由被註冊。進入檔幾乎總是值得即時讀取,因為它影響後續每個關於程式碼位置的決策。
設定檔
package.json、tsconfig.json、pyproject.toml、docker-compose.yml、.env.example、Cargo.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 動作
- 萃取並改寫。 讀取檔案後,在 scratchpad 中寫一兩句話——「
refundGateway.submit(amount, orderId)發 POST 到/v1/refunds,回傳{status, traceId}」——並把該摘要視為往後的規範引用。原始檔案內容變成可拋棄的。 - 壓縮或清除過時的工具結果。 Claude 4 支援刪除已被取代的工具結果的 context 編輯功能;對已完全挖掘的檔案讀取刻意使用這個功能。
- 不要重新讀取同一個未更改的檔案。 若上次 Read 後檔案沒有被編輯,先前萃取的事實仍然有效;重新讀取只是在不增加資訊的情況下加倍成本。
Hygiene vs 摘要
Hygiene 是比通用摘要更強的動作。Hygiene 說的是「我已萃取這個檔案的貢獻;我不再需要原始內容。」摘要說的是「這是原始內容的壓縮版本。」Hygiene 是考試獎勵的動作——摘要通常是以架構解決方案形式包裝的干擾選項,而更難的決策(完全捨棄內容)才是正確答案。
Repo Map 模式 — 維護高層索引檔以便導覽
repo map 是一個手動策劃或由 agent 維護的檔案(通常是 REPO_MAP.md、.claude/REPO_MAP.md,或嵌入在 CLAUDE.md 中),以密集、可導覽的形式摘要程式碼庫的模組邊界、公開 API 和跨模組相依。一個好的 repo map 讓 Claude 不用執行任何 Glob 或 Grep 就能回答「身份驗證在哪裡?」或「帳單模組的公開介面有哪些?」
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);深層迴圈累積很快。
- 累積工具結果大小。 大型
Read或Bash的輸出,主導長 session 的 token 用量。 - CLAUDE.md + 工具定義的額外負擔。 這些在每一輪都會重播,設定了一個永久的下限。
- 模型公告的 context window。 衡量其他一切的上限。
風險讀取前的預算感知閘門
在對大型檔案發出 Read 之前,agent(或一個 hook)應確認:
- 估算的檔案大小。
Glob回傳的路徑,或快速的Bash wc -l,可以提供大小估算。 - 當前剩餘預算。 從先前工具結果大小的總和粗略估算。
- 替代方案。 若檔案很大且特定區域已知(來自先前的 Grep 命中),只讀行範圍。若區域未知,先花一次 Grep。
不檢查大小就總是讀取完整檔案的 agent,會定期在單個超大檔案上耗盡預算。對超過某個門檻(例如 500 行)的檔案總是先做 Grep 或行範圍讀取的 agent,能夠順暢地執行更長的 session。
Developer Productivity with Claude 情境題中,常見的干擾選項建議「讀取完整檔案,以確保 agent 在編輯前擁有完整的 context」。當檔案很大時,這幾乎總是錯的。考試正確的做法是對相關 symbol 執行 Grep,Read 精準的行範圍,進行編輯,若編輯的驗證需要看到更多內容,再事後進行第二次精準讀取。完整檔案讀取應該是例外,而不是預設,只保留給小型檔案(幾百行)或對任務至關重要的檔案。
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 的工具許可清單應包含 Read、Grep、Glob,以及 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,讓他不用繞一圈就知道各類食材分佈在哪個區。
跳過貨單和採買本,把整個市場的商品都搬回來「以備不時之需」的助手,回到廚房時桌子已經堆滿、根本找不到真正要用的食材。這正是跳過 Glob 和 Grep、對大型程式碼庫預設全檔讀取的 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/ 下有哪些檔案。」這把 Grep 和 Glob 混淆了。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) Grep 找 processRefund,並在每個命中處 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 的檔案的正確方式?
- 正確:
Grep找AuthService(或import.*AuthService)遍歷整個程式碼庫,並讀取匹配的命中。 - 錯誤:
Glob找**/*AuthService*——這只匹配路徑中包含該字串的檔案,而不是內容中 import 了該 symbol 的檔案。
模板 E:探索 Subagent 的決策
任務是在計劃進行重大重構之前進行深入的多檔案調查。協調者的 context 預算很緊,而光是調查就會產生數萬個 token 的原始檔案內容。協調者應該自己探索,還是啟動 Explore subagent?
- 正確做法: 啟動一個有
Read、Grep、Glob、Write(scratchpad)但沒有Edit的 Explore subagent。subagent 的隔離 context 吸收原始檔案內容;只有 scratchpad 摘要回傳給協調者。這讓協調者的預算可用於規劃和編輯。
大型程式碼庫探索 Context Management(Domain 5.4)的七步驟劇本:
- 永遠不要載入整個程式碼庫。 程式碼庫比任何 context window 大了數個數量級。
- Glob 找路徑,Grep 找 symbol。 兩個不同的工具;混淆它們是最常見的考試陷阱。
- Grep-first。 在
Read任何大型檔案之前,先解決「這個東西在哪裡?」 - 讀取行範圍,不讀整個檔案。 精準讀取優於超過約 500 行的全檔讀取。
- 把持久性狀態外部化到 scratchpad。 磁碟,而不是對話,才是探索發現的家。
- 在深入鑽研之前建立程式碼庫形狀。 CLAUDE.md → 設定檔 → 進入點 → 最近的目錄 CLAUDE.md,然後再 Grep。
- 實踐 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 上的 Glob 和 Grep 有什麼差異,為什麼這個區別很重要?
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.md、SCRATCH.md 或 .claude/scratchpad/task-<id>.md),agent 在探索過程中寫入累積的發現——已確認的事實、待驗證的假設、已排除的線索、決策記錄、逐檔筆記。它優於對話式筆記的原因是:對話中的持久性狀態必須在每一輪重播,與主動推理爭奪顯著性,且容易受到迷失中段效應的影響。磁碟上的持久性狀態在不引用它的輪次中零成本,需要時可以以有邊界的成本重新讀取,並跨 session 邊界存活,使其成為程式碼庫探索版本的任務 5.1 案例事實區塊。
什麼時候應該啟動 Explore subagent 而不是在主要 agent 中進行調查?
當調查的深度足以讓其原始檔案內容排擠關鍵的協調者 context 時,啟動 Explore subagent。明確的觸發條件:調查觸及數十個檔案、產出數萬個 token 的原始內容、在計劃重大重構之前進行,或協調者的剩餘預算已受限。給 subagent Read、Grep、Glob 和 Write(用於 scratchpad),但不給 Edit——subagent 的職責是發現,不是變更。對於短小的、精準的調查,subagent 增加了開銷而沒有收益;能解決問題的最輕量模式,就是考試正確的模式。
在陌生的程式碼庫中開始任務時,如何決定即時讀取哪些、懶惰讀取哪些?
即時讀取體積小、資訊密度高、能影響後續每個決策的檔案:最上層的 CLAUDE.md、主要設定檔(package.json、pyproject.toml、Cargo.toml 等)、主要進入點,以及可能目標目錄路徑上最具體的 CLAUDE.md。這四次讀取通常花費幾千個 token,給 agent 一張專案技術棧、模組邊界和慣例的地圖。懶惰讀取其他所有內容:先用 Glob 和 Grep 縮小,讀取行範圍而非完整檔案,並在繼續前把發現萃取到 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——則不。
延伸閱讀
- Claude Certified Architect — Foundations (CCA-F) Exam Guide: https://everpath-course-content.s3-accelerate.amazonaws.com/instructor/8lsy243ftffjjy1cx9lm3o2bw/public/1773274827/Claude+Certified+Architect+%E2%80%93+Foundations+Certification+Exam+Guide.pdf
- Context windows — Claude API Docs: https://docs.anthropic.com/en/docs/build-with-claude/context-windows
- Long context prompting tips — Claude API Docs: https://docs.anthropic.com/en/docs/build-with-claude/prompt-engineering/long-context-tips
- Tool reference — Anthropic-provided built-in tools: https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/tool-reference
- CLAUDE.md configuration — Claude Code Docs: https://docs.anthropic.com/en/docs/claude-code/claude-md
- 社群通過報告(893/1000,Kishor Kukreja,2026-04-09): https://medium.com/@kishorkukreja/i-passed-anthropics-claude-certified-architect-foundations-exam-with-a-score-of-893-1000-2206c27efd6c
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.