鄭智維先生 Claude Code 實戰指南:30 個技巧 + 8 個踩坑

鄭智維先生 的臉書看到 Claude Code 30 個技巧 + 8 個踩坑 文章分享,看起來是之後開課的章節規劃。

我請 Claude (Claude chat,下同。) 針對鄭先生分享的圖檔,寫了兩篇文章。

這是第一篇,請 Claude 根據這些要點,提出看法。

接著讓 Claude 跳出這張圖的範疇,另外寫一篇文章「Claude Code 教學:一些實作上的眉眉角角」。

我覺得兩篇文章都寫的很好(建議都看,然後在實作中試做), 如果沒有經過這樣的過程,而是一開始就直接請 Claude 撰寫「Claude Code 實作指引 」的話,內容應該會是現在的十分之一不到。


▌1. 入門篇 Quick Start

01|Claude Code ≠ ChatGPT,也 ≠ Copilot

這是最重要的認知校正。很多人第一次用 Claude Code,會帶著「AI 聊天助理」或「程式碼補全工具」的心態進來,結果很快就感到困惑:為什麼它有時候會自己跑一堆指令?為什麼它會主動讀檔案?

Claude Code 的設計定位是 agentic coding assistant,也就是說它被設計來:

  • 主動執行 bash 指令(不只是建議你去執行)
  • 讀取並理解整個 codebase 的結構
  • 跨檔案、跨模組進行修改
  • 自行規劃多步驟的實作流程

與 ChatGPT 的本質差異在於:ChatGPT 預設是對話,你問它它回答,執行與否由你決定。Claude Code 預設是行動,它會直接動你的檔案、跑你的測試、提交你的 commit。這不是功能強弱的差別,而是操作模型根本不同。

如果心態不正確,要麼低估它(只拿來問問題),要麼被它嚇到(它怎麼自己改了這麼多東西)。

02|一次只做一件事

這條看起來像廢話,但背後有具體的工程理由。

Claude Code 的每個 Session 都有 context window 限制。當你在一個 Session 裡混雜「先重構這個模組、順便修那個 bug、然後幫我寫測試、對了還要更新文件」,會發生幾件事:

  • Context 被大量的中間狀態佔用,後期回應品質下降
  • 它對任務之間的依賴關係,容易產生錯誤假設
  • 出錯時很難找出是哪個步驟所造成
  • Rollback 困難,因為改動範圍太廣

正確做法是把工作拆成獨立的子任務,每個任務開一個乾淨的 Session。任務之間的銜接靠 CLAUDE.md 和 git 狀態來傳遞,而不是靠同一個 Session 的記憶。

03|先講結果,再談做法

一般人下指令的方式是:「幫我把這個 function 改成 async,然後加上 error handling,回傳值改成 Result type。」這是在描述做法。

更有效的方式是:「這個 function 目前在網路不穩時會讓整個程式 crash,我希望它能夠優雅地處理失敗,並回傳錯誤原因給呼叫端,具體怎麼實作你來判斷。」這是在描述結果。

差別在於:當你描述做法,Claude Code 會照單全收,即使那個做法不是最適合你的 codebase 的選擇。當你描述結果,它會根據你現有的程式碼風格、已有的 utility、現有的型別定義來選擇最合適的實作方式。

例外情形:如果你對某個實作方式有強烈的技術理由(例如效能考量、團隊規範),當然可以明確指定,不必刻意模糊。

04|規則寫進 CLAUDE.md

CLAUDE.md 是 Claude Code 的「長期記憶」入口。每次啟動 Session,它會自動讀取專案根目錄的 CLAUDE.md,作為整個工作的基礎背景。

應該放進去的內容

  • 專案架構說明(哪個目錄放什麼、模組之間的依賴關係)
  • 技術選擇與限制(例如:不使用 ORM、日誌一律用 structlog)
  • 命名規範與程式碼風格(例如:function 用動詞開頭、型別用 PascalCase)
  • 測試規範(例如:每個 public function 必須有對應的 unit test)
  • 禁止事項(例如:不直接修改 migration 檔案、不動 config/production.yaml)

不應該放進去的內容

  • 每次任務的具體細節(那是 Session 開始時再說)
  • 太長的背景故事(超過 500 行的 CLAUDE.md 反而會稀釋重點)

CLAUDE.md 可以有多層,子目錄也可以有自己的 CLAUDE.md,Claude Code 會根據當前工作目錄自動合併讀取。

05|每個任務開新 Session

承接第 02 條。這裡補充操作層面的說明。

新 Session 的意義是:乾淨的 context。它不會記得上一個 Session 你叫它做了什麼、改了哪些東西、有哪些結論。它唯一的「記憶」來源是:

  1. CLAUDE.md(你寫進去的長期規則)
  2. 目前的 git 狀態(它可以 git loggit diff 來理解現況)
  3. 你這個 Session 開頭給的背景說明

所以正確的 Session 開場方式是簡短交代任務背景,不要假設它記得上次的事。一個好的開場範例:

「我在修一個關於訂單狀態同步的 bug,相關程式碼在 services/order_sync.py,問題描述在 GitHub Issue #142,請先讀那個檔案再開始。」

06|截圖不如貼 log,貼 log 不如貼結構

本條已稍做修改。

