# 策展 · X (Twitter) 🔥

> 作者：Jason Zuo (@xxxjzuo) · 平台：X (Twitter) · 日期：2026-04-01

> 原始來源：https://x.com/xxxjzuo/status/2039093625376645537

## 中文摘要

# Claude Code 原始碼背後的設計哲學：51 萬行程式碼，絕大部分都與 AI 無關 

今天 AI 圈最大的新聞，莫過於 Claude Code 的原始碼洩漏了。

51.2 萬行 TypeScript，1903 個檔案。很多人已經在拆裡面的具體實現了，甚至是手搓了開源版本。

我更想聊的是這份原始碼暴露出來的一套設計哲學，作為普通非技術使用者也可以複製的使用 AI Agent 的底層邏輯。 

Claude Code 好用，不只是因為 Opus 模型本身的能力強。51 萬行程式碼裡，真正呼叫 LLM API 的部分可能不到 5%。剩下全是 harness：圍繞模型搭建的運行環境。安全檢查、權限控制、上下文管理、記憶系統、工具編排、Prompt 工程。

這 95% 就是 Claude Code 的 harness 設計哲學。也是它跟其他 AI 程式撰寫工具拉開差距的地方。模型是引擎，harness 是整台車。引擎再強，沒有煞車、方向盤和變速箱，你哪兒也去不了。

---

## 設計哲學的核心：不信任模型

讀 Claude Code 的原始碼，最強烈的感受不是"Anthropic 工程能力真強"，而是"Anthropic 對自己的模型真不信任"。

這不是哲學層面的不信任。原始碼註釋裡有大量 A/B 測試資料和故障率統計。每個 harness 組件背後，都是一個被資料驗證過的"Claude 做不到這件事"。不是在吹模型多強，是在用程式碼承認模型的邊界，然後用架構補上去。

先讀後改鐵律。FileEditTool 會檢查你是不是已經用 FileReadTool 讀過這個檔案，沒讀過直接報錯，不讓改。原始碼裡的邏輯大致是這樣的：

```typescript
// FileEditTool 核心檢查
if (!hasFileBeenRead(filePath)) {
  throw new ToolError(
    "You must read the file before editing it. Use FileReadTool first."
  );
}
```

為什麼？因為 LLM 會 hallucinate 沒讀過的檔案內容。如果不強制先讀，Claude 可能憑空寫一段程式碼覆蓋你的檔案。這條規則不是建議，是硬限制。程式碼級別的"你沒看過就不許動"。

這就是為什麼 Claude Code 改檔案的準確率比其他工具高。不是模型更聰明，是架構不給模型犯傻的機會。

