Claude Code 真正厲害的不是某一段神秘 prompt,而是一整套把 prompt、tool、permission、agent、memory 統一起來的工程系統。

先講結論

2026 年 3 月 31 日,Claude Code 的 512,000 行 TypeScript 原始碼意外洩漏。

大家第一反應是找有沒有藏什麼神奇 prompt。結果發現:沒有。

它厲害的地方是一套 Agent Operating System——把確定性的工程系統包在機率性的 LLM 外面,讓整體行為變得可預測、可治理。

這篇不是功能介紹,而是從原始碼分析整理出來的設計哲學筆記——這些決策為什麼這樣做,以及做 AI 產品的時候可以學什麼。


第一個關鍵轉換:從確定性到機率性

Web 開發是確定性的:你寫一個函數,給固定 input,永遠回傳固定 output。架構圖是靜態的,資料流可預測,debug 就是找「哪行壞了」。

AI agent 是機率性的:LLM 的輸出每次都可能略有不同。「邏輯」是用自然語言寫的,「debug」是調文字,「架構」的核心是怎麼讓模型做出正確決策。

Claude Code 的解法很清楚:LLM 決定「做什麼」,程式決定「允不允許」,然後執行。把機率性的部分隔離在 LLM 裡,外面用工程系統做治理。


Agent Loop:骨幹很簡單

while (true) {
  呼叫 Claude API
  if (stop_reason == "tool_use") {
    執行工具
    把 tool_result 追加到 messages[]
    繼續循環
  } else {
    回傳文字給使用者
    break
  }
}

這就是整個 agent 的骨幹,query.ts 裡的 while-true 迴圈。

真正的工程量在外面那層 harness:permission 系統、streaming 處理、context 壓縮、sub-agent 編排、memory 管理——每一層都是獨立解決一個問題。

為什麼用 AsyncGenerator:token 透過 yield 流出,tool call 是遞歸的,中斷也很乾淨。比用 callback 或 state machine 簡單很多,而且天生支援 streaming。


Tool 設計:每個工具是一個治理單元

工具不是「直接裸調」,每個 tool 都有自己的生命週期:

validateInput()     → 最早失敗,拒絕無效參數
checkPermissions()  → 工具專屬授權檢查
call()              → 執行並回傳結果

而且每個工具必須聲明自己的能力屬性:

屬性問的問題
isConcurrencySafe()可以和其他工具同時跑嗎?
isReadOnly()有沒有副作用?
isDestructive()不可逆嗎?
interruptBehavior()中斷時應該怎麼處理?

為什麼重要StreamingToolExecutor 靠這些屬性決定哪些工具可以在 streaming 還沒結束時就並行執行。這不是效能優化,是架構決策——讓 agent 的操作感完全不同。


Permission System:不是開關,是決策鏈

validateInput()
    ↓
PreToolUse Hooks(使用者定義,可批准 / 拒絕 / 修改輸入)
    ↓
規則比對(alwaysAllow / alwaysDeny / alwaysAsk)
    ↓
(沒有規則命中)→ 互動式提示
    ↓
checkPermissions()(工具專屬邏輯,路徑沙盒等)
    ↓
tool.call()

這個設計讓 agent 可以在「自動執行」和「需要人類確認」之間做細緻控制,不是二元開關,是一個可配置的決策鏈。

YOLO Mode 的真相:名字叫 YOLO,但它其實是一個 ML-based 快速分類器,自動判斷是否允許某個操作。不是「允許一切」,命名有點誤導。


System Prompt:靜態 + 動態分層

很多人以為 AI 產品的核心是一段超厲害的 system prompt。Claude Code 的答案是:不是文字,是動態組裝架構

getSystemPrompt() {
  // 靜態前綴(適合 prompt cache)
  身份定義、基礎系統規範、工具使用規範 ...

  // 動態後綴(按 session 條件注入)
  session_guidance、memory_prompt、env_info、
  language_preference、mcp_instructions、token_budget ...
}

SYSTEM_PROMPT_DYNAMIC_BOUNDARY 這個 marker 把 prompt 切成靜態和動態兩段——靜態部分可以被 prompt cache 命中,大幅降低費用。

還有一個函數叫 DANGEROUS_uncachedSystemPromptSection()命名本身就說明這是踩過坑學到的。DANGEROUS_ 前綴是他們用命名來表達架構約束的慣例,比寫文件更有效。


Memory:Index 而非 Storage

MEMORY.md(永遠在 context,~150 字/行,只存指針)
    ↓
topic files(按主題分檔的實際內容)
    ↓
daily logs(原始觀察,autoDream 的輸入來源)

核心原則:Memory 是 index,不是 storage。 MEMORY.md 保持 ≤ 200 行 / 25KB。

他們還做了一個叫 Dream System 的東西。是的,字面意義的「做夢」——在使用者閒置時,agent 在背景跑 memory consolidation,把零散的觀察整合成結構化的記憶。

三門觸發條件(三個同時滿足才跑):

  1. 時間門:距上次 dream 超過 24 小時
  2. Session 門:至少 5 個 session 後
  3. Lock 門:取得 consolidation lock,防並發

Sub-Agent:乾淨的 Context 隔離

主 Agent
  ├── Fork Agent(子進程,全新 messages[],共享 file cache)
  ├── Remote Agent(透過 bridge,完全隔離)
  └── In-Process Teammate(同一進程,共享狀態)

關鍵設計:子 agent 有自己的 messages[],不污染主對話。每個子任務在乾淨的 context 裡思考,失敗也不影響主 agent。

Fork 的 cache 優勢:子 agent 的 context 是主 agent 的 byte-for-byte 複製,API 可以 cache 這個共享部分——spawn 5 個並行 agent 的費用接近 1 個循序 agent。


Context Compaction:Context 是有限資源,要精打細算

Context 滿了怎麼辦?不是直接截斷,而是五種策略按壓力程度選擇:

  1. snipCompact — 移除重複 system message 和過時標記
  2. microCompact — 選擇性修剪最近的 tool result
  3. autoCompact — 用另一個 API call 總結舊訊息
  4. contextCollapse — 重構整個 context
  5. 截斷 — 最後手段

目標是盡量保留最多有用的資訊,不是能省就省。


一個值得特別記住的工程決策

Claude Code 上新模型(代號 Capybara)的時候遇到一個問題:模型在 tool result 之後有過早停止生成的 bug。

解法不是等模型修好,而是prompt shape surgery

  • 注入 Tool loaded. sentinel 建立安全 boundary
  • 重排 token 順序避免觸發 premature stop
  • 每個修法都有 kill-switch(tengu_* 前綴 flag)可以快速 rollback

這就是 AI 產品工程的日常——不等模型,用工程繞過模型缺陷。而且每個 workaround 都要可以快速關掉。


結語

看完整份原始碼分析之後,最大的感受是:

AI agent 的護城河不在模型,在 harness。

模型會進步,競爭對手可以用同樣的模型。但一套把 prompt architecture、tool runtime、permission model、agent orchestration、context management、memory system 統一起來的工程系統,才是真正難以複製的東西。


工程的最高境界不是讓 AI 更聰明,而是讓不夠聰明的 AI 也能穩定做對事。