原圖說「截圖比描述更有效」,這在 Claude.ai 的聊天介面可能成立(因為你在描述 UI 問題、視覺 bug),但在 Claude Code 的終端機工作情境下,截圖通常是最沒效率的做法。

正確的優先順序是:

  1. 貼結構(最好):直接貼 tree 輸出、git diff、錯誤的 stack trace 文字
  2. 貼 log(次之):把終端機的錯誤訊息完整複製貼上
  3. 貼截圖(最後手段):只有在問題本身是視覺性的(例如 TUI 排版異常)才考慮

原因很簡單:Claude Code 可以直接處理文字,截圖需要多一層 OCR 式的解析,資訊密度低、容易遺漏細節,而且截圖無法被 Claude Code 直接引用或搜尋。

07|真實資料才準

讓 Claude Code 在你的實際 codebase上工作,不要給它假資料、簡化版範例、或是「類似的情況」。

常見的錯誤做法:

  • 「我有一個 function,大概長這樣:def process(data): ...,幫我優化」
  • 「假設有一個 User 模型,欄位是 id, name, email,幫我寫查詢」

這樣做的問題是:Claude Code 會針對你描述的假設情境優化,但你的真實 codebase 可能有完全不同的型別定義、不同的 ORM 行為、不同的資料格式。它給你的答案看起來合理,但移植回去時往往需要大量調整。

直接讓它讀真實的檔案,告訴它具體的路徑,讓它自己去理解現況。

08|做完要它自我驗證

每次任務完成後,明確要求 Claude Code 驗證自己的輸出。驗證方式依任務性質而定:

  • 程式碼修改:跑測試(pytestgo testnpm test
  • 新增功能:跑 linter + 跑相關測試
  • 重構:確認所有現有測試仍然通過
  • 文件修改:確認連結有效、範例程式碼可以執行

這條的重點不是「叫它自己跑一遍」,而是把驗證標準說清楚。「做完幫我驗證」是模糊的。「做完跑 pytest tests/test_order_sync.py 並確認全部通過」是明確的。

09|中文也能高效下指令

Claude Code 對中文的理解能力與英文幾乎持平,不需要為了「讓 AI 看得懂」而強迫自己用英文下指令。

更實際的建議是:用你最能精確表達意思的語言。技術術語(function name、variable name、錯誤訊息)保留英文,說明邏輯和需求的部分用中文,混用完全沒問題。

唯一要注意的是:指令要精確,不管中英文都一樣。「幫我整理一下這段程式碼」和「將這段程式碼中重複的邏輯抽取成 private helper function,並補上 type hint」是完全不同層次的指令。

10|錯了就修,別怕迭代

這是心態問題,也是流程問題。

很多人第一次看到 Claude Code 改錯了,反應是「AI 不可靠」然後放棄。正確的心態是:第一次輸出是草稿,迭代是正常流程。

有效的迭代方式

  • 說明哪裡不對、為什麼不對,而不是只說「不對,重來」
  • 如果方向根本跑偏,直接開新 Session,重新給更清晰的指令
  • 用 git 做版本控制,每個可接受的中間狀態都 commit,方便 rollback

迭代不是失敗,是正常的協作節奏。


▌2. 中階篇 Workflow

01|重複工作做成 Skill

在 Claude Code 的語境中,Skill 是指把一段可重複使用的工作流程封裝成標準化的指令模板,讓你不需要每次重新解釋背景和規則。

什麼樣的工作適合做成 Skill

  • 每次新增一個 API endpoint 都要做的固定步驟(建 route、寫 handler、寫測試、更新文件)
  • 每次 code review 前的標準檢查清單
  • 每次發版前的固定確認流程

Skill 的實作方式有兩種:

第一種是寫進 CLAUDE.md:把流程步驟直接描述在對應的章節,Claude Code 啟動時自動載入。適合全專案通用的工作流程。

第二種是獨立的 prompt 檔案:在專案裡建一個 .claude/skills/ 目錄,每個 Skill 是一個 .md 檔,需要時用 /file 指令載入。適合情境特定、不需要每次都啟動的流程。

一個實際的 Skill 範例(新增 API endpoint):

## Skill: 新增 REST API Endpoint

步驟:
1. 在 `routes/` 目錄建立對應的 route 檔案
2. 在 `handlers/` 建立 handler,遵循現有的 error handling 模式
3. 在 `schemas/` 定義 request/response 的 Pydantic model
4. 在 `tests/test_api/` 建立對應測試,至少涵蓋正常流程和錯誤情境
5. 更新 `docs/api.md` 的 endpoint 列表

禁止事項:直接在 route 檔案裡寫業務邏輯。

這樣每次只需要說「用新增 endpoint 的 Skill,幫我建 POST /orders」,不需要重複解釋整套規範。

02|建立個人使用習慣

所謂個人使用習慣,是指你與 Claude Code 的互動模式標準化。每個人的工作風格不同,Claude Code 沒有辦法自動猜測你的偏好,你需要主動建立並記錄下來。

建議建立的個人習慣清單

  • 指令模板:你習慣怎麼開場一個 Session?每次都用類似的格式,Claude Code 的理解效率會更高
  • 驗證標準:你對「完成」的定義是什麼?是跑過測試、還是跑過測試加 linter 加 type check?
  • 溝通風格:你希望它在不確定時先問你,還是先做再說?明確在 CLAUDE.md 裡寫清楚
  • 輸出格式偏好:你希望它解釋每個步驟,還是直接給結果?

這些習慣最終都應該整合到 CLAUDE.md 的「工作協議」章節,而不是每次靠口頭重申。

03|MCP 串接外部工具

MCP(Model Context Protocol)是 Claude Code 對外整合的標準介面。理解它的正確方式是:MCP 讓 Claude Code 獲得它原本沒有的能力。

原生的 Claude Code 能做的事是:讀寫本地檔案、執行 bash 指令、理解程式碼。透過 MCP,它可以:

  • 查詢你的 Linear/Jira tickets
  • 讀取 Notion 文件
  • 操作瀏覽器(做 E2E 測試或網頁截圖)
  • 呼叫公司內部的 API

MCP 的設定方式:

~/.claude/config.json(全域)或專案的 .claude/config.json(專案層級)加入 MCP server 設定:

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "your_token"
      }
    }
  }
}

