Gary
Hsieh
2026 · taipeiloading
回到文章列表
軟體工程AI 趨勢2026-04-02

Gall’s Law 來看 Claude Code 原始碼 — 用基礎 Computer Science 的知識來分析

Gall’s Law 來看 Claude Code 原始碼 — 用基礎 Computer Science 的知識來分析

Gall’s Law 來看 Claude Code 原始碼 — 用基礎 Computer Science 的知識來分析

這一兩天大家都在分析 Claude Code 的 512K 行原始碼,一整天看完、分析後,心得是 — Claude Code Source 用的都是基礎的 Computer Science 可以解釋的工程技術。

用這個結論來看 Claude Code Source 就變得很直觀了:

  • LLM 就是 CPU
  • Context Window 就是 RAM
  • Prompt 就是程式碼
  • Agent 就是 Process

AI Harness 底層邏輯就是設計一套OS。

我挑了幾個來記錄一下,從原始碼裡來微觀整個 Computer Science:

《Prompt 怎麼管理》

1|.text/.data Section vs. Static + Dynamic Prompt 分離

設計目的:為了 Prompt Caching

  • 傳統:ELF binary 把 .text(唯讀程式碼)和 .data(可寫資料)分段,OS 可以跨 process 共享 .text page 省記憶體
  • AI Harness:System prompt 切成靜態段(工具定義、persona、安全規則)和動態段(session 狀態),中間用 SYSTEM_PROMPT_DYNAMIC_BOUNDARY 標記邊界

Why:靜態段永遠不變 → 每次 hit Anthropic 的 prompt cache → token 成本直接降 90%,回應延遲降低。好處:跟 OS 共享 .text page 省記憶體是同一個道理 — 不變的東西只算一次錢。

For What:我們在串 agent 的時候,不變的東西(工具定義、persona)放前面,會變的(使用者狀態)放後面 — 光這一步就能省一大筆錢錢錢。

程式碼在 constants/ 目錄,services/api/promptCacheBreakDetection.ts 追蹤多個 cache-break 向量。

2|Cache Invalidation vs. DANGEROUS_uncachedSystemPromptSection()

設計目的:為了防止工程師意外打破 Prompt Cache

  • 傳統:改了 cache key → 整個 cache line 失效;Rust 用 unsafe 區塊讓危險操作可見
  • AI Harness:函式命名 DANGEROUS_ 強迫開發者意識到「這段會打破所有使用者的 prompt cache」

Why:一個工程師在靜態段加了「2026/04/04 18:30」,全域 cache 就失效了。好處:用命名讓錯誤決策的成本顯而易見 — API 設計基本原理:「很容易用對、很難用錯」。

For What:我們的 prompt 裡有沒有不小心把會變的東西放在不該變的地方?每一個動態值都要問:值不值得為了這個打破 cache。

《Context 會爆,怎麼辦》

3|L1/L2/L3 Cache Hierarchy vs. 四階段 Context 壓縮管線

設計目的:為了分層淘汰 Context

  • 傳統:CPU 的 L1(最快最小)→ L2 → L3(最慢最大)→ disk swap,每級有不同的 eviction policy
  • AI Harness:tool result budgeting(L1)→ microcompact(L2)→ context collapse(L3)→ autocompact(L4)→ autoDream(disk),每級有不同豁免規則

Why:不是只有一種壓縮,是一整個分層的 eviction pipeline。好處:精確控制什麼留什麼丟。連續失敗 3 次自動停止(circuit breaker),三行 code 阻止每天浪費 250,000 次 API call。

For What:設計 agent 時要想清楚 context 的淘汰分級 — 哪些即時壓縮、哪些保留到 session 結束、哪些跨 session 持久化。

程式碼在 query.ts:379→413→440→453services/compact/microCompact.ts:41-51

4|Garbage Collection vs. autoDream 記憶精煉

設計目的:為了防止 Context Pollution

  • 傳統:JVM GC 回收不再被引用的物件,分代策略(Young GC 頻繁、Full GC 謹慎),GC thread 獨立於 application thread
  • AI Harness:autoDream 在使用者離線時啟動 forked subagent,跑四階段整理(定位 → 收集 → 合併 → 修剪到 200 行以內),三門觸發(24h + 5 sessions + lock)

