很多人第一次用 Claude Code,都用 ChatBot 的直覺在操作:

丟一段需求,等它幫你寫完。不對就再補 prompt。再不對就把規則寫更長。再不對就接更多 MCP、開更多子代理。

結果常常不是越來越強,而是越來越亂。上下文變髒、工具越接越多卻越容易選錯、規則越寫越長卻越不遵守。

這不是 prompt 技巧不夠。而是你在用一個「工程代理系統」,卻還用「聊天機器人」的方式管理它。

這篇文章的目標,是把 Claude Code 從「看起來很會寫程式的聊天視窗」,還原成一套可以治理、可以驗證、可以長期維護的工程工作系統。


一、底層是代理循環,不是對話回應

Claude Code 的核心不是「回答問題」,而是反覆執行一個循環:

收集上下文 → 採取行動 → 驗證結果 → 完成,或回到收集

這個循環看似簡單,但實務上會不會失控,取決於你怎麼設計它的上下文、行動能力、控制邊界、隔離方式與驗證機制。

卡住的地方幾乎從來不是模型不夠聰明。更多時候是:給了它錯誤的上下文、沒辦法判斷結果對不對、也沒辦法撤回。

把 Claude Code 想成一個剛進團隊的高能力工程師。你如果只丟一句「去做」,它可能也會開始動。但真正決定品質的,從來不是它願不願意做,而是:它拿到了哪些資訊、可以做哪些事、哪些事不能做、什麼情況要停、怎樣才算完成。


二、六層架構:治理 Claude Code 的完整框架

要把 Claude Code 用穩,最實用的方式是把它拆成六層來看:

層次 組件 負責的事
L1 CLAUDE.md / rules / memory 長期上下文、協作契約、固定約束
L2 Tools / MCP 動作能力、外部連接、資料讀寫
L3 Skills 工作方法論、按需載入的工作流
L4 Hooks 強制插入、審計點、確定性控制
L5 Subagents 隔離的工作單元、高噪音任務
L6 Verifiers 驗證閉環、可回滾、可審查

這六層缺一不可。只強化其中一層,整體系統反而容易失衡:

  • CLAUDE.md 寫太長 → 常駐上下文先污染自己
  • 工具接太多 → Claude 選工具像在逛迷宮
  • Subagent 開到處都是 → 狀態開始漂移
  • 沒有驗證 → 最後只能靠「它說做完了」自我安慰

這就是很多人越用越卡的根源。


三、先把名詞切清楚

這幾個詞很容易混在一起:

組件 定位 給 Claude 的是什麼 典型用途
Tool / MCP 動作能力 新功能 讀檔、改檔、查 GitHub、跑指令
Skill 工作方法 流程與框架 發布前清單、故障分診流程
Hook 硬性控制 確定性插入點 編輯後自動 lint、阻止修改特定檔案
Subagent 隔離執行 獨立上下文 掃整個 repo、大量測試、大型審查

一句話記住:要給新能力用 Tool/MCP,要給方法用 Skill,要做硬限制用 Hook,要做隔離探索用 Subagent。


四、上下文工程:最重要的系統約束

很多人把上下文當「容量問題」,其實卡住的地方通常不是不夠長,而是太吵了——有用的資訊被大量無關內容淹沒。

真實的上下文成本

Claude Code 的 200K 上下文並非全部可用。實際成本分布大致如下:

類型 佔用量 說明
系統指令 ~2K 固定開銷
啟用的 Skill 描述符 ~1–5K 每個 Skill 的描述常駐
MCP Server 工具定義 ~10–20K 最大隱形殺手
LSP 狀態 ~2–5K 固定開銷
CLAUDE.md + Memory ~3–7K 半固定
動態可用(對話、檔案、工具輸出) ~160–180K 真正能用的空間

一個典型 MCP Server(如 GitHub)包含 20–30 個工具定義,每個約 200 tokens,合計 4,000–6,000 tokens。接 5 個 Server,光工具定義就吃掉約 25,000 tokens(12.5%)。在需要大量讀碼的場景,這 12.5% 很關鍵。

建議的上下文分層

載入方式 放哪裡 放什麼
始終常駐 CLAUDE.md 專案契約、建置命令、禁止事項
按路徑載入 rules 語言、目錄、檔案類型特定規則
按需載入 Skills 工作流程、領域知識
隔離載入 Subagents 大量探索、平行研究、高噪音任務
不進上下文 Hooks 確定性腳本、審計、阻斷