重要提醒: 踩坑區第 07 條會提到,MCP 設定出問題時很容易誤以為是 Claude Code 本身的 bug。串接前務必先獨立測試 MCP server 是否正常運作。

04|大任務先拆解

這條的核心概念是:不要把一個大任務直接丟給 Claude Code,讓它自己決定怎麼拆。

你拆和它拆的差異在於:你對業務邏輯、技術負債、風險點的掌握比它深。讓它自己拆,它會從技術角度拆,可能忽略「這個模組現在有人在同時修改」或「這個 API 改了要通知下游團隊」這類非程式碼的考量。

實際的拆解框架:

以「重構訂單模組」為例,錯誤做法是:「幫我重構訂單模組」。

正確做法是先自己拆成:

  1. 盤點現有模組的所有 public interface(不動實作,只整理清單)
  2. 針對每個 interface 補齊缺失的測試(確保重構前有安全網)
  3. 重構內部實作(保持 interface 不變)
  4. 確認所有測試通過
  5. 更新相關文件

每個步驟是獨立的 Session,步驟之間靠 git commit 留下可回溯的檢查點。

05|文件直接丟給它讀

不需要把文件內容複製貼上到指令裡。Claude Code 可以直接讀取本地檔案,你只需要告訴它路徑。

幾種常見的餵文件方式

  • 本地檔案:「請先讀 docs/architecture.md 再開始」
  • 多個檔案:「相關的型別定義在 types/order.tstypes/payment.ts
  • 整個目錄:「src/services/ 目錄下的所有檔案都是相關的」

進階用法: 如果你有外部文件(API 規格、第三方 SDK 文件),先把它下載成本地的 .md.txt 檔,放進專案目錄,然後在 CLAUDE.md 裡標註它的位置。這樣每個 Session 都能自動取用,不需要每次重新貼網址或複製內容。

注意: 檔案太大時(超過幾萬字),直接讓它讀完整檔案會佔用大量 context。這時應該告訴它去找特定章節,而不是叫它讀整份文件。

06|Debug 直接貼 log

「怎麼貼」才有效?有效的 log 貼法

貼完整的 stack trace,不要自己節錄「重要的部分」。你認為不重要的那幾行,往往是 Claude Code 最需要的線索。

# 錯誤示範
「出現了 KeyError,幫我看看」

# 正確示範
「執行 `python main.py --config prod.yaml` 出現以下錯誤:

Traceback (most recent call last):
  File "main.py", line 47, in load_config
    return config[env]['database']
KeyError: 'database'

config 檔案內容如下:[貼上實際的 yaml 內容]」

同時貼上:錯誤訊息、觸發錯誤的指令、相關的設定或資料。讓它有完整的情境,而不是要它猜。

07|先理解舊程式再改

它的重要性不只是「避免破壞現有功能」,而是:舊程式碼裡往往有你不知道的隱性知識。

一段看起來「寫得很奇怪」的程式碼,可能是為了處理某個邊界案例、某個外部系統的怪異行為、或是某個已經不在職的工程師踩過的坑。直接叫 Claude Code 改掉,等於把這些隱性知識一起刪掉。

正確的流程

  1. 先叫它讀完相關程式碼,用自己的話解釋這段程式碼在做什麼
  2. 確認它的理解是否正確(你來驗證)
  3. 詢問它是否看到任何可疑的邊界處理或特殊邏輯
  4. 確認理解無誤後,再進行修改

多了步驟 1-3,看似慢了,但避免的是「改完測試過了,上線後才發現把某個邊界案例的處理邏輯刪掉了」這類高成本錯誤。

08|Claude 當 Code Reviewer

這是一個非常實用但常被忽略的使用方式:在你提 PR 之前,讓 Claude Code 先 review 你自己寫的程式碼。

有效的 review 指令範例:

請 review 以下這個 git diff,重點檢查:
1. 是否有潛在的 race condition
2. Error handling 是否完整
3. 是否有遺漏需要更新的測試
4. 命名是否符合專案規範(見 CLAUDE.md)

[貼上 git diff 輸出]

這樣做的實際價值:

  • 在人工 review 之前先過濾掉明顯問題,節省團隊時間
  • Claude Code 對 pattern 的記憶比人強,不會因為「看太多 code 看麻了」而漏掉明顯錯誤
  • 可以針對你自己的弱點設計 review checklist(例如你常忘記加 null check,就把這條加進 prompt)