Why:Context window 塞滿過時資訊 = memory leak,推理品質大幅下滑。好處:每次對話讀到的是精煉記憶,不是 50 個 session 的雜訊。

For What:我們的 agent 跑了 20 輪還塞著第一輪的垃圾?那就是 memory leak — 需要設計 context 的 GC 策略。

程式碼在 services/autoDream/services/autoDream/consolidationPrompt.ts

5|微服務 Circuit Breaker vs. Auto-Compact 失敗熔斷

設計目的:為了防止失敗重試雪崩

  • 傳統:微服務架構中連續失敗 N 次自動斷開呼叫
  • AI Harness:Context 壓縮連續失敗 3 次自動停止 — MAX_CONSECUTIVE_AUTOCOMPACT_FAILURES = 3

Why:1,279 個 session 有 50+ 次連續失敗,每天浪費 250,000 次 API call。好處:三行 code 阻止每天燒 25 萬次 API call。

For What:我們的 agent 有沒有某個操作在失敗時無限重試?加一個 circuit breaker 可能是 ROI 最高的三行 code。

程式碼在 services/compact/autoCompact.ts:68-70

《Agent 要跟外部互動》

6|System Call vs. Tool Use

設計目的:為了 Agent 的 I/O 權限控制

  • 傳統:Process 不能直接操作硬體,必須透過 syscall 請求 OS 代勞
  • AI Harness:Agent 不能直接執行 bash 或寫檔案,必須透過 tool call 請求 harness 代勞,每個 tool 自帶 permission 定義和風險分級

Why:所有危險操作都經過一層權限檢查 — 跟 user-space 不能直接碰硬體是同一個道理。好處:Tool schema cache 避免每次 API call 重新序列化 40+ 工具,直接省 token。

For What:我們設計 agent 的 tool 時,有沒有想過每個 tool 的權限分級?哪些 LOW risk 可以自動執行、哪些 HIGH risk 需要人工確認?

程式碼在 tool.tstools/ 40+ tools,tools/toolSchemaCache.ts

7|Interrupt Handler vs. Frustration Regex

設計目的:為了用最低成本偵測緊急信號

  • 傳統:硬體中斷讓 CPU 暫停當前任務,極低延遲處理緊急事件
  • AI Harness:一段 regex 偵測使用者憤怒(wtf、shit、so frustrating…),不用 LLM 判斷

Why:中斷必須極低延遲;情緒偵測必須極低成本 — 不要為了一句髒話呼叫一次 LLM。好處:Regex 比 LLM inference 快 1000 倍、便宜 1000 倍。

For What:不是所有問題都值得用 LLM 解決。我們的系統裡有哪些判斷可以用 Rule-based 邏輯搞定?

程式碼在 utils/userPromptKeywords.ts:7-8

8|Frame Buffer vs. Ink 終端渲染引擎

設計目的:為了 Token Streaming 的渲染效能

  • 傳統:顯示卡用雙緩衝、dirty rectangle、只重繪變化區域
  • AI Harness:Ink 引擎用 Int32Array ASCII pool + bitmask style metadata + patch optimizer,stringWidth 呼叫量減少 ~50x

Why:Token 一個字一個字流進來,跟遊戲 60fps 逐幀渲染是同一個效能挑戰。好處:遊戲引擎的渲染優化直接搬到終端 UI。

For What:如果我們的 AI 產品有 streaming 輸出,渲染效能就是 UX — 不是只有 model 速度重要。

程式碼在 ink/ 目錄,據 Alex Kim 分析引用 ink/screen.tsink/optimizer.ts

《Agent 不只一個》

9|fork() 子程序 vs. Subagent

設計目的:為了背景任務不汙染主 Agent

  • 傳統:Unix fork() 建立獨立子程序,有自己的 address space
  • AI Harness:autoDream 用 forked subagent 跑記憶整理 — 獨立 context window,read-only bash,主 agent 完全不受影響

Why:在主 agent 裡做記憶整理,整理過程的 token 會汙染當前對話(meta-cognitive noise)。好處:主 agent 不阻塞、不汙染。

For What:我們的 agent 有背景任務嗎?它跟主對話是共用 context 還是獨立的?共用 = 汙染。