設計的本質很簡單:偶爾才用到的東西,不要每次都塞進主上下文。

Tool Output:另一個隱形上下文殺手

除了 MCP 工具定義的固定開銷,動態部分同樣有個常被忽視的坑:Tool Output。cargo test 一次完整輸出動輒幾千行,git logfindgrep 在稍大的 repo 裡也能輕鬆塞滿螢幕。

Claude 並不需要全部細節,它通常只需要知道:有沒有過、哪裡掛了、下一步該做什麼。但只要這些輸出進了上下文,就是實實在在的 token 消耗。

實務建議:與其把完整輸出餵給 Claude,不如截短:

cargo test 2>&1 | head -30

更進一步,可以用 Hook 透明處理輸出,讓 Claude 只看到關鍵訊號:

# 原始輸出(幾千行)
running 262 tests ...

# 處理後 Claude 看到的
✓ cargo test: 262 passed (1 suite, 0.08s)

Claude 真正需要的就是「過了還是掛了,掛在哪裡」,其他都是噪音。

壓縮機制的陷阱與解法

上下文快滿時 Claude Code 會自動壓縮,但預設壓縮算法按「可重新讀取」判斷,早期的架構決策和約束理由往往會被一起刪掉。兩小時後再改,可能根本不記得兩小時前定了什麼。

解法一:在 CLAUDE.md 寫 Compact Instructions

## Compact Instructions
When compressing, preserve in priority order:
1. Architecture decisions (NEVER summarize)
2. Modified files and their key changes
3. Current verification status (pass/fail)
4. Open TODOs and rollback notes
5. Tool outputs (can delete, keep pass/fail only)

解法二:開新會話前,先讓 Claude 寫 HANDOFF.md

請 Claude 寫清楚:目前做到哪裡、試過哪些方法、哪些走得通、哪些是死路、下一步建議做什麼、目前風險與待驗證項目。下一個新鮮上下文的 Claude 只讀這份文件就能接著做,不依賴壓縮算法的摘要品質。


五、Plan Mode 的工程價值

Plan Mode 的本質是把「探索」和「執行」拆開。探索階段不動檔案,只做釐清目標、確認限制、比較方案、拆解實作順序、找出風險點。

階段 操作 目的
探索(Plan Mode) 只讀、分析、比較方案 不在錯誤假設上浪費執行成本
執行 動檔案、寫程式 方案已確認後才開始

按兩下 Shift+Tab 進入 Plan Mode

對於複雜重構、跨模組遷移、高風險設定變更,Plan Mode 特別有用。一個進階玩法:開一個 Claude 寫計畫,再開一個以「高級工程師」身份審這個計畫,讓 AI 審 AI,效果很好。


六、Skills 設計:不是模板庫,是按需載入的工作流

Skill 的描述符常駐上下文,完整內容只有真的被觸發時才載入。這個「按需載入」機制叫做 progressive disclosure(漸進式揭露)

一個好 Skill 應該具備什麼

要素 說明 範例
描述寫「何時使用」 不是「我是什麼」,而是「什麼情況用我」 Use for PR reviews with focus on correctness.
完整步驟 輸入、步驟、輸出、停止條件 避免寫了開頭沒有結尾
正文只放骨架 大資料拆到 supporting files 不要把百科全書塞進 SKILL.md
有副作用要限制 disable-model-invocation: true 防止 Claude 自己心血來潮觸發

描述符要寫短,每個 Skill 都在偷上下文空間:

# 低效(~45 tokens)
description: |
  This skill helps you review code changes in Rust projects.
  It checks for common issues like unsafe code, error handling...

# 高效(~9 tokens)
description: Use for PR reviews with focus on correctness.

三種最值得自己做的 Skill 類型

類型 適合情境 核心設計
檢查清單型 release 前、交付前核對 每項 pass/fail,有一項 fail 就不能繼續
工作流型 高風險操作(遷移、回滾) disable-model-invocation: true,內建回滾步驟
領域專家型 故障分診、日誌調查 固定的證據收集路徑 + 決策矩陣

範例:領域專家型(runtime-diagnosis)

---
name: runtime-diagnosis
description: Use when the app crashes, hangs, or behaves unexpectedly at runtime.
---

## Evidence Collection
1. Run `app doctor` and capture full output
2. Last 50 lines of logs
3. Plugin/module state

## Decision Matrix
| Symptom         | First Check              |
|-----------------|--------------------------|
| Crash on startup | doctor output → syntax error |
| Rendering glitch | GPU backend / terminal capability |
| Config not applied | Config path + schema version |