09|卡住就換方法

更精確的說法是:卡住先診斷原因,再決定換什麼。

卡住的常見原因及對應做法:

原因 症狀 對應做法
任務描述不清 它一直給不相關的答案 重新描述,聚焦在結果而非做法
Context 太雜 後期回應品質明顯下降 開新 Session,只帶必要的背景
任務超出範圍 它開始亂猜或產出不確定的答案 把任務拆小,一次只處理一個面向
工具限制 某個操作它做不到 確認是否需要額外的 MCP 工具
真的是 bug 重複嘗試都失敗,但邏輯上應該可行 查 Claude Code 的 issue tracker

「換問法」只解決第一種原因,其他情況需要不同的處理方式。

10|自動生成 PR / Commit

Claude Code 可以根據它所做的修改,自動生成有意義的 commit message 和 PR 描述。

讓它生成高品質 commit message 的指令:

根據剛才的修改,生成一個符合 Conventional Commits 格式的 commit message。
格式:<type>(<scope>): <description>
type 只能用:feat, fix, refactor, test, docs, chore
description 用中文,說明改了什麼、為什麼改。

PR 描述的生成:

根據這個 git diff,生成 PR 描述,包含:
- 改動摘要(2-3 句)
- 主要變更項目(條列)
- 測試方式
- 是否有 breaking change

重要提醒: 自動生成的 commit message 一定要人工確認後再送出。它生成的描述可能技術上正確,但缺少業務背景(例如「這個改動是為了修復客戶 A 反映的問題」這類資訊,它不會自動加進去)。


▌3. 進階篇 Engineering

01|Worktree 平行開發

Git Worktree 是一個相對冷門但非常適合搭配 Claude Code 使用的 git 功能。它讓你在同一個 repository 裡同時 checkout 多個 branch,每個 branch 在獨立的目錄下運作,互不干擾。

為什麼 Claude Code 特別適合搭配 Worktree?

不用 Worktree 的情況下,如果你想讓 Claude Code 同時處理兩個任務(例如一邊修 bug、一邊開發新功能),你必須在同一個工作目錄裡頻繁切換 branch,每次切換都要確認 working tree 乾淨,而且兩個任務的 Claude Code Session 會互相干擾對方的檔案狀態。

用 Worktree 之後,每個任務有自己的目錄、自己的 branch、自己的 Claude Code Session,彼此完全隔離。

實際設定方式:

# 主目錄是 main branch
# 建立第二個 worktree 給 feature branch
git worktree add ../myproject-feature feature/order-refactor

# 建立第三個 worktree 給 hotfix
git worktree add ../myproject-hotfix hotfix/payment-crash

# 查看所有 worktree
git worktree list

之後在不同的終端機視窗,分別在不同目錄下啟動 Claude Code,各自獨立作業。兩個 Session 修改的是不同目錄下的檔案,不會互相覆蓋。

適合用 Worktree 的情境:

  • 同時有 hotfix 和 feature 開發進行中
  • 需要在不同的實驗性方向之間切換
  • 讓 Claude Code 跑長時間任務時,你想繼續在主目錄做其他事

02|Sub-agents 並行處理

這條是進階篇裡難度最高的概念,也是最容易被誤解的。

Sub-agents 不是 Claude Code 的內建功能,而是一種架構模式。

所謂 Sub-agents 並行處理,是指你設計一個 orchestration 層,由一個主要的 Agent 負責拆解任務、分派工作,再由多個子 Agent 各自執行,最後把結果彙整。

為什麼需要這個:

單一 Claude Code Session 的 context window 有限,處理速度也是線性的。當任務可以被分解成彼此獨立的子任務時,並行跑多個 Session 可以大幅縮短總時間。

實際的實作思路:

以「對整個 codebase 進行安全性審查」為例:

主 Agent 的工作:
1. 掃描所有模組,列出清單
2. 把模組分組(每組 5-10 個檔案)
3. 對每組啟動一個子 Session,給相同的審查 checklist
4. 收集各子 Session 的輸出,彙整成統一報告

目前實作 Sub-agents 需要透過 Claude API 或搭配 orchestration 框架(如 LangGraph、自建的 Python 腳本),不是在 Claude Code 介面裡直接操作的功能。這個模式對有 API 使用背景的開發者比較實用。

重要提醒: 並行不代表一定更好。如果子任務之間有依賴關係(任務 B 需要任務 A 的輸出),強行並行反而會造成錯誤。只有真正獨立的任務才適合並行。

03|Hooks 自動觸發流程

Hooks 是 Claude Code 的事件觸發機制,讓你可以在特定事件發生時自動執行預設的動作。

目前支援的主要 Hook 時機:

  • PreToolUse:Claude Code 準備使用某個工具之前
  • PostToolUse:某個工具執行完畢之後
  • Stop:Claude Code 完成整個任務、準備結束之前

Hook 的設定位置:

~/.claude/config.json 或專案的 .claude/config.json 裡設定:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "npm run lint --fix"
          }
        ]
      }
    ],
    "Stop": [
      {
        "type": "command",
        "command": "python scripts/notify_slack.py"
      }
    ]
  }
}