程式碼在 services/autoDream/

10|Thread Pool vs. Multi-Agent Coordinator

設計目的:為了平行處理和任務品質

  • 傳統:Thread pool 分派 worker thread 平行執行
  • AI Harness:Coordinator 產生多個 worker agent 平行跑 Research → Synthesis → Implementation → Verification,prompt 明確教 LLM 平行思維,禁止懶惰委派

Why:Coordinator 必須做真正的 synthesis,不能當 pass-through。好處:獨立 context 互不汙染,平行度提升速度。

For What:我們在做 multi-agent 時,coordinator 有在做 synthesis 嗎?還是只是把 user 的話轉發給 worker?

程式碼在 coordinator/coordinatorMode.ts

11|Shared Memory / IPC vs. Scratchpad

設計目的:為了 Multi-Agent 的知識共享

  • 傳統:多個 process 透過 shared memory segment 交換資料
  • AI Harness:多個 worker agent 透過 scratchpad 目錄共享持久知識,私有 context 跟共享記憶清楚分開

Why:Multi-agent 必須解決溝通問題 — 誰能看到什麼。好處:清晰的共享 / 私有邊界,避免 worker 之間的 context 互相汙染。

For What:我們的 multi-agent 系統裡,哪些資訊是所有 agent 都該看到的?哪些是私有中間狀態?

程式碼在 coordinator/ 內,feature gate tengu_scratch

《Agent 行為能力邊界》

12|#ifdef 預處理器 vs. Compile-Time Feature Elimination

設計目的:為了 Agent 行為邊界安全(控制 agent「能做什麼」和「知道自己能做什麼」的邊界 — 不是靠 prompt 說「不要做」,是讓功能在構建時就不存在)

  • 傳統:C 的 #ifdef 在預處理階段移除程式碼,debug code 不存在於 release binary
  • AI Harness:Bun 的 feature() 在 bundle 階段把 KAIROS、BUDDY、Coordinator Mode 等從外部構建中物理移除 — 連一個 byte 都不佔

Why:以前 #ifdef 保護效能和 binary 大小;在 AI harness 裡保護的是行為邊界。好處:LLM 無法呼叫不存在的工具。移除 schema = 移除 agent 的認知 — 它不只是「不能做」,是「不知道可以做」。

For What:不該用的工具就別放進 prompt。移除 tool schema 比加一句「不要用這個工具」有效一萬倍。

程式碼 import { feature } from “bun:bundle”,12 個 compile-time flags。

13|Memory Protection (mprotect/munmap) vs. Agent Behavior Boundary

設計目的:為了不可繞過的權限控制

  • 傳統:mprotect() 設頁面 no-access(地址還在,可繞過)vs. munmap() 直接移除頁面(地址不存在,連 segfault 都不會發生)
  • AI Harness:Runtime feature flag(代碼還在,prompt injection 可能繞過)vs. Compile-time elimination(工具不存在,連嘗試呼叫的可能性都沒有)(USER_TYPE === ‘ant’ 判斷內部 vs 外部構建)

Why:我們不會對一個從未映射的地址發生 segfault;agent 不會嘗試呼叫一個從未定義的工具。好處:攻擊面是零 — 不是「被禁止」而是「從未存在」。

For What:設計 agent 權限時,想一下我們是在做 mprotect 還是 munmap — 前者有破口,後者沒有。

14|ACL / 權限控制 vs. Policy as Code

設計目的:為了做出可以用程式碼調整的安全邊界

  • 傳統:檔案權限寫在設定檔,由 OS 自動執行,有明確 owner
  • AI Harness:CYBER_RISK_INSTRUCTION 寫進 system prompt,有具名 owner(David Forsythe, Kyla Guru),修改需要 Safeguards team review

Why:安全規則不能是一份 Word 文件靠人遵守,要是機器自動執行的 code。好處:可審計、可版本化、有明確責任歸屬。

For What:我們的 agent 有哪些安全邊界?它們是寫在文件裡提醒自己,還是寫在 prompt 裡讓機器執行?

程式碼在 constants/cyberRiskInstruction.ts

15|Firewall Rule Chain vs. Bash Validator Chain Short-Circuit