![](https://pub-75d4fe1e4e80421b9ecb1245a7ae0d1a.r2.dev/curated/1775006248386-iaHEwp7ItXYAAlrPRjpg.jpg)

三層上下文壓縮。LLM 管不好自己的 context window，對話長了就開始丟重要資訊。CC 設計了三層遞進式壓縮：

```markdown
使用者對話開始
│
▼
[Level 1] 微壓縮 (Micro Compaction)
│  • 僅清理舊的 tool 呼叫結果
│  • 完整保留對話主線
│  • 成本最低 / 無語義損失
│
▼  (觸發條件：token ≈ 視窗上限)
[Level 2] 自動壓縮 (Auto Compaction)
│  • 觸發閾值：視窗大小 - 13000 buffer
│  • 壓縮歷史對話（保留關鍵資訊）
│  • 熔斷機制：
│      - 連續失敗超過閾值 → 停止壓縮
│
▼  (若仍超限)
[Level 3] 完全壓縮 (Full Compaction)
│  • AI 生成整段對話摘要
│  • 替換全部歷史訊息
│  • 強約束指令：
│      "只總結，不呼叫工具"
│
▼
繼續對話
```

每一層的觸發閾值、預留 buffer、熔斷上限，都不是拍腦袋定的，是在"保留足夠上下文繼續工作"和"騰出足夠空間接收新訊息"之間反覆調出來的平衡點。

sub-Agent 的身份注入。Claude 會無限遞歸 spawn 子 Agent。原始碼裡給子 Agent 注入了一段身份聲明：

```markdown
// 子 Agent 的系統提示詞注入
"You are a sub-agent. You cannot create
additional sub-agents. Complete the task
yourself using only the tools available to you."
```

翻譯過來就是："你是一個工人，不是經理。不要試著再雇人，自己幹活。" Coordinator 模式下有明確的並行規則：

```markdown
Coordinator 並行策略：
只讀任務（研究/搜尋）→ 並行執行
寫入任務（改檔案）  → 按檔案分組串行
原文註釋："Parallelism is your superpower"
前提：讀寫分離
```

BashTool 安全體系。一個 BashTool，18 個檔案做安全檢查。prompt.ts 裡有大約 350 行寫給 AI 看的行為守則。這就是為什麼 Claude Code 從不會擅自 git push --force。不是模型更有分寸，是 Prompt 裡已經把規矩講死了。

工具工廠的默認值是整個安全體系的基石：

```typescript
// src/tools/tool-factory.ts

interface ToolDefinition {
  isConcurrencySafe: boolean; // 默認 false
  isReadOnly: boolean;       // 默認 false
}
```

兩個 false，一行程式碼。這叫 fail-closed。如果工具開發者忘了聲明安全屬性，系統默認它是"不安全的、會寫入的"。寧可過度保守，也不漏掉一個風險。這個設計決策決定了整個系統的安全底線。

---

## Prompt 是編譯出來的，不是寫出來的

打開 src/constants/prompts.ts，會看到整個 Prompt 的組裝邏輯：

![](https://pub-75d4fe1e4e80421b9ecb1245a7ae0d1a.r2.dev/curated/1775006248365-iaHEwqAV8asAAnnzxjpg.jpg)

分界線上面是靜態內容，Claude API 可以緩存，不重複計費。分界線下面是動態內容，每次對話都不一樣。

```typescript
function buildSystemPrompt() {
  return [
    // ─── 靜態部分（可緩存）───
    BASE_SYSTEM_PROMPT,         // 基礎人格和規則
    TOOL_PROMPTS,               // 所有工具的使用手冊
    SAFETY_RULES,               // 安全規則

    // ─── 緩存分界線 ───
    SYSTEM_PROMPT_DYNAMIC_BOUNDARY,

    // ─── 動態部分（每次不同）───
    gitBranch,                  // 當前 Git 分支
    claudeMdConfig,             // CLAUDE.md 專案配置
    userMemories,               // 使用者偏好記憶
    currentDateTime,            // 當前時間
  ];
}
```

Anthropic 把 Prompt 當編譯器的輸出來優化。靜態部分是編譯後的二進制，動態部分是運行時參數。省錢、快、靈活，三個好處同時拿到。

緩存穩定性的維護是一場持續的保衛戰。Claude API 的 Prompt cache 是基於字節級前綴匹配的。不只是工具順序，原始碼裡追蹤了十幾種可能打破緩存的因素：系統 Prompt、工具 schema、模型名稱、beta header 列表、effort 值，任何一個變化都會導致緩存失效。CC 團隊為此發明了專門的 latch 機制：某些參數一旦在會話中首次設定，即使後續狀態變化也不允許修改，因為改了就會打破數萬 token 的緩存。

```markdown
緩存穩定性設計：

1. 工具排序寫死
   - 不按字母序
   - 不按使用頻率

2. 子 Agent fork 結果統一占位符
   - 使用相同占位符替換
   → 10 個子 Agent，只有第 1 個冷啟動
   → 後 9 個直接命中緩存

3. 靜態 Prompt 不包含任何動態變數

4. 動態參數用 latch 機制鎖定，防止中途變化打破緩存
```

每個工具目錄下有獨立的 prompt.ts，是專門寫給 LLM 看的使用手冊。BashTool 的 prompt.ts 大約 370 行。不是寫給人看的檔案，是寫給 AI 看的行為守則，每次啟動時注入系統提示詞。

42 個工具也不是全量注入的。透過 ToolSearchTool 按需發現，需要什麼載入什麼。每多一個工具就多一段 Prompt 描述，多花一份 token。設定 CLAUDE_CODE_SIMPLE=true，直接砍到只剩 3 個工具：Bash、讀檔案、改檔案。連 harness 自身都在做 context management。Prompt 的每一個 token 都有成本，harness 不能無節制地膨脹。

順便說一句，CC 團隊因為自家 SDK 的流式解析存在 O(n²) 性能問題，直接繞過了 Anthropic 官方 SDK，自己管理所有的流式狀態累積。旗艦產品繞過自家基礎設施，harness 工程的複雜度可見一斑。

---

## 記憶系統：精確度優先於召回率

用過 Claude Code 的人都有一個感受：它好像真的認識你。你告訴它"不要在測試中 mock 資料庫"，下次對話它就不會再 mock。

背後的記憶檢索不是你以為的關鍵詞匹配或向量搜尋：

```markdown
記憶檢索流程：
1. 使用者發送訊息
2. Claude Sonnet（小模型）掃描所有記憶檔案的標題+描述
3. 選出最相關的記憶
4. 把完整內容注入當前對話上下文
策略：precision > recall
寧可漏掉，不要污染
```

這個取捨很有意思：大多數系統追求"盡量多找到相關資訊"，CC 反過來，追求"絕不注入無關資訊"。因為對 LLM 來說，context 裡的噪音比缺失更致命。

原始碼裡還有一個叫 KAIROS 的特性標誌。在這個模式下，長會話中的記憶存在按日期的追加式日誌中。然後有一個 /dream 技能會在低活躍期運行，把原始日誌蒸餾成結構化的主題檔案。AI 在"睡覺"的時候整理記憶。

---

![](https://pub-75d4fe1e4e80421b9ecb1245a7ae0d1a.r2.dev/curated/1775006248362-iaHEwo3kabUAEiitrjpg.jpg)

## 三種安全哲學：不是好壞，是信任假設不同

為什麼 Anthropic 選了最難的那條路？因為只有這樣，AI 才能在你的真實環境裡幹活，而不是在一個乾淨房間裡寫一段程式碼讓你複製過來。

權限系統不是 allow/deny 二態，是四態決策：

權限決策：四態模型

allow       → 直接執行，不問

deny        → 直接拒絕，不執行

ask         → 彈窗問使用者，等確認

passthrough → 低風險操作，默認放行

粒度比二態細得多。ask 讓使用者做即時判斷，passthrough 讓低風險操作直接透過。粒度決定體驗，太粗使用者煩，太細使用者累。四態是 Anthropic 試出來的平衡點。

![](https://pub-75d4fe1e4e80421b9ecb1245a7ae0d1a.r2.dev/curated/1775006248338-iaHEwpCQjWUAAHR21jpg.jpg)

三種不同的信任假設。Cursor 賭人類可以一直盯著。Copilot 賭隔離就是安全。Claude Code 賭精確控制行為邊界比限制接觸範圍更有效。51 萬行程式碼就是這個賭注的成本。

---

## 內部版和外部版不一樣

原始碼裡有個 isAnthropicEmployee 分支：

```typescript
if (isAnthropicEmployee()) {
  // 更激進的輸出策略
  // "倒金字塔寫作法"
  // "不寫註釋除非 WHY 不明顯"

  // 實驗功能
  enableFeature("VerificationAgent");
  enableFeature("ExploreAndPlanAgent");
}
```

Anthropic 自己就是 Claude Code 最大的使用者。他們在用自己的產品開發自己的產品。內部版是實驗場，外部版是穩定版。

CC 的架構不是一次性設計出來的，是在 Anthropic 自己的高強度使用中不斷迭代的。每個功能從內部版畢業到外部版，都經過了實戰驗證。Opus 4.5 時代需要的某些限制，到 Opus 4.6 就不需要了。架構會隨著模型能力的提升持續調整，有些組件會被拆掉，有些新的會加上。這也是 harness 哲學的一部分：為拆除而設計。

---

## 對做 Agent 產品的人意味著什麼

最直接的就是社區已經大量用 Claude Code 分析了 Claude Code 原始碼，把核心邏輯抽出來做出了各種 Agent-SDK。claude-Agent-SDK 本來是 CC 套了一層殼做成 SDK，每次 query 要創建一個 CC 進程，開銷大。

利用這次洩露的內容，手搓的各種 Agent-SDK 把邏輯抽成函數呼叫，不依賴本地 CLI 進程。這件事本身就驗證了一點：CC 的價值不在調模型那一小部分程式碼，在於 harness 的工程實現。把 harness 邏輯抽出來，換個模型接進去，核心能力還在。

推薦 @idoubicc 做的 open-Agent-SDK https://x.com/idoubicc/status/2039006326882546141?s=20

從 CC 原始碼能提煉出幾條通用的 harness 設計原則：

Fail-closed 不是 fail-open。不確定一個操作是不是安全的？默認禁止。CC 的工具工廠就是這麼做的。一行默認值，決定了整個系統的安全底線。

每個 harness 組件要有一個顯式的假設。"因為 Claude 會 hallucinate 沒讀過的檔案，所以有先讀後改鐵律。"說不清這個組件在補什麼缺口，這個組件就不該存在。

為拆除而設計。模型升級後，有些限制就不需要了。今天你花一周搭的組件，半年後可能該拆了。如果拆不掉，說明它已經從"補模型缺口"變成了"產品本身的功能"，那它就不再是 harness 組件了。

不過原始碼也暴露了這個原則的另一面。註釋裡工程師自己寫了：多遍 normalization 本質上是脆弱的，每一遍清理都可能製造出前一遍本該處理的條件。原則是對的，但現實中 patch 累積的速度往往比拆除的速度快。為拆除而設計是目標，不是現狀。

Harness 要管自己的開銷。工具按需載入、緩存邊界精確劃分、固定排序維護前綴匹配。Harness 本身也是 context 的消費者，不能無節制地膨脹。

---

51 萬行，絕大部分都是 harness。42 個工具對應系統呼叫，權限系統對應使用者權限管理，記憶系統對應持久化儲存，Agent 蜂群對應進程管理。Claude Code 不是一個套了 AI 的程式撰寫工具，是一個以 LLM 為內核的作業系統。

模型會迭代，具體的 harness 組件也會過時。但 fail-closed、先讀後改、角色分離、按需載入、為拆除而設計，這些設計哲學不會。

Claude Code 好用，是因為 Anthropic 用 51 萬行程式碼承認了一件事：再強的模型也需要一個好的運行環境。

## 標籤

Claude Code, CLI, Agent, 教學資源, Harness, Anthropic, Claude
