作者: Yuker
2026年3月31日,安全研究者Chaofan Shou 發現Anthropic 發佈到npm 的Claude Code 套件中,source map 檔案並沒有被剝離。
這意味著: Claude Code 的完整TypeScript 源碼,51.2萬行,1903個文件,就這樣暴露在了公網上。
我當然不可能在短短數小時內看完這麼多程式碼,因此,我帶著三個問題去讀這份原始碼:
Claude Code 和其他AI 程式設計工具到底有什麼本質差異?
為什麼它寫程式的"手感"就是比別人好?
51萬行程式碼裡,到底藏著什麼?
讀完之後,我的第一個反應是:這不是一個AI 程式設計助手,這是一個作業系統。
一、先講一個故事:如果你要僱一個遠端程式設計師
想像你雇了一個遠端程式設計師,給他你電腦的遠端存取權限。
你會怎麼做?
如果你是Cursor的做法:你讓他坐在你旁邊,每次他要敲命令之前你看一眼,點個"允許"。簡單粗暴,但你得一直盯著。
如果你是GitHub Copilot Agent的做法:你給他一台全新的虛擬機,讓他在裡面隨便折騰。搞完了把程式碼提交上來,你審核後再合併。安全,但他看不到你本地的環境。
如果你是Claude Code的做法:
你讓他直接用你的電腦——但你給他配了一套極度精密的安檢系統。他能做什麼、不能做什麼、哪些操作需要你點頭、哪些可以自己來、甚至他想用rm -rf 都要經過9層審查才能執行。
這就是三種完全不同的安全哲學:
為什麼Anthropic 選了最難的那條路?
因為只有這樣,AI 才能用你的終端、你的環境、你的配置來工作——這才是"真正幫你寫代碼",而不是"在一個乾淨房間裡給你寫一段代碼然後複製過來"。
但代價是什麼?他們為此寫了51 萬行程式碼。
二、你以為的Claude Code vs 實際的Claude Code
大多數人以為AI 程式設計工具是這樣的:
Claude Code 實際上是這樣的:
相信大家都很好奇上面的是什麼,不急,讓我們逐一拆開看。
三、第一個秘密:提示詞不是寫出來的,是"拼裝"出來的
開啟src/constants/prompts.ts,你會看到這個函數:
export async function getSystemPrompt( tools: Tools, model: string, additionalWorkingDirectories?: string[], mcpClients?: MCPServerConnection[], ): Promise<string[]> { return [ // --- 静态内容(可缓存)--- getSimpleIntroSection(outputStyleConfig), getSimpleSystemSection(), getSimpleDoingTasksSection(), getActionsSection(), getUsingYourToolsSection(enabledTools), getSimpleToneAndStyleSection(), getOutputEfficiencySection(), // === 缓存边界=== ...(shouldUseGlobalCacheScope() ? [SYSTEM_PROMPT_DYNAMIC_BOUNDARY] : []), // --- 动态内容(每次不同)--- ...resolvedDynamicSections, ].filter(s => s !== null) }注意到那個SYSTEM_PROMPT_DYNAMIC_BOUNDARY了嗎?
這是一個緩存分界線。分界線上面的內容是靜態的,Claude API 可以快取它們,節省token 費用。分界線下面的內容是動態的——你目前的Git 分支、你的CLAUDE.md 項目配置、你之前告訴它的偏好記憶……每次對話都不一樣。
這意味著什麼?
Anthropic 把提示字當成了編譯器的輸出來最佳化。靜態部分是"編譯後的二進位",動態部分是"運行時參數"。這樣做的好處是:
省錢:靜態部分走緩存,不重複計費
快:快取命中直接跳過這些token 的處理
靈活:動態部分讓每次對話都能感知當下環境
⛏️每個工具都有獨立的"使用手冊"
更讓我震驚的是:每個工具目錄下都有一個prompt.ts 檔案──這是專門寫給LLM 看的使用手冊。
看看BashTool 的(src/tools/BashTool/prompt.ts,約370 行):
這不是寫給人看的文檔,這是寫給AI 的行為準則。每次Claude Code 啟動時,這些規則都會被注入到系統提示詞中。
這就是為什麼Claude Code 從不會擅自git push --force,而某些工具會--不是模型更聰明,是提示詞裡已經把規矩講清楚了。
而且Anthropic 內部版本跟你用的不一樣
程式碼裡大量出現這樣的分支:
ant 是Anthropic 內部員工。他們的版本有更詳細的程式碼風格指引("不寫註解除非WHY 不明顯")、更激進的輸出策略("倒金字塔寫作法"),以及一些仍在A/B 測試的實驗功能(Verification Agent、Explore & Plan Agent)。
這說明Anthropic 自己就是Claude Code 最大的使用者。他們在用自己的產品來開發自己的產品。
四、第二個秘密:42個工具,但你只看到了冰山一角
開啟src/tools.ts,會看到工具註冊中心:
42 個工具,但大部分你從未直接看過。因為很多工具是延遲載入的-只有當LLM 需要時,才透過ToolSearchTool 按需注入。
為什麼要這樣做呢?
因為每多一個工具,系統提示詞就要多一段描述,token 就要多花一份錢。如果你只是想讓Claude Code 幫你改一行程式碼,它不需要載入"定時任務排程器"和"團隊協作管理器"。
還有一個更聰明的設計:
設定CLAUDE_CODE_SIMPLE=true,Claude Code 只剩下三個工具:Bash、讀取檔案、改變檔案。這是給極簡主義者的後門。
1️⃣所有工具都從同一個工廠出來
注意那些預設值:isConcurrencySafe 預設false,isReadOnly 預設false。
這叫做fail-closed 設計-如果一個工具的作者忘了聲明安全屬性,系統會假設它是"不安全的、會寫入的"。寧可過度保守,也不漏掉一個風險。
2️⃣"先讀後改"的鐵律
FileEditTool 會檢查你是否已經用FileReadTool 讀過這個檔案。如果沒有,直接報錯,不讓改。
這就是為什麼Claude Code 不會像某些工具那樣"憑空寫一段程式碼覆蓋你的檔案"——它被強制要求先理解再修改。
五、第三個秘密:記憶系統-為什麼它能"記住你"
用過Claude Code 的人都有一個感覺:它好像真的認識你。
你告訴它"不要在測試中mock 資料庫",下次對話它就不會再mock。你告訴它"我是後端工程師,React 新手",它解釋前端程式碼時就會用後端的類比。
這背後是一個完整的記憶系統。
1️⃣用AI 檢索記憶
Claude Code 用另一個AI (Claude Sonnet)來決定"哪些記憶和當前對話相關"。
不是關鍵字匹配,不是向量搜尋——是讓一個小模型快速掃描所有記憶文件的標題和描述,選出最多5 個最相關的,然後把它們的完整內容注入到當前對話的上下文中。
策略是"精確度優先於召回率" ——寧可漏掉一個可能有用的記憶,也不塞進一個不相關的記憶污染上下文。
⏰KAIROS 模式:夜間"做夢"
這是最讓我覺得科幻的部分。
程式碼中有一個叫KAIROS 的特性標誌。在這個模式下,長會話中的記憶不是存在結構化檔案裡,而是存在著按日期的追加式日誌中。然後,有一個/dream 技能會在"夜間"(低活躍期)運行,把這些原始日誌蒸餾成結構化的主題文件。
AI 在"睡覺"的時候整理記憶。這已經不是工程了,這是仿生學。
六、第五個秘密:它不是一個Agent,是一群
當你讓Claude Code 做一個複雜任務時,它可能悄悄做了這件事:
它生成了一個子Agent 。
而且子Agent 有嚴格的"自我意識"注入,防止它遞歸生成更多子Agent:
這段程式碼在說: "你是一個工人,不是經理。別想著再僱人,自己工作。"
👤 Coordinator 模式:經理模式
在協調器模式下,Claude Code 變成純粹的任務編排者,自己不工作,只分配:
核心原則寫在程式碼註解裡:
"Parallelism is your superpower"只讀研究任務:並行跑。 寫入檔案任務:按檔案分組序列跑(避免衝突)。
🗣️Prompt Cache 的極致優化
為了最大化子Agent 的快取命中率,所有fork 子代理程式的工具結果都使用相同的佔位符文字:
為什麼?因為Claude API 的prompt cache 是基於字節級前綴匹配的。如果10 個子Agent 的前綴位元組完全一致,那麼只有第一個需要"冷啟動",後面9 個直接命中快取。
這是一個每次呼叫節省幾美分的優化,但在大規模使用下,能省下大量成本。
七、第六個秘密:三層壓縮,讓對話"永不超限"
所有LLM 都有上下文視窗限制。對話越長,歷史消息越多,最終一定會超出限制。
Claude Code 為此設計了三層壓縮:
1️⃣第一層:微壓縮-最小代價
export async function microcompactMessages(messages, toolUseContext, querySource) { // 时间触发:如果上次交互已过很久,服务器缓存已冷const timeBasedResult = maybeTimeBasedMicrocompact(messages, querySource) if (timeBasedResult) return timeBasedResult // 缓存编辑路径:通过API 的缓存编辑功能直接删除旧内容if (feature('CACHED_MICROCOMPACT')) { return await cachedMicrocompactPath(messages, querySource) } }微壓縮只動舊的工具呼叫結果-把" 10分鐘前讀的那個500行檔案的內容"替換成[Old tool result content cleared] 。
提示詞和對話主線完全保留。
2️⃣第二層:自動壓縮-主動收縮
當token 消耗接近上下文視窗的87%(視窗大小- 13,000 buffer),自動觸發。有一個熔斷器:連續3 次壓縮失敗後停止嘗試,避免死循環。
3️⃣第三層:完全壓縮-AI 總結
讓AI 對整段對話產生摘要,然後用摘要取代所有歷史訊息。生成摘要時有一個嚴厲的前置指令:
為什麼要這麼嚴厲?因為如果總結過程中AI 又去呼叫工具,就會產生更多的token 消耗,適得其反。這段提示詞就是在說: "你的任務是總結,別幹別的。"
壓縮後的token 預算:
檔案恢復:50,000 tokens
每個文件上限:5,000 tokens
技能內容:25,000 tokens
這些數字不是拍腦袋定的——它們是在"保留足夠上下文繼續工作"和"騰出足夠空間接收新消息"之間的平衡點。
八、讀完這份源碼,我學到了什麼
1️⃣AI Agent 的90% 工作量在"AI"之外
51 萬行程式碼裡,真正呼叫LLM API 的部分可能不到5%。其餘95% 是什麼?
安全檢查(18 個檔案只為一個BashTool)
權限系統(allow/deny/ask/passthrough 四態決策)
情境管理(三層壓縮+ AI 記憶檢索)
錯誤恢復(熔斷器、指數退避、Transcript 持久化)
多Agent 協調(蜂群編排+ 郵件通訊)
UI 互動(140 個React 元件+ IDE Bridge)
效能最佳化(prompt cache 穩定性+ 啟動時並行預取)
如果你正在做AI Agent 產品,這才是你真正要解決的問題。不是模型夠不夠聰明,是你的鷹架夠不夠結實。
2️⃣好的提示詞工程是系統工程
不是寫一段漂亮的prompt 就完事了。 Claude Code 的提示詞是:
7 層動態組裝
每個工具附有獨立的使用手冊
快取邊界精確劃分
內部版本和外部版本有不同的指令集
工具排序固定以保持快取穩定
這是工程化的提示詞管理,不是手工藝。
3️⃣為失敗設計
每一個外在依賴都有對應的失敗策略:
4️⃣Anthropic 把Claude Code 當作業系統在做
42 個工具= 系統呼叫權限系統= 使用者權限管理技能係統= 應用程式商店MCP 協定= 裝置驅動Agent 蜂群= 行程管理上下文壓縮= 記憶體管理Transcript 持久化= 檔案系統
這不是一個"聊天機器人加幾個工具",這是以LLM 為核心的作業系統。
總結
51 萬行程式碼。 1903 個文件。 18 個安全文件只為一個Bash 工具。
9 層審查只為讓AI 安全地幫你敲一行指令。
這就是Anthropic 的答案:要讓AI 真正有用,你不能把它關在籠子裡,也不能放它裸奔。你得給它建一套完整的信任體系。
而這套信任體系的代價,是51 萬行程式碼。