實際有用的 Hook 應用:

  • 每次寫入檔案後自動跑 linter(PostToolUse: Write → lint
  • 每次任務完成後自動跑測試(Stop → pytest
  • 每次修改特定目錄的檔案後自動觸發 build(PostToolUse: Write → make build
  • 任務完成後發送 Slack 通知(適合長時間跑的任務)

注意事項: Hook 執行的指令是同步的,會阻擋 Claude Code 的下一步。如果你的 Hook 指令很慢(例如完整的測試套件),考慮只跑相關的子集,或改成非同步的通知方式。

04|Skill 模組化重用

這條承接中階篇的「重複工作做成 Skill」,進階版的重點是:Skill 的設計本身需要工程思維。

Skill 的常見設計缺陷:

  • 太寬泛:「幫我寫測試」這種 Skill 等於沒有 Skill,因為沒有提供任何約束
  • 太具體:把某個特定任務的細節硬編進 Skill,導致其他情境無法復用
  • 缺乏參數化:好的 Skill 應該有明確的「輸入變數」,讓呼叫者填入

一個設計良好的 Skill 範例:

## Skill: 新增 Service Layer 方法

輸入參數:
- SERVICE_NAME: 目標 service 的名稱(例如 OrderService)
- METHOD_NAME: 新方法的名稱(例如 cancel_order)
- METHOD_DESCRIPTION: 這個方法要做什麼(用自然語言描述)

執行步驟:
1. 讀取 `services/{SERVICE_NAME}.py`,理解現有的 method 風格
2. 讀取 `types/` 目錄,確認相關型別定義
3. 實作 {METHOD_NAME},遵循現有的 error handling 模式
4. 在 `tests/test_{SERVICE_NAME}.py` 新增對應測試
5. 確認 `mypy` 通過

禁止事項:
- 不直接操作資料庫,必須透過 repository layer
- 不在 service 裡處理 HTTP 相關邏輯

Skill 的版本管理:

Skill 檔案應該納入 git 版本控制,跟著 codebase 一起演進。當專案的技術規範改變(例如換了 ORM、改了測試框架),對應的 Skill 也要同步更新,否則 Skill 反而會讓 Claude Code 往錯誤的方向走。

05|自建 MCP 串公司系統

這條是進階篇裡實作門檻最高的,但對有內部系統整合需求的團隊來說,價值也最大。

什麼情況需要自建 MCP Server:

  • 公司有內部 API(工單系統、部署系統、監控平台)沒有現成的 MCP server
  • 需要整合私有資料來源(內部知識庫、設計稿、產品規格文件)
  • 現有的開源 MCP server 功能不符合需求,需要客製化

MCP Server 的基本架構(以 Python 為例):

from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp import types

server = Server("company-internal")

@server.list_tools()
async def list_tools():
    return [
        types.Tool(
            name="get_ticket",
            description="從內部工單系統取得 ticket 詳情",
            inputSchema={
                "type": "object",
                "properties": {
                    "ticket_id": {
                        "type": "string",
                        "description": "Ticket ID,例如 PROJ-1234"
                    }
                },
                "required": ["ticket_id"]
            }
        )
    ]

@server.call_tool()
async def call_tool(name: str, arguments: dict):
    if name == "get_ticket":
        ticket_id = arguments["ticket_id"]
        # 呼叫內部 API
        result = internal_api.get_ticket(ticket_id)
        return [types.TextContent(type="text", text=str(result))]

async def main():
    async with stdio_server() as streams:
        await server.run(*streams, server.create_initialization_options())

自建 MCP 的實務建議:

  • 先從最高頻使用的查詢操作開始(唯讀),不要一開始就做寫入操作
  • 每個 tool 的 description 要寫清楚,Claude Code 會根據 description 決定什麼時候呼叫哪個 tool
  • 加上適當的 rate limiting,避免 Claude Code 在 loop 裡瘋狂呼叫內部 API
  • 認證資訊放環境變數,不要 hardcode 在 MCP server 程式碼裡

06|Human-in-the-loop 檢查點

隨著任務複雜度提高,讓 Claude Code 完全自動跑完所有步驟不見得是好事。Human-in-the-loop 是指在關鍵節點設置人工確認步驟,確保方向正確再繼續。

哪些節點應該設置檢查點:

  • 破壞性操作前:刪除資料、修改 migration、改動 public API interface
  • 跨越模組邊界前:從一個模組的修改延伸到另一個模組時
  • 不確定性高的判斷:需要業務邏輯知識才能決定的選擇
  • 長時間任務的中間點:每完成一個重要里程碑,確認方向無誤再繼續

在指令裡設置檢查點的方式:

請依序執行以下步驟,每個步驟完成後停下來等我確認才繼續:

步驟 1:讀取所有相關檔案,列出你的修改計畫
[等待確認]

步驟 2:執行修改
[等待確認]

步驟 3:跑測試並回報結果
[等待確認]

步驟 4:生成 commit message

這個模式在 Claude Code 上需要你明確在指令裡說「每步完成後等我確認」,它不會自動暫停。

07|Test First 思維

Test First 不是 TDD 的教條,而是在 Claude Code 工作流程裡的具體實踐方式。

為什麼 Test First 在 Claude Code 語境下特別重要:

Claude Code 執行速度快,很容易讓你在沒有安全網的情況下快速累積大量修改。如果沒有測試先行,你可能在發現問題時已經有幾十個檔案被動過,很難定位是哪個改動造成的。

Claude Code 的 Test First 工作流程:

# 1. 先描述行為,讓它寫測試
「針對 OrderService.cancel_order,先寫測試。
測試案例需涵蓋:
- 正常取消成功的情況
- 訂單狀態不允許取消時應拋出例外
- 資料庫操作失敗時的 rollback 行為
先寫測試,不要實作,確認測試會失敗(紅燈)再告訴我。」

# 2. 確認測試正確(紅燈)後,再讓它實作
「測試看起來正確,現在實作 cancel_order,目標是讓測試通過。」

# 3. 確認測試通過(綠燈)後,考慮 refactor
「測試全過了,看看實作有沒有可以整理的地方,在不改變行為的前提下重構。」

這個流程(紅燈 → 綠燈 → 重構)讓每個步驟的驗證標準都非常明確,Claude Code 不需要猜測「完成」的定義。

08|技術選型比較

Claude Code 可以作為技術選型的分析工具,但這條需要特別說明正確的使用方式,否則很容易得到看似合理但實際上不適用的建議。

錯誤的使用方式:

「我要選一個 Python 的非同步任務佇列,Celery 和 RQ 哪個好?」

這個問題問出來,Claude Code 會給你一個教科書式的比較,但完全不考慮你的具體情境。

正確的使用方式:

我需要選擇一個 Python 非同步任務佇列,請根據以下限制條件提供建議:

現況:
- 現有 stack:FastAPI + PostgreSQL + Redis(已有)
- 任務量:每天約 10 萬個任務
- 任務類型:90% 是發送 email 和 webhook 通知,10% 是報表生成(需要 5-10 分鐘)
- 團隊:3 人,沒有 Celery 使用經驗

限制:
- 不想引入新的 infrastructure(已有 Redis,不想再加 RabbitMQ)
- 需要有 retry 機制和任務狀態查詢

請針對這個具體情境給建議,不需要給通用比較。

條件越具體,建議越實用。讓它針對你的真實情境分析,而不是生成一篇通用的技術比較文章。

09|Pipeline 串接任務

Pipeline 是指把多個 Claude Code 任務串成有序的自動化流程,前一個任務的輸出成為下一個任務的輸入。

一個實際的 Pipeline 範例(PR 自動化審查流程):

#!/bin/bash
# pipeline: PR 送出前的自動審查

# Step 1: 靜態分析
echo "=== Step 1: 靜態分析 ===" 
claude "請對 git diff main 的內容進行靜態分析,
        找出潛在的 bug、未處理的 edge case、
        以及不符合 CLAUDE.md 規範的部分,
        輸出結果存到 /tmp/review_step1.md"

# Step 2: 安全性檢查
echo "=== Step 2: 安全性檢查 ==="
claude "讀取 /tmp/review_step1.md 和 git diff main,
        專注檢查安全性問題:SQL injection、
        未驗證的輸入、硬編碼的憑證、
        輸出結果附加到 /tmp/review_step2.md"

# Step 3: 生成最終報告
echo "=== Step 3: 生成報告 ==="
claude "讀取 /tmp/review_step1.md 和 /tmp/review_step2.md,
        整合成一份 PR review 報告,
        格式符合我們的 PR template,
        存到 pr_review_report.md"

Pipeline 設計的關鍵原則:

  • 每個 Step 的輸出要明確存成檔案,不要依賴 Session 的記憶傳遞
  • 每個 Step 失敗時要有明確的錯誤處理,不要讓後面的 Step 用到錯誤的輸入
  • Pipeline 越長越脆弱,盡量控制在 5 個 Step 以內

10|設定檔版本控制

這是一個影響整個團隊協作品質的重要實踐。

應該納入版本控制的 Claude Code 相關設定:

專案目錄/
├── CLAUDE.md                    # 一定要 commit
├── .claude/
│   ├── config.json              # 專案層級設定,一定要 commit
│   ├── skills/                  # 所有 Skill 檔案,一定要 commit
│   │   ├── add-endpoint.md
│   │   └── code-review.md
│   └── hooks/                   # 如果有自訂 hook 腳本,commit
│       └── post-write-lint.sh

不應該 commit 的設定:

~/.claude/config.json            # 個人全域設定,放 gitignore
.claude/config.local.json        # 個人的本地覆寫,放 gitignore

為什麼這很重要:

當 CLAUDE.md 和 Skill 檔案納入版本控制,新加入的團隊成員 clone 專案後,Claude Code 的行為會和其他人一致。不會出現「在你的電腦上 Claude Code 知道不能動 migration 檔案,但在我這裡它不知道」這種情況。

設定檔的 commit message 也應該說明為什麼這樣設定,而不只是「更新 CLAUDE.md」。這些設定背後的理由,往往比設定本身更有價值。


▌4. 踩坑區 Pitfalls

01|把它當聊天工具 :cross_mark:

這是最普遍、成本最高的誤用方式。

具體症狀:

  • 用 Claude Code 問「這個設計模式有什麼優缺點?」
  • 請它解釋某個概念,然後根據解釋自己去實作
  • 把它當 Stack Overflow,問完就關掉

這樣做沒有錯,但完全浪費了 Claude Code 的核心能力。Claude Code 的價值不在於「回答問題」,而在於「直接動手做」。當你在問它「這樣設計好不好」,它本來可以直接讀你的 codebase、評估你的具體情境、然後直接幫你實作更好的版本。

校正方式:把「問句」改成「任務句」

# 聊天模式(低效)
「Python 的 dataclass 和 Pydantic 有什麼差別?」

# 任務模式(高效)
「看一下 models/ 目錄,評估哪些地方用 dataclass 但應該改用 Pydantic,
 列出建議清單,並說明理由。如果我同意,直接幫我改。」

02|一次塞太多需求 :cross_mark:

這條和入門篇第 02 條「一次只做一件事」呼應,但踩坑的角度不同。入門篇講的是任務拆解的原則,這裡要說的是為什麼塞太多需求會讓品質系統性下降。

實際發生的事:

當你在一個指令裡塞進五個需求,Claude Code 會嘗試同時滿足所有需求。問題是:

  • 需求之間可能有隱性衝突,它不會主動指出,而是選一個它認為合理的折衷
  • Context 被五個任務的資訊稀釋,每個任務分到的「注意力」都不足
  • 其中一個需求比較複雜,它會在那裡多花資源,其他需求就草草帶過
  • 出錯時你不知道是哪個需求造成的

最容易被忽略的隱性症狀:

輸出「看起來都完成了」,但每個部分都只做到 80%。測試少了幾個邊界案例、文件更新漏了一個章節、重構只改了主要路徑沒改 edge case。這種錯誤很難被發現,因為表面上每個需求都有對應的輸出。

03|用假資料測試 :cross_mark:

為什麼假資料會造成系統性的誤判?

假資料的三種常見形式:

第一種是簡化的 schema:「假設 User 有 id、name、email 三個欄位」,但你真實的 User model 有 30 個欄位,其中有幾個有複雜的 validation 邏輯。Claude Code 針對簡化版寫出來的程式碼,碰到真實資料時會在你意想不到的地方爆掉。

第二種是乾淨的假資料:你給它「正常」的測試資料,但真實環境裡有歷史遺留的髒資料(null 值、格式不一致、編碼問題)。它寫出來的程式碼在乾淨資料上跑得很好,上線後第一個真實請求就崩潰。

第三種是規模不符:你給它 10 筆資料測試,但真實環境是 100 萬筆。它的實作可能在小資料量下完全正確,但有 N+1 query 問題或記憶體問題,只有在真實規模下才會出現。

原則:能用真實資料就用真實資料。 如果因為隱私或安全原因不能用真實資料,至少確保假資料的 schema、髒資料比例、資料量規模都接近真實情況。

04|同 Session 做多件事 :cross_mark:

這條和第 02 條有關聯,但要強調的是另一個面向:Session 的狀態污染問題。

什麼是狀態污染:

在同一個 Session 裡,Claude Code 的「理解」會隨著對話累積而漂移。Session 初期它對你的 codebase 有某個理解,做了幾件事之後,中間的對話內容會修改它的理解,到後期它可能在用一個已經和現實不符的心智模型做事。

一個典型的污染場景:

你:「幫我重構 OrderService」(它讀了 OrderService,建立了理解)
它:(完成重構)
你:「順便幫我看看 PaymentService 有沒有問題」
它:(讀了 PaymentService)
你:「好,現在幫我整合這兩個 service」
它:(此時它對 OrderService 的理解是重構前的版本,
      因為重構是在這個 Session 早期做的,
      但 context 裡關於 OrderService 的早期描述
      和後來的修改混在一起,它可能用錯誤的狀態整合)

正確做法: 每個獨立的任務開新 Session。任務之間靠 git 狀態傳遞,不靠 Session 記憶。

05|沒驗證就相信完成 :cross_mark:

這條是所有踩坑裡對實際產品品質影響最大的一條。

Claude Code 說「完成了」不代表真的完成了。

它會說完成的原因可能是:

  • 它認為自己完成了,但實際上遺漏了某個步驟
  • 它遇到了一個它不確定怎麼處理的情況,選擇了一個「看起來合理」的做法,沒有告知你
  • 它生成的程式碼語法正確,但邏輯有問題,只有跑起來才會發現
  • 測試通過了,但測試本身寫錯了(測試在測錯誤的行為)

建立系統性的驗證習慣:

不要問「你完成了嗎?」,而是問「跑測試,告訴我結果」、「把你改動的所有檔案列出來」、「解釋你的實作邏輯,讓我確認方向正確」。

驗證不是對 Claude Code 不信任,而是正常的工程實踐。人寫的程式碼也需要 review 和測試,AI 寫的程式碼同樣如此。

06|沒讀 code 就直接改 :cross_mark:

這條是進階篇第 07 條「先理解舊程式再改」的反面,但踩坑的嚴重程度值得單獨強調。

沒讀就改的具體風險:

  • 刪掉隱性的防禦邏輯:某段「看起來多餘」的 null check,其實是為了處理某個外部系統回傳的異常資料
  • 破壞未記錄的合約:某個 function 的呼叫端對它的行為有隱性假設,改了實作但不知道有這個假設
  • 引入重複邏輯:它不知道類似的功能已經在另一個模組實作過,又寫了一份新的
  • 違反架構決策:某個設計選擇背後有特定的理由(例如效能、一致性),它不知道理由,把它「優化」掉了

最貴的一種錯誤: 改動通過了所有測試,上線後才發現某個只在特定條件下觸發的邏輯被破壞了。這類 bug 的 debug 成本極高,因為測試沒有覆蓋到,而且通常需要在生產環境才能重現。

07|MCP 問題誤判成 Claude 問題 :cross_mark:

對實際在用 MCP 的開發者來說,這是最容易浪費大量時間的坑。

為什麼容易誤判?

MCP 的架構是 Claude Code → MCP Server → 外部系統。

當某個操作失敗時,錯誤可能發生在任何一層,但從 Claude Code 的介面看起來,症狀都是「它沒有做到我要求的事」。

常見的誤判場景:

你叫它「從 Linear 取得本週的 open tickets」
它回說「我沒有找到任何 tickets」

你以為:Claude Code 理解有問題
實際上可能是:
- MCP server 沒有啟動
- MCP server 的認證 token 過期
- Linear API 的 rate limit 被觸發
- 你的 workspace 設定讓它只能看到某個 team 的 tickets

正確的 debug 流程:

  1. 先獨立測試 MCP server 是否正常(不透過 Claude Code,直接呼叫 MCP server)
  2. 確認認證資訊是否有效
  3. 確認 MCP server 的 log,看實際收到了什麼請求、回傳了什麼
  4. 確認是 Claude Code 的問題之後,才開始從 Claude Code 的角度 debug

一個快速診斷的方法: 把你的需求用最簡單的方式表達,叫它列出它能用的 MCP tools。如果它連列出 tools 都有問題,那是 MCP 連線的問題,不是 Claude Code 理解的問題。

08|套件版本升級爆炸 :cross_mark:

這條是一個非常具體的操作風險。

場景描述:

你叫 Claude Code「把這個專案的依賴套件更新到最新版」。它很勤快地更新了 requirements.txtpackage.json,跑了測試,測試通過,告訴你完成了。

三週後你上線,發生了奇怪的 bug。

為什麼會這樣:

套件版本升級的風險不只是 breaking change,還包括:

  • 行為細節改變:API 相容但某個邊界案例的行為不同,測試沒有覆蓋到
  • 間接依賴升級:你的直接依賴沒變,但它的依賴升了版,引入了問題
  • 環境差異:本地測試通過,但 CI 或生產環境的某個設定讓新版套件行為不同
  • 時間炸彈:新版套件有 deprecation warning,會在某個時間點後停止支援你用的 API

正確的升級流程(叫 Claude Code 照這個做)

1. 先只升級一個套件,不要一次全升
2. 每次升級後跑完整測試套件
3. 查看該套件的 CHANGELOG,確認有沒有 breaking change 或行為改變
4. 在 staging 環境跑一段時間,確認沒有問題再升下一個
5. 每個成功的升級單獨 commit,方便 rollback

結語

善用 Claude Code,但你才是專案的主人

Claude Code 會讓你的執行速度大幅提升,但速度本身不是目標。

有幾個能力是 Claude Code 無法取代你的:

  • 判斷什麼值得做:它可以幫你快速實作任何功能,但哪個功能應該先做、哪個根本不應該做,是你的判斷
  • 理解業務背景:程式碼背後的商業邏輯、使用者需求、團隊限制,它只知道你告訴它的部分
  • 承擔後果:它寫的程式碼上線後出了問題,需要你去面對和修復
  • 長期維護:一個快速生成但沒有人真正理解的 codebase,會在六個月後變成技術負債

最後一個實際建議:

定期回頭讀 Claude Code 幫你寫的程式碼。不是為了找錯誤,而是為了確保你真正理解自己的 codebase。如果有一段程式碼是 Claude Code 寫的,但你說不清楚它在做什麼,那是一個警訊,不是可以忽略的細節。

工具越強大,使用者的判斷力就越重要。Claude Code 是你的工程夥伴,不是你的替代品。

▌附錄:3 Step 開始法

第一次使用 Claude Code 的人,一個可以立刻執行的起點:

Step 1:建好 CLAUDE.md

在專案根目錄建立 CLAUDE.md,至少包含:專案是做什麼的、技術 stack、目錄結構說明、最重要的三到五條開發規範。不需要完美,之後隨時可以補充。

Step 2:任務拆成 5 步以內

在任務開始前,先自行拆解。如果拆不到 5 步以內,代表任務還太大,繼續拆。每一步要有明確的完成標準(可以用測試通過、可以用 diff 檢查、可以用肉眼驗證)。

Step 3:做完要求自我驗證

每個任務完成後,明確告訴 Claude Code 用什麼方式驗證。驗證通過後,自己再看一遍改動的程式碼,確認你理解發生了什麼。

關鍵心法:

  • 明確目標:模糊的指令產生模糊的結果,永遠值得多花一分鐘把需求說清楚
  • 小步快跑:每個小步驟都有驗證,比一次跑完再發現問題要省時間
  • 持續驗證:驗證是工作流程的一部分,不是額外的負擔
  • 不斷迭代:第一次輸出是起點,不是終點

▌參考資料

1個讚