## Output
Root cause / Blast radius / Fix steps / Verification command

Skill 調用頻率的最佳策略

頻率 策略
高頻(>1 次/會話) 保持 auto-invoke,優化描述符
低頻(<1 次/會話) disable-auto-invoke,手動觸發,描述符脫離上下文
極低頻(<1 次/月) 移除 Skill,改為文件記錄

七、Tool 設計:不是功能越多越好

給 agent 用的工具,重點不是功能堆得多完整,而是讓它更容易用對

好工具 vs. 壞工具

面向 好的設計 壞的設計
命名 github_pr_review(有系統前綴) review(模糊)
目標 單一明確目的 一個工具包五種行為
參數 語義清楚 到處都是 idnametarget
錯誤訊息 有修正指引 只回 opaque error code
大輸出 支援 concise/detailed 模式 永遠完整輸出
層次 高層任務工具 暴露過多底層碎片工具

Claude 選工具靠的是語意判斷,而不是你覺得 API 設計漂不漂亮。工具越碎、越模糊、越多重目的,它就越容易選歪。

AskUserQuestion 工具的演進:一個真實的設計故事

Claude Code 團隊在設計「任務中途暫停問用戶」這個功能時,試了三個版本:

版本 做法 問題
v1 給已有工具加 question 參數 Claude 大多數時候直接忽略,繼續往下跑
v2 要求 Claude 在輸出裡寫特定 markdown 格式 Claude 經常「忘了」按格式寫,邏輯非常脆弱
v3 做成獨立的 AskUserQuestion 工具 Claude 想提問就必須顯式調用它,調用即暫停,無歧義

結論:既然你就是要 Claude 停下來問,那就直接給它一個專門的工具。加個 flag 或約定輸出格式,它一順手就略過去了。

什麼時候不該再加 Tool

情況 建議做法
本地 shell 就能穩定完成 讓 shell 做,不要再多包一層
模型只需要靜態知識 用文件、rules、Skill
需求本質是流程約束 用 Skill,不是 Tool
Schema 與回傳格式還不穩定 先驗證清楚再做成工具

八、Hooks:把不該靠記憶的事收回確定性流程

Hooks 不是「自動化小腳本」,更精準的說法是:控制平面的硬邏輯。凡是你不希望 Claude 靠臨場發揮決定的事,都可以考慮放進 Hook。

適合 vs. 不適合放 Hooks 的事

適合放 Hooks 不適合放 Hooks
阻擋修改受保護檔案 需要大量上下文判讀的語意決策
編輯完自動 format / lint 長時間執行的業務流程
SessionStart 注入動態上下文 需要多步推理與權衡的判斷
任務完成後推送通知 (這些應交給 Skill 或 Subagent)

範例:編輯 Rust 檔後立刻 cargo check

{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Edit",
      "pattern": "*.rs",
      "hooks": [{
        "type": "command",
        "command": "cargo check 2>&1 | head -30",
        "statusMessage": "Running cargo check..."
      }]
    }]
  }
}

每次編輯完立刻知道有沒有編譯錯誤,不是等你改了十幾個檔後才發現第一個檔就編不過。

三層搭配最穩

只靠其中一層都會有漏洞:

  • 只寫 CLAUDE.md 規則 → Claude 經常當沒看見
  • 只靠 Hooks → 細節判斷做不了
  • 只靠 Skill → 沒有強制保護
層次 角色
CLAUDE.md 宣告規則(「提交前必須通過測試和 lint」)
Skill 告訴它流程與判讀方式
Hook 在關鍵路徑做硬驗證,必要時阻斷

三樣疊加才有方法、有規則、也有警察。


九、Subagents:最大的價值不是平行,而是隔離

很多人聽到 Subagent,第一反應是「平行跑比較快」。但它最大的價值其實是隔離

大範圍掃 repo、跑大量測試、大型日誌搜尋、代碼審查——這些工作非常容易污染主上下文。交給 Subagent 做,主線只拿回摘要,主上下文會乾淨很多。

設計 Subagent 時要明確約束

參數 目的
tools / disallowedTools 限定工具範圍,不給和主線一樣寬的權限
model 探索任務用 Haiku/Sonnet,重要審查用 Opus
maxTurns 防止跑飛
isolation: worktree 需要動檔案時隔離檔案系統

如果子代理權限跟主線一樣寬,那不叫隔離,只是分身。

