<cite id="ffb66"></cite><cite id="ffb66"><track id="ffb66"></track></cite>
      <legend id="ffb66"><li id="ffb66"></li></legend>
      色婷婷久,激情色播,久久久无码专区,亚洲中文字幕av,国产成人A片,av无码免费,精品久久国产,99视频精品3
      網(wǎng)易首頁 > 網(wǎng)易號 > 正文 申請入駐

      面試官皺眉:“沒用過 Claude Code 也敢來?” 我不屑:“但我能寫一個!”,他愣了:等等我記一下…

      0
      分享至

        大家好,我是程序員魚皮 ?。

        堪稱全球最強的 AI 編程工具 Claude Code 的 50 多萬行源碼泄露了!一家以 AI 安全著稱的公司,自己卻在代碼發(fā)布環(huán)節(jié)翻了車。

        

        針對這件事,我只想說兩個字:

        感謝!

        

        這份源碼對學(xué)技術(shù)的同學(xué)來說簡直是寶藏資源啊,過年了過年了!

        那 Claude Code 源碼具體是怎么泄露的?源碼里有哪些精妙的設(shè)計?為什么它能做到 AI 編程工具的天花板?

        下面我利用 AI 帶大家一起學(xué)習(xí),學(xué)會它優(yōu)秀的設(shè)計后,你可以改進自己的 AI 項目、或者面試的時候吊打一下面試官。

        ?? 本文對應(yīng)視頻版:https://bilibili.com/video/BV1ZB9EBmEAU

         完整源碼我存了一份,想要獲取完整源碼的同學(xué)可以點我頭像,私信「claude」獲取,隨時可能被下掉,速速速

        到底是怎么泄露的

        Claude Code 是通過 npm 發(fā)布的,你可以把 npm 理解為程序員的「應(yīng)用商店」,開發(fā)者把寫好的工具打包上傳到這里,別人一行命令就能安裝。

        

        正常情況下,代碼上線之前會經(jīng)過「壓縮混淆」處理,變成一坨人類看不懂的東西。

        

        但在開發(fā)的時候,為了方便定位 Bug,代碼打包工具會自動生成一個叫Source Map的文件,它相當(dāng)于一張「翻譯對照表」,能把加密后的代碼還原成原始版本。但是這個文件只能在開發(fā)環(huán)境用,上線時必須刪掉!

        結(jié)果 Anthropic 的工程師在發(fā)布 Claude Code 2.1.88 版本的時候,打包工具 Bun 默認(rèn)生成了 Source Map 文件,而他們忘了在發(fā)布配置里把.map文件排除掉。于是一個 59.8 MB 的cli.js.map文件就這么被直接發(fā)到了公開的 npm 倉庫。

        

        這個 map 文件本質(zhì)上是一個 JSON,里面有兩個關(guān)鍵數(shù)組,sources存著所有文件的路徑,sourcesContent存著每個文件的完整源碼,兩者一一對應(yīng)。只要寫個腳本解析一下這個 JSON,按路徑把內(nèi)容寫出來,所有源碼就原樣還原了。

        而且據(jù)說 map 文件里甚至還引用了一個 Cloudflare R2 存儲桶的公開地址,點進去直接就能下載打包好的完整源碼目錄,連腳本都不用寫。

        

        安全研究員 Chaofan Shou 最先發(fā)現(xiàn)了這個問題并發(fā)到了 X 上:

        

        然后幾個小時之內(nèi) GitHub 上就冒出了好幾個鏡像倉庫,源碼傳遍了整個互聯(lián)網(wǎng),其中有個倉庫不到 1 天就快 10w Star 了(而且倉庫里早就沒有 Claude Code 源碼了)……

        更搞笑的是,去年 2 月 Claude Code 剛發(fā)布的時候就出過一模一樣的事故,同樣的錯誤犯了兩次!

        怕不是 Claude Code 團隊的開發(fā)者 Vibe Coding 上癮,連基本操作都忘了?

        源碼里都有什么

        這次泄露的是 Claude Code 客戶端的源碼,包括 1906 個 TypeScript 源文件、大約 51.2 萬行代碼。涵蓋了 Agent 循環(huán)引擎、40 多個內(nèi)置工具的完整實現(xiàn)、系統(tǒng)提示詞的組裝邏輯、記憶系統(tǒng)、上下文壓縮、權(quán)限管控機制,還有一堆沒上線的隱藏功能。但是不包括服務(wù)端的模型訓(xùn)練代碼和 API 后端邏輯。

        
      Claude Code 完整架構(gòu)

        整個項目用的是 React Ink 框架,簡單說就是用 React 來寫命令行界面,你可以理解為「在終端里寫網(wǎng)頁」。所以 Claude Code 的命令行交互才會比很多傳統(tǒng)工具絲滑。

        

        我用 AI 把它的架構(gòu)從上到下梳理了一遍,大致分為 6 層:

        1)最上面是 CLI 和界面層,你在終端里看到的所有交互都是這一層負(fù)責(zé)的

        2)往下是 Agent 循環(huán)引擎,你可以把它理解為 Claude Code 的大腦,所有的決策都從這里發(fā)出

        3)再往下是工具系統(tǒng),40 多個內(nèi)置工具加上 MCP 擴展

        4)然后是記憶系統(tǒng),解決 AI 聊著聊著就斷片兒的老毛病

        5)上下文壓縮系統(tǒng),解決 token 越來越貴、窗口越來越滿的問題

        6)最底層是權(quán)限和安全系統(tǒng)

        
      Claude Code 分層架構(gòu)圖

        接下來咱們結(jié)合源碼,看看每個模塊具體是怎么實現(xiàn)的,Claude Code 是怎么做到這么好用的?

        一、Agent 循環(huán)

        大家都知道現(xiàn)在的 AI 編程工具早已經(jīng)不是簡單的「一問一答」了,而是能連續(xù)執(zhí)行、自主完成任務(wù)的 AI Agent。

        可能有同學(xué)會覺得,這背后一定是什么特別復(fù)雜的架構(gòu),用了什么 AI Agent 開發(fā)框架、什么多 Agent 協(xié)作之類的吧?

        但我打開負(fù)責(zé)核心對話循環(huán)的query.ts文件一看,好家伙,最核心的代碼其實就是一個while(true)無限循環(huán)!

        // query.ts
      asyncfunction*queryLoop(params: QueryParams, consumedCommandUuids:string[]){
      letstate: State = {
      messages: params.messages,
      toolUseContext: params.toolUseContext,
      autoCompactTracking:undefined,
      maxOutputTokensRecoveryCount:0,
      hasAttemptedReactiveCompact:false,
      turnCount:1,
      // ...
      }

      // eslint-disable-next-line no-constant-condition
      while(true) {
      // 1. 上下文壓縮(防止 token 爆炸)
      // 2. 調(diào)用大模型,流式獲取響應(yīng)
      // 3. 解析模型返回的工具調(diào)用
      // 4. 執(zhí)行工具,獲取結(jié)果
      // 5. 把結(jié)果追加到對話歷史
      // 6. 如果沒有新的工具調(diào)用,結(jié)束;否則繼續(xù)循環(huán)
      }
      }

        就是這么樸素的一個循環(huán)。每一輪迭代里,程序先做上下文壓縮、再調(diào)用大模型拿到響應(yīng),如果模型說「我要用某個工具」就去執(zhí)行,把結(jié)果追加到對話歷史里,然后進入下一輪,一直循環(huán)工作直到活兒干完了才停下來。

        這在 AI 領(lǐng)域叫ReAct 機制(推理 + 執(zhí)行),讓 AI 自己形成「思考 → 行動 → 觀察 → 再思考」的閉環(huán)。Claude Code 的源碼就是這個理論最接地氣的工程實現(xiàn)了。

        

        每次循環(huán)中,程序會通過services/api/claude.ts里的queryModel函數(shù)來跟大模型溝通。這個函數(shù)負(fù)責(zé)發(fā)送請求、接收 SSE 流式輸出、累計 token 用量這些事情。模型返回的結(jié)果里如果包含tool_use類型的內(nèi)容,說明 AI 還想調(diào)用工具繼續(xù)干活,循環(huán)就接著轉(zhuǎn);如果沒有tool_use了,說明任務(wù)做完了,循環(huán)就結(jié)束。

        // services/api/claude.ts — 模型調(diào)用核心函數(shù)
      asyncfunction*queryModel(
      messages: Message[],
      systemPrompt: SystemPrompt,
      thinkingConfig: ThinkingConfig,
      tools: Tools,
      signal: AbortSignal,
      options: Options,
      ):AsyncGenerator{
      // 解析模型(含 Bedrock inference profile)
      // 合并 Beta headers
      // 構(gòu)造 anthropic.beta.messages 流式請求
      // 累計 token 用量
      // yield 流式事件
      }

        在這個循環(huán)定義的上方,還有一段 Anthropic 工程師留下的注釋,叫什么「巫師守則」:

        // query.ts — queryLoop 函數(shù)上方
      /**
      * The rules of thinking are lengthy and fortuitous...
      *
      * The rules follow:
      * 1. A message that contains a thinking block must be part of a query
      * whose max_thinking_length > 0
      * 2. A thinking block may not be the last message in a block
      * 3. Thinking blocks must be preserved for the duration of an assistant
      * trajectory
      *
      * Heed these rules well, young wizard. For they are the rules of thinking,
      * and the rules of thinking are the rules of the universe. If ye does not
      * heed these rules, ye will be punished with an entire day of debugging
      * and hair pulling.
      */

        這三條規(guī)則是關(guān)于模型思考過程(thinking block)的處理約束,大意就是「年輕的巫師啊,好好遵守這三條關(guān)于 thinking block 的規(guī)則,不然你將受到整整一天 debug 和拔頭發(fā)的懲罰」。

        我一時間分不清,這是程序員的浪漫,還是 AI 的浪漫?

        二、工具設(shè)計

        Claude Code 內(nèi)置了 40 多個工具,在負(fù)責(zé)工具注冊和管理的tools.ts文件里,有個getAllBaseTools()函數(shù)列出了所有內(nèi)置工具:

        // tools.ts — 工具注冊文件
      /**
      *NOTE:This MUST stay in sync with https://console.statsig.com/...
      * in order to cache the system prompt across users.
      */
      exportfunctiongetAllBaseTools():Tools{
      return[
      AgentTool, // 子 Agent 生成
      TaskOutputTool, // 任務(wù)輸出
      BashTool, // 執(zhí)行終端命令
      ...(hasEmbeddedSearchTools() ? [] : [GlobTool, GrepTool]),
      FileReadTool, // 讀文件
      FileEditTool, // 編輯文件
      FileWriteTool, // 寫文件
      NotebookEditTool, // 編輯 Notebook
      WebFetchTool, // 網(wǎng)絡(luò)請求
      WebSearchTool, // 網(wǎng)絡(luò)搜索
      TodoWriteTool, // 待辦事項
      SkillTool, // 技能調(diào)用
      EnterPlanModeTool,// 進入規(guī)劃模式
      ...(process.env.USER_TYPE ==='ant'? [ConfigTool] : []),
      // ... 還有幾十個,根據(jù)環(huán)境和 Feature Flag 動態(tài)加載
      ...(isToolSearchEnabledOptimistic() ? [ToolSearchTool] : []),
      ]
      }

        注意開頭那段注釋,意思是這份工具清單必須和他們的 A/B 測試配置中心保持同步,否則全球用戶共享的系統(tǒng)提示詞緩存就廢了??磥砉ぞ咦圆恢皇枪δ軉栴},還直接關(guān)系到成本和性能。

        還有最后一行的ToolSearchTool,當(dāng)用戶接了很多 MCP 插件、工具數(shù)量特別多的時候,Claude Code 不會把所有工具的完整描述都塞進系統(tǒng)提示詞里,而是先給模型一份「工具名 + 一句話介紹」的精簡清單,讓模型自己選需要哪些,再按需加載完整定義,從而節(jié)省了大量 token。

        代碼里還能看到process.env.USER_TYPE === 'ant'這個判斷,ant 是 Anthropic 內(nèi)部員工的代號(螞蟻),這說明 Anthropic 自己也在重度用 Claude Code 來開發(fā) Claude Code,怪不得這源碼一股 AI 味兒。

        每個具體的工具都是通過Tool.ts里的buildTool工廠函數(shù)創(chuàng)建的,這個函數(shù)有個很巧妙的默認(rèn)值設(shè)計

        // Tool.ts — 工具類型定義和工廠函數(shù)
      // Defaults (fail-closed where it matters):
      // - isConcurrencySafe → false (assume not safe)
      // - isReadOnly → false (assume writes)
      // - isDestructive → false
      // - toAutoClassifierInput → '' (skip classifier — security-relevant tools must override)
      constTOOL_DEFAULTS = {
      isEnabled:()=>true,
      isConcurrencySafe:(_input?: unknown) =>false,
      isReadOnly:(_input?: unknown) =>false,
      isDestructive:(_input?: unknown) =>false,
      toAutoClassifierInput:()=>'',
      // ...
      }

        注釋里寫的 「fail-closed where it matters」 是什么意思呢?

        可以看到isConcurrencySafeisReadOnly都默認(rèn)為false,也就是說如果某個工具的開發(fā)者忘了聲明「我只是讀個文件,不會改東西」,系統(tǒng)就自動把它當(dāng)成危險操作處理,不讓它并發(fā)執(zhí)行。

        這種思路叫做fail-closed(失敗時關(guān)閉),打個比方就像公司的門禁系統(tǒng),你沒刷卡默認(rèn)進不去;跟它相反的 fail-open 就像小區(qū)大門,誰來都讓進。

        對于 AI 應(yīng)用,你不知道它下一步會調(diào)用什么工具。在這種不確定性下,「默認(rèn)禁止」比「默認(rèn)允許」安全太多了。畢竟 Claude Code 直接操作你整個代碼庫,一旦出事兒可能是你半個月的代碼白寫了。

        還有toAutoClassifierInput默認(rèn)返回空字符串,意味著默認(rèn)跳過自動分類器檢查,但注釋專門強調(diào)了安全相關(guān)的工具必須自己重寫這個方法。這也是 fail-closed 的思路。

        三、讀寫分離的工具并發(fā)

        假設(shè) AI 同時想讀 3 個文件、再改 1 個文件,這 4 個操作是一個一個排隊跑、還是一起并發(fā)執(zhí)行呢?

        Claude Code 在負(fù)責(zé)工具執(zhí)行編排的toolOrchestration.ts里做了一套很聰明的讀寫分離機制。

        先看并發(fā)上限,默認(rèn)最多 10 個工具同時并發(fā),還可以通過環(huán)境變量調(diào)整:

        // services/tools/toolOrchestration.ts — 工具執(zhí)行編排
      functiongetMaxToolUseConcurrency():number{
      returnparseInt(process.env.CLAUDE_CODE_MAX_TOOL_USE_CONCURRENCY ||'',10) ||10
      }

        然后是核心的分批邏輯:

        // services/tools/toolOrchestration.ts
      functionpartitionToolCalls(toolUseMessages, toolUseContext):Batch[]{
      returntoolUseMessages.reduce((acc, toolUse) =>{
      consttool = findToolByName(toolUseContext.options.tools, toolUse.name)
      constparsedInput = tool?.inputSchema.safeParse(toolUse.input)
      constisConcurrencySafe = parsedInput?.success
      ?(() => {
      try{
      returnBoolean(tool?.isConcurrencySafe(parsedInput.data))
      }catch{
      returnfalse// 拋異常也當(dāng)不安全,又是 fail-closed
      }
      })()
      :false // 解析失敗也當(dāng)不安全

      if(isConcurrencySafe && acc[acc.length - 1]?.isConcurrencySafe) {
      acc[acc.length- 1].blocks.push(toolUse) // 合并到并發(fā)批次
      }else{
      acc.push({ isConcurrencySafe, blocks: [toolUse] }) // 新開一個批次
      }
      returnacc
      }, [])
      }

        簡單說就是連續(xù)幾個只讀工具可以一起跑,但一旦遇到寫操作,就得排隊等前面的都完成了才行。而且注意那個 try-catch,如果判斷方法本身拋了異常(比如參數(shù)解析出錯),也直接當(dāng)不安全處理。

        

        并發(fā)執(zhí)行完之后,產(chǎn)生的上下文修改contextModifier也不會立刻生效,而是先排隊存著,等一個批次的所有工具都跑完了再按順序依次應(yīng)用。

        在工具執(zhí)行編排文件的runTools函數(shù)里能看到這個邏輯:

        // services/tools/toolOrchestration.ts — runTools 函數(shù)
      if(isConcurrencySafe) {
      constqueuedContextModifiers = {}
      forawait(constupdate of runToolsConcurrently(blocks, ...)) {
      if(update.contextModifier) {
      // 先排隊,不立即應(yīng)用
      queuedContextModifiers[toolUseID].push(modifyContext)
      }
      }
      // 全部跑完后,按工具調(diào)用順序依次應(yīng)用
      for(constblock of blocks) {
      for(constmodifier of queuedContextModifiers[block.id]) {
      currentContext = modifier(currentContext)
      }
      }
      }

        學(xué)過數(shù)據(jù)庫的同學(xué)肯定覺得眼熟,這不就是「讀讀并行、讀寫互斥」的簡化版嘛。很多計算機底層的設(shè)計思想,換個場景照樣管用,這就是基礎(chǔ)知識的魅力。

        四、System Prompt 的緩存分裂

        Anthropic 的 API 支持 Prompt Cache 提示詞緩存,如果你每次發(fā)給模型的系統(tǒng)提示詞前半部分都不變,API 就能緩存這部分內(nèi)容,后續(xù)請求直接復(fù)用,不用重新處理。

        打開負(fù)責(zé)系統(tǒng)提示詞組裝的constants/prompts.ts文件,你會看到提示詞被一個叫DYNAMIC_BOUNDARY的標(biāo)記分成了上下兩部分:

        // constants/prompts.ts — 系統(tǒng)提示詞組裝
      exportconstSYSTEM_PROMPT_DYNAMIC_BOUNDARY =
      '__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__'

      sections = [
      // ...靜態(tài)部分:角色定義、行為規(guī)范、工具說明、語氣要求等
      // === BOUNDARY MARKER - DO NOT MOVE OR REMOVE ===
      ...(shouldUseGlobalCacheScope() ? [SYSTEM_PROMPT_DYNAMIC_BOUNDARY] : []),
      // --- Dynamic content (registry-managed) ---
      ...resolvedDynamicSections, // 動態(tài)部分:當(dāng)前時間、git 狀態(tài)、CLAUDE.md 配置、MCP 工具等
      ]

        Claude Code 用這條分界線精確地把提示詞切成兩半:上面是靜態(tài)部分,全球幾百萬用戶共享同一份緩存;下面是動態(tài)部分,比如你當(dāng)前的時間、你的 Git 倉庫狀態(tài)、你自己配的 CLAUDE.md 規(guī)則等等,每個用戶各不相同,獨立加載。

        源碼注釋里還專門警告,如果把動態(tài)內(nèi)容不小心混到了靜態(tài)部分里,每個用戶的提示詞都不一樣了,緩存就全廢了。

        // constants/prompts.ts
      // WARNING: Do not remove or reorder this marker without updating cache logic in:
      // - src/utils/api.ts (splitSysPromptPrefix)
      // - src/services/api/claude.ts (buildSystemPromptBlocks)

        如果你也在做 AI 應(yīng)用,調(diào)用量大的話,這個優(yōu)化技巧能幫你省不少錢。

        五、內(nèi)容檢索策略

        AI 模型本身沒有你項目的代碼記憶,所以需要一種方式讓它「看到」相關(guān)的代碼和文檔。

        現(xiàn)在業(yè)界最流行的做法叫 RAG 檢索增強生成,簡單說就是先把項目數(shù)據(jù)做 Embedding 存到向量數(shù)據(jù)庫里,用戶提問時先從數(shù)據(jù)庫里檢索出相關(guān)內(nèi)容,再連同問題一起發(fā)給模型回答。

        但沒想到,Claude Code 壓根不用這套!

        不管是搜記憶文件還是搜歷史對話,它用的都是最樸素的 Grep 文本搜索。

        在負(fù)責(zé)記憶系統(tǒng)的memdir/memdir.ts文件里有個buildSearchingPastContextSection函數(shù),寫得很明確:

        // memdir/memdir.ts — 記憶搜索指令
      constmemSearch =`grep -rn " " ${autoMemDir}--include="*.md"`
      consttranscriptSearch =`grep -rn " " ${projectDir}/ --include="*.jsonl"`

        Claude Code 的創(chuàng)始人 Boris Cherny 在播客里說過:俺們試過 RAG,但發(fā)現(xiàn)讓 AI 自己決定搜什么、怎么搜,效果反而遠遠好于 RAG。

        我的理解是這樣的,RAG 相當(dāng)于你幫實習(xí)生把相關(guān)資料都整理好了打包給他看;而 Agentic Search 是直接給他公司文檔庫的權(quán)限,讓他自己去找。模型能力越強,后者的優(yōu)勢就越大,因為 AI 比你更知道自己需要什么信息。而且 Grep 這種方案簡單、沒有索引過期問題、不用維護向量數(shù)據(jù)庫,工程復(fù)雜度直接降了一個量級。

        所以做 AI 應(yīng)用的時候,哪些能力該交給工程系統(tǒng)、哪些該留給 AI 模型,這個邊界值得好好想想。模型越來越強,很多以前需要復(fù)雜工程方案解決的問題,現(xiàn)在可能直接讓 AI 自己搞定就行了。

        六、三層記憶架構(gòu)

        這是我覺得整份源碼里設(shè)計最精妙的部分了,也是現(xiàn)在 Context Engineering 上下文工程領(lǐng)域最值得學(xué)的案例。

        用過 AI 編程工具的朋友應(yīng)該都體驗過:同一個對話框里聊久了,AI 就斷片兒了,忘了之前說過什么,甚至自相矛盾。

        Claude Code 為了解決這個問題,搞了一套分層記憶系統(tǒng),網(wǎng)上有人管它叫 Self-Healing Memory 自愈記憶。

        
      第一層、MEMORY.md(熱數(shù)據(jù),常駐加載)

        MEMORY.md 就像一本書的目錄,每次對話都會加載到上下文里。

        看看memdir/memdir.ts文件里是怎么限制它的大小的:

        // memdir/memdir.ts — 記憶索引文件
      exportconstENTRYPOINT_NAME ='MEMORY.md'
      exportconstMAX_ENTRYPOINT_LINES =200
      // ~125 chars/line at 200 lines. At p97 today; catches long-line indexes that
      // slip past the line cap (p100 observed: 197KB under 200 lines).
      exportconstMAX_ENTRYPOINT_BYTES =25_000

        最多 200 行、25KB,而且只存指針不存內(nèi)容,每行不超 150 字符。因為它每次都要占上下文窗口的位置,如果太大就會把有用的對話內(nèi)容擠掉。

        注釋里提到,25KB 那個字節(jié)限制是后來加的。因為他們發(fā)現(xiàn)有用戶雖然沒超 200 行,但每行寫了一大堆,200 行居然能寫到 197KB。所以不得不加個字節(jié)數(shù)的兜底保護。

        如果內(nèi)容超出限制了怎么辦?

        在這個文件里,還有一段詳細(xì)的截斷邏輯:

        // memdir/memdir.ts — 截斷邏輯
      exportfunctiontruncateEntrypointContent(raw:string):EntrypointTruncation{
      // 先按行數(shù)截斷
      lettruncated = wasLineTruncated
      ? contentLines.slice(0, MAX_ENTRYPOINT_LINES).join('\n')
      : trimmed
      // 再按字節(jié)數(shù)截斷,在最后一個換行符處切,避免截斷到一半
      if(truncated.length > MAX_ENTRYPOINT_BYTES) {
      constcutAt = truncated.lastIndexOf('\n', MAX_ENTRYPOINT_BYTES)
      truncated = truncated.slice(0, cutAt >0? cutAt : MAX_ENTRYPOINT_BYTES)
      }

      // 截斷后追加 WARNING,讓 AI 知道這個文件沒加載完
      return{
      content: truncated +
      `\n\n> WARNING:${ENTRYPOINT_NAME}is${reason}. Only part of it was loaded.`,
      }
      }

        采用行數(shù)截斷 + 字節(jié)截斷雙保險,截斷時還會在最后一個換行符處切開,不會切到一行的中間。截斷之后還追加了一條 WARNING,讓 AI 知道「這個索引沒加載完整」。這種細(xì)節(jié)才是 Claude Code 體驗好的原因。

        第二層、話題文件(溫數(shù)據(jù),按需加載)

        你的編碼偏好、項目的架構(gòu)約定、之前踩過的坑這些細(xì)節(jié)信息,都存在單獨的話題文件里,比如user_role.mdfeedback_testing.md。

        新對話開始時,Claude Code 會用 Sonnet 小模型來挑選最多 5 個跟當(dāng)前對話相關(guān)的文件加載進來。在負(fù)責(zé)記憶召回的findRelevantMemories.ts文件中,可以看到它挑選記憶的提示詞:

        // memdir/findRelevantMemories.ts — 記憶召回
      constSELECT_MEMORIES_SYSTEM_PROMPT =`You are selecting memories that will be
      useful to Claude Code as it processes a user's query.
      Return a list of filenames for the memories that will clearly be useful (up to 5).
      - If a list of recently-used tools is provided, do not select memories that are
      usage reference or API documentation for those tools (Claude Code is already
      exercising them). DO still select memories containing warnings, gotchas, or
      known issues about those tools — active use is exactly when those matter.`

        最后那條規(guī)則我覺得是 punchline:如果某個工具正在被使用,就不加載它的使用文檔(你都在用了說明你會用),但一定要加載它的已知問題和坑。想想也對,你正在用一個東西的時候,最怕的不就是不知道有什么坑嘛。

        而且 Claude Code 的記憶不記代碼。因為代碼會發(fā)生變化,但記憶并不會自動更新。舉個例子,如果記憶里說「函數(shù) X 在第 30 行」,你后來重構(gòu)了,這條記憶就變成誤導(dǎo)了。所以它只記人的偏好和判斷,代碼的事實永遠去源碼里實時讀取。

        做過后端開發(fā)的朋友都知道,緩存和數(shù)據(jù)庫不一致是最坑的 Bug 之一。Claude Code 的做法等于從根源上消滅了不一致的可能性。

        第三層、歷史對話(冷數(shù)據(jù),Grep 搜索)

        更早之前的歷史對話會被存成.jsonl格式的文件,需要的時候用 Grep 搜關(guān)鍵詞就能找到。

        總結(jié)一下,不同溫度的數(shù)據(jù)用不同方式管理。熱的常駐、溫的按需、冷的搜索。

        如果你面試被問到 “AI 應(yīng)用怎么做長期記憶”,這套方案絕對能讓面試官眼前一亮,畢竟 Claude Code 這種級別的產(chǎn)品都在用。

        七、五級上下文壓縮

        上一節(jié)講的是記憶怎么存和取,這一節(jié)講的是上下文怎么「瘦身」。大模型的上下文窗口是有上限的,隨著對話越來越長、工具調(diào)用結(jié)果越攢越多,token 用量會快速膨脹,不僅費錢,還可能直接超出窗口限制導(dǎo)致請求失敗。

        Claude Code 為了應(yīng)對這個問題,設(shè)計了五級壓縮策略,像漏斗一樣層層過濾:

         Snip 剪裁:最輕的一刀,把舊的工具調(diào)用結(jié)果只保留結(jié)構(gòu),不保留內(nèi)容

         Microcompact 微壓縮:把體積大的工具執(zhí)行結(jié)果卸載到緩存里。注意是卸載到緩存而不是直接丟掉,因為子智能體后續(xù)可能還需要這些結(jié)果

         Context Collapse 折疊:對中間的對話做折疊摘要,只保留關(guān)鍵信息

         Autocompact 自動壓縮:當(dāng)上下文占用超過閾值時,觸發(fā)全量摘要壓縮

         Reactive Compact 應(yīng)急壓縮:最后的兜底,當(dāng) API 返回 413 “提示詞太長” 錯誤時緊急觸發(fā)

        

        這五級從輕到重依次觸發(fā),能裁掉的內(nèi)容先裁掉,實在不夠了再上更重的方案。

        從query.ts文件的開頭可以看到其中三級壓縮模塊通過 Feature Flag 按需引入(另外兩級在其他文件里):

        // query.ts — 壓縮模塊按需加載
      constreactiveCompact = feature('REACTIVE_COMPACT')
      ?require('./services/compact/reactiveCompact.js') :null
      constcontextCollapse = feature('CONTEXT_COLLAPSE')
      ?require('./services/contextCollapse/index.js') :null
      constsnipModule = feature('HISTORY_SNIP')
      ?require('./services/compact/snipCompact.js') :null

        這里面還有個「斷路器」機制讓我印象深刻,在負(fù)責(zé)自動壓縮的services/compact/autoCompact.ts文件里:

        // services/compact/autoCompact.ts — 斷路器
      // Stop trying autocompact after this many consecutive failures.
      // BQ 2026-03-10: 1,279 sessions had 50+ consecutive failures
      // (up to 3,272) in a single session, wasting ~250K API calls/day globally.
      constMAX_CONSECUTIVE_AUTOCOMPACT_FAILURES =3

        看到注釋中的那串?dāng)?shù)字了嗎?

        2026 年 3 月 10 號他們統(tǒng)計發(fā)現(xiàn)有 1279 個會話連續(xù)壓縮失敗了 50 次以上,最夸張的一個會話連續(xù)失敗了 3272 次還在不停重試,全球每天浪費 25 萬次 API 調(diào)用!

        要是讓我這種老倒霉蛋遇上了,光 token 費就夠我吃一個月的了,這要是曝光出來公關(guān)團隊怕是有的忙了……

        所以他們加了這個斷路器,連續(xù)失敗 3 次就自動停下來。

        八、安全審查

        用 Claude Code 的時候你可以開啟--dangerously-skip-permissions模式(也叫 YOLO 模式),跳過所有權(quán)限確認(rèn),讓 AI 自己干活。

        我之前一直以為這模式就是完全不設(shè)防了,看了源碼才知道,其實背后還偷偷跑著一個「影子 AI」在幫你把關(guān)。

        源碼里有個文件叫utils/permissions/yoloClassifier.ts,每次主 AI 要執(zhí)行操作,這個獨立的 AI 分類器都會過一遍:

        // utils/permissions/yoloClassifier.ts — YOLO 安全分類器
      exportasyncfunctionclassifyYoloAction(
      toolName:string,
      toolInput: Record,
      // ...
      ):Promise<'allow' | 'soft_deny' | 'hard_deny'>{
      // 用一個獨立的模型來判斷這個操作安不安全
      // allow: 安全的,直接放行
      // soft_deny: 有風(fēng)險,降級成需要手動確認(rèn)
      // hard_deny: 直接攔截,沒得商量
      }

        而且權(quán)限系統(tǒng)不只有 YOLO Classifier 一個檢查點。一次工具調(diào)用要過的關(guān)卡至少包括:

         你當(dāng)前的運行模式(Plan / Auto / Bypass)

         用戶在 hooks 里設(shè)的自定義規(guī)則

         YOLO Classifier 的模型分析

         Bash 命令危險度分類(像 rm -rf 這種直接攔截)

         配置文件里的規(guī)則引擎

        多個來源的權(quán)限結(jié)果還有競爭關(guān)系,最終取最嚴(yán)格的那個。

        

        其中第 4 點 Bash 命令安全檢查的嚴(yán)格程度遠超我的預(yù)期。在tools/BashTool/bashSecurity.ts這個文件里,定義了23 種安全檢查規(guī)則:

        // tools/BashTool/bashSecurity.ts — Bash 安全檢查 ID
      constBASH_SECURITY_CHECK_IDS = {
      INCOMPLETE_COMMANDS:1, // 殘缺命令(以 tab 或 - 開頭)
      JQ_SYSTEM_FUNCTION:2, // jq 的 system() 函數(shù)調(diào)用
      OBFUSCATED_FLAGS:4, // 混淆的命令行參數(shù)
      SHELL_METACHARACTERS:5, // 危險的 shell 元字符
      DANGEROUS_VARIABLES:6, // 危險環(huán)境變量注入
      IFS_INJECTION:11, // IFS 變量注入
      PROC_ENVIRON_ACCESS:13, // /proc/environ 訪問
      CONTROL_CHARACTERS:17, // 控制字符
      UNICODE_WHITESPACE:18, // Unicode 空白字符欺騙
      ZSH_DANGEROUS_COMMANDS:20, // Zsh 危險命令(zmodload 等)
      COMMENT_QUOTE_DESYNC:22, // 注釋與引號狀態(tài)不同步
      QUOTED_NEWLINE:23, // 引號內(nèi)換行
      // ... 共 23 種
      }

        比如第 18 條的UNICODE_WHITESPACE,說明 Anthropic 的安全團隊考慮過用 Unicode 零寬空格來混淆命令的攻擊手法,讓安全檢查器看到的和 shell 實際執(zhí)行的不是同一條命令。還有第 20 條針對 Zsh 的zmodload命令,這個命令能加載模塊繞過常規(guī)的文件和網(wǎng)絡(luò)檢查,總之防護做的還是很周到的。

        怪不得我開著全部放行模式用了這么久,從來沒出過什么嚴(yán)重事故,原來是有一套多層機制在背后替我負(fù)重前行。

        九、Feature Flag 和未來功能

        在 Claude Code 的源碼中,你會經(jīng)常看到feature('XXX')的判斷:

        // tools.ts — Feature Flag 條件加載
      constSleepTool = feature('PROACTIVE') || feature('KAIROS')
      ?require('./tools/SleepTool/SleepTool.js').SleepTool :null

      constWebBrowserTool = feature('WEB_BROWSER_TOOL')
      ?require('./tools/WebBrowserTool/WebBrowserTool.js').WebBrowserTool :null

        這就是 Feature Flag 功能開關(guān),做開發(fā)的同學(xué)應(yīng)該都不陌生。每個實驗功能都藏在開關(guān)后面,可以按用戶、按環(huán)境灰度發(fā)布。這樣萬一出了問題,就不用回滾代碼,直接關(guān)掉開關(guān)就行。通過條件require,關(guān)掉的功能在打包時還能被 tree-shaking 掉,不增加體積。

        有趣的是,這些 Feature Flag 等于無意中泄露了 Claude Code 的產(chǎn)品路線圖:

        1)KAIROS:長期助手模式,AI 可以 24 小時持續(xù)運行不結(jié)束。里面還有個 AutoDream 自動做夢功能,名字起得很是浪漫,說白了就是 AI 白天干活記筆記,晚上自動整理記憶。

        2)COORDINATOR_MODE:多 Agent 協(xié)作,一個 AI 指揮多個 AI 干活。

        從coordinatorMode.ts能看到,它的工作流分四個階段:

        // coordinator/coordinatorMode.ts — 協(xié)調(diào)者工作流定義
      | Phase | Who | Purpose |
      |----------------|--------------------|---------------------------------------------------------|
      | Research | Workers (parallel) | Investigate codebase, find files, understand problem |
      | Synthesis | You (coordinator) | Read findings, craft implementation specs |
      | Implementation | Workers | Make targeted changes per spec, commit |
      | Verification | Workers | Test changes work |

        子智能體之間通過utils/mailbox.ts里的 Mailbox(一個基于文件的消息隊列)來通信。

        還有 VOICE_MODE 語音模式、WEB_BROWSER_TOOL 瀏覽器操作工具等等。

        十、反蒸餾和臥底模式

        Anthropic 為了防止競爭對手竊取 Claude Code 的能力、以及防止內(nèi)部信息通過開源貢獻泄露,在源碼里埋了兩套防御機制。(但沒想到這波泄露了個大的 )

        先說反蒸餾。有些競爭對手可能會通過錄制 Claude Code 的 API 流量來「蒸餾」它的能力,就是把大模型的輸入輸出錄下來,用來訓(xùn)練自己的小模型。

        Anthropic 的應(yīng)對策略簡直絕了,直接往 API 請求里注入假工具定義:

        // services/api/claude.ts — 負(fù)責(zé)模型 API 調(diào)用
      // Anti-distillation: send fake_tools opt-in for 1P CLI only
      if(feature('ANTI_DISTILLATION_CC')
      && process.env.CLAUDE_CODE_ENTRYPOINT ==='cli'
      && shouldIncludeFirstPartyOnlyBetas()
      ) {
      result.anti_distillation = ['fake_tools']
      }

        做防御不是單純加密或者限速,而是主動給你喂假數(shù)據(jù),讓你拿去訓(xùn)練的模型越訓(xùn)越差,有點兒反間計的意思。

        而且它只在 Anthropic 官方的命令行客戶端,也就是你在終端里直接用claude命令的場景中才生效,通過 SDK 或其他方式接入的不受影響。

        再說臥底模式,Anthropic 內(nèi)部員工用 Claude Code 往開源項目提交代碼時,會自動啟用這個模式:

        // utils/undercover.ts — 負(fù)責(zé)隱藏 AI 貢獻痕跡
      /**
      * Undercover mode — safety utilities for contributing to public repos.
      * When active, Claude Code strips all attribution to avoid leaking internal
      * model codenames, project names, or other Anthropic-internal information.
      * The model is not told what model it is.
      *
      * There is NO force-OFF. This guards against model codename leaks.
      */

      exportfunctionisUndercover():boolean{
      if(process.env.USER_TYPE ==='ant') {
      if(isEnvTruthy(process.env.CLAUDE_CODE_UNDERCOVER))returntrue
      // Auto: active unless we've confirmed we're in an internal repo.
      returngetRepoClassCached() !=='internal'
      }
      returnfalse
      }

        注釋里寫得很明確:「There is NO force-OFF」,不能強制關(guān)閉。而且從代碼邏輯看,默認(rèn)就是開啟的,只有當(dāng)倉庫被確認(rèn)為內(nèi)部倉庫時才會關(guān)掉。說明 Anthropic 非常擔(dān)心內(nèi)部模型代號通過開源貢獻泄露出去。

        十一、其他細(xì)節(jié)

        最后分享幾個源碼里藏著的有趣細(xì)節(jié)。

        1)在buddy/目錄下,Anthropic 的工程師居然偷偷藏了一套數(shù)字寵物系統(tǒng)!

        一共 18 種物種,從鴨子到仙人掌應(yīng)有盡有:

        // buddy/types.ts — 虛擬寵物物種定義
      exportconstSPECIES = [
      duck, goose, blob, cat, dragon, octopus, owl, penguin,
      turtle, snail, ghost, axolotl, capybara, cactus, robot,
      rabbit, mushroom, chonk,
      ]asconst

        這個功能原本計劃 4 月份作為彩蛋預(yù)熱、5 月正式上線,結(jié)果源碼泄露了提前被大家發(fā)現(xiàn)了。AI 寫代碼寫累了,然后擼擼 AI 寵物,Anthropic 的工程師也太會整活了。

        2)還有個小細(xì)節(jié),因為 Claude 之前老是浪費一輪對話去執(zhí)行mkdir檢查目錄存不存在,工程師們直接在memdir/memdir.ts里硬編碼了一行提示,告訴 AI “這個目錄已經(jīng)存在了,直接用 Write 工具往里寫就行,不要再跑 mkdir 或者檢查目錄是否存在了!”

        // memdir/memdir.ts
      // Shipped because Claude was burning turns on `ls`/`mkdir -p` before writing.
      exportconstDIR_EXISTS_GUIDANCE =
      'This directory already exists — write to it directly with the Write tool
      (do not run mkdir or check for its existence).'

        3)Claude Code 對啟動速度有一種近乎偏執(zhí)的追求。

        比如在入口文件cli.tsx里,--version這種最簡單的請求一個模塊都不加載,直接返回;其他路徑全部用await import()動態(tài)加載,按需引入。

        更絕的是,在加載主模塊的這幾百毫秒里,它會同時啟動一個「早期輸入捕獲器」(utils/earlyInput.ts),把你在等待時敲的鍵都緩存起來,模塊加載完之后再回放,讓你感覺 “剛敲完就有反應(yīng)了”。

        初始化階段還會偷偷發(fā)一個 TCP 預(yù)連接(utils/apiPreconnect.ts),讓 TCP+TLS 握手和初始化工作并行跑,省掉 100ms 左右的等待時間。

        // utils/apiPreconnect.ts — TCP 預(yù)連接
      /**
      * Preconnect to the Anthropic API to overlap TCP+TLS handshake with startup.
      * The TCP+TLS handshake is ~100-200ms that normally blocks inside the first
      * API call. Kicking a fire-and-forget fetch during init lets the handshake
      * happen in parallel with action-handler work.
      */
      最后聊幾句

        看完這份源碼,你會發(fā)現(xiàn) Claude Code 里其實沒什么驚天動地的新算法,用的基本上都是程序員接觸過的基礎(chǔ)知識,比如并發(fā)控制、讀寫分離、分層緩存、斷路器、功能開關(guān)等等……

        但是 Claude Code 團隊把這些東西組合到了 AI 場景里,打造出了一個極其優(yōu)秀的產(chǎn)品,所以說計算機的基礎(chǔ)知識和設(shè)計思想很重要。

        這份源碼也是目前最好的 AI 應(yīng)用架構(gòu)教材了。像 Agent 循環(huán)怎么寫、工具系統(tǒng)怎么設(shè)計、記憶怎么管理、安全怎么做,答案全在里面。簡歷上如果能寫上 “深度閱讀了 Claude Code 源碼并應(yīng)用于自己的項目”,那絕對是加分項。

        至于說這次泄露對 Claude Code 有多大影響嘛…… 我覺得其他做 AI 編程工具的競爭對手們肯定開心壞了,大家也學(xué)到知識(吃到瓜)了,我也有流量了,用 Claude Code 的人更多了,可以說是皆大歡喜。

        而且就算有人家的源碼,也很難跟人家這種有資源的專業(yè)團隊去競爭呀,你就像我開源出來一個 yupi-code 估計也沒人用吧?

        話說我最近正好在自己的 魚皮 AI 導(dǎo)航網(wǎng)站 上更新 Claude Code 相關(guān)的教程,萬萬沒想到竟然從源碼開始講起了。如果你想更系統(tǒng)地學(xué)習(xí) AI 編程工具的使用方法、項目實戰(zhàn)、經(jīng)驗技巧和原理,可以關(guān)注一波,后續(xù)持續(xù)更新。

      特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺“網(wǎng)易號”用戶上傳并發(fā)布,本平臺僅提供信息存儲服務(wù)。

      Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

      相關(guān)推薦
      熱點推薦
      四川省公安廳原廳長葉寒冰被公訴,曾被通報“利用職權(quán)為親屬謀利”

      四川省公安廳原廳長葉寒冰被公訴,曾被通報“利用職權(quán)為親屬謀利”

      界面新聞
      2026-04-07 10:54:17
      張雪那位畢業(yè)于廈大的母親,被罵慘了

      張雪那位畢業(yè)于廈大的母親,被罵慘了

      迷世書童H9527
      2026-04-07 23:04:57
      當(dāng)年的陳紅,在陳凱歌家里慵懶一躺,躺贏了

      當(dāng)年的陳紅,在陳凱歌家里慵懶一躺,躺贏了

      科學(xué)發(fā)掘
      2026-04-06 13:06:17
      香港樓市,那是真的爆。

      香港樓市,那是真的爆。

      櫻桃大房子
      2026-04-07 22:16:49
      李賽鳳趁丈夫出差,和體格壯碩的干兒子發(fā)生了親密接觸

      李賽鳳趁丈夫出差,和體格壯碩的干兒子發(fā)生了親密接觸

      西樓知趣雜談
      2026-01-20 17:11:19
      2005年《神話》重慶宣傳,為爭奪金喜善,文強與山西首富大打出手

      2005年《神話》重慶宣傳,為爭奪金喜善,文強與山西首富大打出手

      干史人
      2026-03-27 10:00:07
      回顧“91女神”琪琪:五官出眾,卻因天真讓自己“受傷”

      回顧“91女神”琪琪:五官出眾,卻因天真讓自己“受傷”

      就一點
      2025-11-22 10:36:39
      就業(yè)比土木還爛的幾個專業(yè),誰選誰后悔!

      就業(yè)比土木還爛的幾個專業(yè),誰選誰后悔!

      黯泉
      2026-04-07 21:32:40
      零緩沖,全國一刀切!6月1日起,車主自己去車管所“橫著走”!

      零緩沖,全國一刀切!6月1日起,車主自己去車管所“橫著走”!

      西莫的藝術(shù)宮殿
      2026-04-08 03:16:59
      3月新勢力銷量榜:零跑破5萬登頂,“蔚小理”時代終結(jié)

      3月新勢力銷量榜:零跑破5萬登頂,“蔚小理”時代終結(jié)

      玩車專家1
      2026-04-06 12:07:25
      詐尸了!哈梅內(nèi)伊死而復(fù)生?特朗普大秀軍功,伊朗做出了一個舉動

      詐尸了!哈梅內(nèi)伊死而復(fù)生?特朗普大秀軍功,伊朗做出了一個舉動

      起喜電影
      2026-04-07 16:21:57
      以色列宣布已停止所有對法國防采購

      以色列宣布已停止所有對法國防采購

      財聯(lián)社
      2026-04-05 22:04:05
      鄭麗文緩緩走下飛機,時隔20年再次來到大陸,這次是自己率團

      鄭麗文緩緩走下飛機,時隔20年再次來到大陸,這次是自己率團

      大江
      2026-04-07 16:37:01
      瞞不??!武漢清明數(shù)據(jù)炸裂,游客堵到手機沒電,核心原因終于曝光

      瞞不?。∥錆h清明數(shù)據(jù)炸裂,游客堵到手機沒電,核心原因終于曝光

      我不叫阿哏
      2026-04-07 20:39:33
      孔帕尼神了:終結(jié)14年魔咒,諾伊爾一戰(zhàn)封神,維尼修斯7射門0進球

      孔帕尼神了:終結(jié)14年魔咒,諾伊爾一戰(zhàn)封神,維尼修斯7射門0進球

      足球狗說
      2026-04-08 05:39:17
      光學(xué)窗口巨大!美軍絕密無人機剛從伊朗返航,就被人拍了個精光

      光學(xué)窗口巨大!美軍絕密無人機剛從伊朗返航,就被人拍了個精光

      溫讀史
      2026-04-08 06:47:38
      喝一箱牛奶不如吃一碗它,中老年常吃,隨手一煮就香

      喝一箱牛奶不如吃一碗它,中老年常吃,隨手一煮就香

      開心美食白科
      2026-04-07 18:55:02
      香蕉被點名!醫(yī)生:香蕉放黑 2 天,抗性淀粉翻倍,控糖護腸

      香蕉被點名!醫(yī)生:香蕉放黑 2 天,抗性淀粉翻倍,控糖護腸

      岐黃傳人孫大夫
      2026-04-06 21:25:03
      為了伊朗,法國時隔37年首次投出反對票

      為了伊朗,法國時隔37年首次投出反對票

      遠方青木
      2026-04-07 23:59:18
      安慶6歲失聯(lián)女童確認(rèn)遇害,嫌疑人柳某某(女,35歲)被抓,指認(rèn)現(xiàn)場引圍觀一度交通堵塞,女童父親不愿多言,鎮(zhèn)政府:一直在安撫家屬情緒

      安慶6歲失聯(lián)女童確認(rèn)遇害,嫌疑人柳某某(女,35歲)被抓,指認(rèn)現(xiàn)場引圍觀一度交通堵塞,女童父親不愿多言,鎮(zhèn)政府:一直在安撫家屬情緒

      極目新聞
      2026-04-07 12:16:29
      2026-04-08 07:31:00
      程序員魚皮 incentive-icons
      程序員魚皮
      一手科技資訊和編程干貨
      84文章數(shù) 83關(guān)注度
      往期回顧 全部

      科技要聞

      滿嘴謊言!OpenAI奧特曼黑料大起底

      頭條要聞

      特朗普稱美方正就伊朗戰(zhàn)爭進行“激烈談判”

      頭條要聞

      特朗普稱美方正就伊朗戰(zhàn)爭進行“激烈談判”

      體育要聞

      霸氣!趙心童:斯諾克的未來定屬于中國 20年后50%選手都是中國人

      娛樂要聞

      女首富陳麗華離世 被曝生前已分好遺產(chǎn)

      財經(jīng)要聞

      10萬億財政轉(zhuǎn)移支付,被誰拿走了?

      汽車要聞

      不止是大 極狐首款MPV問道V9靜態(tài)體驗

      態(tài)度原創(chuàng)

      藝術(shù)
      健康
      游戲
      本地
      公開課

      藝術(shù)要聞

      李苦禪這簡簡幾筆,能讓你歡快一整天

      干細(xì)胞抗衰4大誤區(qū),90%的人都中招

      PS3模擬器重大突破!全游戲性能迎來飛躍

      本地新聞

      跟著歌聲游安徽,聽古村回響

      公開課

      李玫瑾:為什么性格比能力更重要?

      無障礙瀏覽 進入關(guān)懷版