設計目的:為了 Shell 指令安全驗證

  • 傳統:iptables 規則依序執行,過早的 ACCEPT 讓後面的 DROP 永遠不跑
  • AI Harness:25+ bash security validators 依序執行,validateGitCommit 回傳 allow → 短路所有後續 validator → ~/.bashrc 被覆寫(歷史漏洞

Why:安全檢查的執行順序本身就是攻擊面。好處:源碼註解自己記錄了歷史漏洞 — 每個 patch 暗示這類問題是系統性的。

For What:我們的 agent 如果有多層安全檢查,順序對嗎?有沒有某個 early-allow 會讓後面的檢查全部失效?

程式碼在 tools/BashTool/bashSecurity.ts:612, 2308-2378

16|Compiler Undefined Behavior vs. Three-Parser Differential

設計目的:為了理解多 Parser 的攻擊面

  • 傳統:同一段 C code 在 GCC 和 Clang 產生不同行為(undefined behavior)
  • AI Harness:同一條 bash 指令被三個 parser(splitCommand_DEPRECATED、tryParseShellCommand、ParsedCommand.parse)解析出不同結果。\r 在 JS regex 是 word separator,在 bash IFS 裡不是

Why:多個 parser 處理同一個輸入 = 差異就是攻擊面。好處:理解這個才知道為什麼 bash security 需要 25 個 validator — 沒有一個 parser 是完美的。

For What:我們的系統如果有多個地方解析同一個輸入(前端 vs. 後端、prompt vs. tool schema),差異就是漏洞。

程式碼在 bashSecurity.ts 內部註解。

17|Buffer Overflow vs. Context Poisoning via Compaction

設計目的:為了理解 AI 版的記憶體攻擊

  • 傳統:攻擊者寫入的資料溢出到函式返回地址,劫持控制流
  • AI Harness:CLAUDE.md 裡藏的惡意指令 → 被 autocompact 的 summarization 洗白成 “user feedback” → model 忠實執行,因為它以為這是使用者的意願

Why:程式邏輯沒有 bug,是記憶體佈局被利用了;model 沒有被 jailbreak,是 context 管理機制被利用了。好處:防禦 AI 攻擊不能只看 model output,要看 context 從哪裡來。

For What:我們的 agent 會讀外部檔案嗎?那些內容在 context 壓縮後還分得出「資料」和「指令」嗎?這是活生生 AI 版 buffer overflow。

程式碼在 services/compact/prompt.ts:359

《軟體防禦》

18|DRM / TPM vs. Native Client Attestation

設計目的:為了防止 API 被冒用

  • 傳統:TPM 晶片在硬體層驗證軟體是正版,軟體層看不到
  • AI Harness:Bun 的 Zig 底層在 HTTP 傳輸層把 cch=00000 覆寫為計算後的 hash — JS 層完全看不到這個替換

Why:認證發生在 JS runtime 之下,應用層代碼無法干預或偽造。好處:防止第三方工具冒充 Claude Code 偷用 subscription API。

For What:如果我們的 AI 產品有 API 認證需求,信任 root 應該放在哪一層 — 越低越難被繞過。

程式碼在 constants/system.ts:59-95NATIVE_CLIENT_ATTESTATION flag。

19|Honeypot vs. Anti-Distillation Fake Tools

設計目的:為了反模型蒸餾

  • 傳統:在系統中放假資料引誘攻擊者暴露身份
  • AI Harness:API 端注入假的 tool definition(anti_distillation: [‘fake_tools’]),正常使用者無感,錄製 API traffic 訓練模型的人會中招。第二層用密碼學簽名保護推理鏈

Why:不是阻止竊取,而是讓竊取到的東西有毒。好處:合法使用者完全不受影響,蒸餾者訓練出有毒模型。

For What:我們的 AI 產品有防蒸餾的考量嗎?Honeypot 思維比 DRM 思維更務實 — 擋不住複製,但可以汙染複製品。

程式碼在 services/api/claude.ts:301-313utils/betas.ts:279-298

《構建與部署》

20|Debug Symbol (.pdb) vs. Source Map (.map)

設計目的:(反面教訓)Build Pipeline 的最後一哩

  • 傳統:.pdb 檔從 crash dump 追回原始碼 — 不能進 release build
  • AI Harness:.map 檔從 minified JS 追回 TypeScript 原始碼 — 不能進 npm publish。但 .npmignore 忘了排除,整個原始碼就洩漏了(就像這次…)

Why:Compile-time elimination 完美移除了內部功能,但 source map 包含的是編譯前的原始碼 — 兩個不同管道的產物。好處:(反面教訓)治理不只是控制 runtime,還要控制 artifact 發佈管道。

For What:我們的 build pipeline 有沒有類似的「最後一哩」盲點?debug 產物、env 檔、log 檔 — 都查過了嗎?

回到 Gall’s Law

「一個能運作的複雜系統,必然是從一個能運作的簡單系統演化而來的」

Claude Code 不是一開始就 512K 行,它一定是從「一個 LLM + 一個 Bash tool + 一段 system prompt」開始,然後每一步解決一個具體問題:

  • prompt 太長 → 用 cache 分層
  • 記憶膨脹 → 加 GC
  • 要跟外部互動 → 加 tool + permission
  • 單 agent 不夠、控制記憶區塊 → 加 coordinator
  • 內外部分開 → 加 feature gate
  • 壓縮會失敗 → 加 circuit breaker
  • 有人要蒸餾 → 加 honeypot

每一步都是基礎 Computer Science。

從 Claude Code Source Code Leak 事件整理出來的心法

(1) Prompt 怎麼下

  • 把 system prompt 當 code 寫 — 要版本控制、要 code review、要測試。不是丟一段話進去就好
  • 先想清楚哪些內容是「永遠不變的」(persona、安全規則、工具定義),哪些是「每次都不同的」(使用者上下文、session 狀態)
  • 不變的放前面,會變的放後面 — 就這一個動作就能讓 prompt cache 命中
  • 每次想在 prompt 裡加東西之前問自己:「這個值會變嗎?」如果會,它不應該出現在靜態區

(2) 成本怎麼省

  • 靜態/動態分離 → prompt cache hit → token 成本降 90%
  • Tool schema 不用每次都全部塞進去 — 用 schema cache,或者只給當前任務需要的 tools
  • 加 circuit breaker — 任何會重試的操作都要設失敗上限。一個沒有 circuit breaker 的 autocompact 每天燒 25 萬次 API call,三行 code 就可解決
  • 不是所有判斷都需要 LLM — rule-based能做的事就用 rule,省下錢還有系統延遲

(3) Context 怎麼設計

  • Context window 就是 RAM — 有限的空間要管理,不然就是 memory leak
  • 設計淘汰分級:哪些資訊即時壓縮、哪些保留到 session 結束、哪些跨 session 持久化
  • 記憶需要 GC — 如果我們的 agent 沒有定期整理 context,20 輪對話後塞滿的是一堆垃圾跟大量的 Context Conflict
  • Context 來源要隔離 — 外部檔案讀進來的內容,在壓縮後還分得出「資料」和「指令」嗎?分不出來就是 buffer overflow 的 AI 版

(4) Agent 怎麼設計

  • Agent 是 process,不是整個系統 — 先設計 harness(OS),再在裡面跑 agent
  • 背景任務要用獨立的 subagent — 共用 context = 汙染。記憶整理、監控、排程都應該是獨立 process
  • Multi-agent 的 coordinator 要做 synthesis — 不能只當 pass-through 轉發訊息。讀完 worker 的結果,精確指示下一步
  • 共享記憶 vs. 私有記憶要分清楚 — scratchpad 放大家都該知道的,私有 context 放中間計算

(5) Tools 怎麼設計

  • 每個 tool 都是一個 syscall — agent 不能直接碰外部世界,必須透過 tool call 經過權限檢查
  • 不該用的工具就別放進 prompt — 移除 tool schema 比下 prompt 說「不要用這個工具」有效一萬倍
  • 每個 tool 要有風險分級 — 哪些可以自動執行、哪些需要人工確認,在設計時就決定好
  • Tool 的安全驗證要注意順序 — 一個過早的 allow 會讓後面所有檢查失效,跟防火牆 rule chain 一樣

用Computer Science 來看 Claude Code Source Code 意外有收穫🧘🧘🧘

#AI#Agent#LLM#Claude Code#Claude