適合丟給 Subagent 的任務

  • 「掃整個 repo,找所有和 auth token 相關的實作」
  • 「審查這次 PR,有沒有 correctness 風險」
  • 「比較 A 與 B 兩種遷移方案的差異」
  • 「收集最近 50 行錯誤日誌與模組依賴狀態」

長時間執行的 bash 命令可以按 Ctrl+B 移到背景,Claude 之後會用 BashOutput 工具查看結果,不會阻塞主線程繼續工作。


十、Prompt Caching:很少人講,但非常重要

Prompt cache 是按前綴匹配運作的。越靠前、越穩定的內容,越能被重用。高命中率不只省成本,速率限制也會寬鬆很多。

Claude Code 的 Prompt 順序:

順序 內容 穩定性
1 System Prompt 靜態,應鎖定
2 Tool Definitions 靜態,應鎖定
3 Chat History 動態,放後面
4 當前使用者輸入 最後

常見破壞 Cache 的行為

行為 為什麼有害
系統 Prompt 放時間戳 讓靜態內容每次都變化
工具定義順序不固定 前綴不匹配,cache 失效
會話中途增刪工具 同上
長會話中途切換模型 最常被忽略!會重建整個 cache

關於切換模型:你以為簡單問題切 Haiku 比較省,但如果前面已經和 Opus 聊了 100K tokens,切換模型會重建整個 cache,可能反而更貴。確實需要切換,用 Subagent 交接,而不是在主線切換。

動態資訊(如當前時間)不要放進系統 Prompt,放到使用者訊息裡傳進去就好,系統 Prompt 不動,cache 不會被打壞。


十一、Verifiers:沒有驗證,就沒有工程級代理

「Claude 說完成了」在工程上幾乎不算完成。真正的完成,至少要能回答:它有沒有做對、錯在哪裡、能不能回滾、誰可以審查。

Verifier 三層架構

層次 工具 適用
基本層 exit code、lint、typecheck、unit test 每次變更
中階層 integration test、screenshot diff、contract test、smoke test 功能完成後
高階層 production log、monitoring metrics、人工審查清單 release 前

在 CLAUDE.md 明確定義驗收方式:

## Verification
For backend changes:
- Run `make test` and `make lint`

For API changes:
- Update contract tests

Definition of done:
- All tests pass
- Lint passes
- No untracked TODO remains

一個很簡單的判斷標準:如果一個任務你說不清楚「什麼叫做完」,那它大概率也不適合直接丟給 Claude 自主完成。


十二、高頻命令一覽

這些命令的共同目標只有一個:主動管理上下文,不要等系統替你善後。

上下文管理

命令 用途
/context 查看 token 使用結構,排查 MCP 或訊息歷史佔比
/clear 同一問題被糾偏兩次以上,直接重開
/compact 壓縮對話,要搭配 Compact Instructions
/memory 確認哪些 CLAUDE.md 真的被載入

能力與治理

命令 用途
/mcp 管理 MCP 連接,檢查 token 成本,斷開閒置 server
/hooks 管理 hooks,控制平面入口
/permissions 查看或更新權限白名單
/sandbox 設定沙箱隔離
/model Opus 用深度推理,Sonnet 用常規,Haiku 用快速探索

會話延續與平行

命令 用途
claude --continue 恢復當前目錄最近會話
claude --resume 打開選擇器恢復歷史會話
claude --continue --fork 從已有會話分叉,同一起點不同方案
claude --worktree 建立隔離 git worktree
claude -p "prompt" 非互動模式,接入 CI / pre-commit
claude -p --output-format json 結構化輸出,便於腳本消費

比較少人提但很好用的

命令/操作 用途
/simplify 對剛改完的程式碼做三維檢查(復用、品質、效率),發現問題直接修
/rewind 回到某個會話 checkpoint 重新總結,適合 Claude 已沿錯誤路徑探索太久
/btw 不打斷主任務的前提下快速問一個旁路問題
/insight 分析當前會話,提煉哪些內容值得沉澱到 CLAUDE.md
雙擊 ESC 回去編輯上一條輸入,重發,不用重開會話
~/.claude/projects/ 所有會話記錄存放於此,用 grep 可搜尋歷史

十三、CLAUDE.md 正確寫法:協作契約,不是知識庫

應該放什麼 vs. 不該放什麼

應該放 不該放
build / test / run 指令 大段背景介紹
關鍵目錄與模組邊界 完整 API 文件
風格與命名約束 空泛原則(如「寫高品質程式碼」)
不明顯的環境坑 Claude 看 repo 就能推得出來的事
NEVER 清單 大量低頻知識(這些放 Skills)
驗證方式  
Compact Instructions  

一份值得參考的範本

# Project Contract

## Build And Test
- Install: `pnpm install`
- Dev: `pnpm dev`
- Test: `pnpm test`
- Typecheck: `pnpm typecheck`
- Lint: `pnpm lint`

## Architecture Boundaries
- HTTP handlers live in `src/http/handlers/`
- Domain logic lives in `src/domain/`
- Do not put persistence logic in handlers

## Safety Rails
### NEVER
- Modify `.env`, lockfiles, or CI secrets without explicit approval
- Remove feature flags without checking all call sites
- Commit without running tests

### ALWAYS
- Show diff before committing
- Update CHANGELOG for user-facing changes

## Verification
- Backend changes: `make test` + `make lint`
- API changes: update contract tests

## Compact Instructions
Preserve:
1. Architecture decisions (NEVER summarize)
2. Modified files and key changes
3. Current verification status (pass/fail)
4. Open risks, TODOs, rollback notes

一個很實用的技巧:每次糾正 Claude 的錯後,告訴它:

“Update your CLAUDE.md so you don’t make that mistake again.”

Claude 在幫自己補規則時其實挺好用的,用久了確實越來越少犯同樣的錯。不過要定期 review,當初加的限制久了也會過時。


十四、建議的專案目錄結構

Project/
├── CLAUDE.md                      ← 全域契約
├── .claude/
│   ├── rules/
│   │   ├── core.md                ← 語言通用規則
│   │   ├── config.md
│   │   └── release.md
│   ├── skills/
│   │   ├── runtime-diagnosis/     ← 領域專家型
│   │   ├── config-migration/      ← 工作流型
│   │   ├── release-check/         ← 檢查清單型
│   │   └── incident-triage/
│   ├── agents/
│   │   ├── reviewer.md
│   │   └── explorer.md
│   └── settings.json
└── docs/
    └── ai/
        ├── architecture.md
        └── release-runbook.md

同時維護多個專案時,把穩定的個人基線放在 ~/.claude/,各專案差異放在專案級 .claude/,不同專案之間就不容易互相污染。


十五、最常見的反模式

反模式 為什麼有害
把 CLAUDE.md 當 Wiki 每次會話被一大包低頻資訊壓著跑
Skill 寫得太胖 一個 Skill 同時包 review、deploy、debug、incident,誰都像它但誰都不夠像
工具太多且命名模糊 Claude 每次都得猜該用哪一個
沒有 verifier 只能靠直覺相信「它應該做好了」
過度自治(Subagent 不限制) 像把辦公室門窗全開還掛招牌說歡迎入侵
不做上下文切換 任務換階段了,還在同一個老會話裡繼續堆
allowedTools 不整理 久了像抽屜裡的舊鑰匙,哪把還能開門連你自己都不知道

十六、給初學者的實作順序:不要一次全上

步驟 做什麼 放什麼
第一步 寫最小可用 CLAUDE.md build/test/run + NEVER 清單 + 驗證方式 + Compact Instructions
第二步 把差異規則拆到 rules 前端目錄規則、後端目錄規則、特定語言規則
第三步 做 2–3 個高頻 Skill PR review、release-check、runtime-diagnosis
第四步 加最小 Hooks 編輯後自動 lint、阻擋特定檔案修改
第五步 定義 verifier 至少先有 test + lint + typecheck
第六步 才考慮 Subagents 與更多 MCP 先把治理做好,再擴能力

不要反過來。不然很容易從工程代理進化成工程煙火。


結語:三個階段

用 Claude Code 大概會經歷三個階段:

階段 關注點 典型行為
第一階段 這個功能怎麼用、這個命令是什麼 一直加 MCP、裝工具
第二階段 怎麼讓它少出錯、怎麼修 prompt 規則越寫越長
第三階段 怎麼讓 agent 在約束下穩定工作 治理上下文、設計驗證、控制邊界

到了第三階段,關注點悄悄變掉了:從「這個功能怎麼用」變成「怎麼讓 agent 在約束下自己跑起來」,兩件事感覺差很多。

Claude Code 的成熟使用方式,最終不是關心「它會不會做」,而是「你有沒有把這套系統治理到可以放心讓它做」。

如果一個任務你說不清楚「什麼叫做完」,那它大概率也不適合直接丟給 Claude 自主完成——驗證標準本身都沒有,Claude 再聰明也跑不出正確答案。