我的好朋友 Claude
第 113 期|Claude Code|創作者、打工仔|

Claude Code 揾卡咗 4 個鐘嘅 bug:log 倒推、git bisect、minimal repro 三個 pattern

撞到一個 bug 卡足 4 個鐘,直接叫 Claude「fix」通常出個亂作嘅 patch。教你 3 個有紀律嘅 debugging pattern:log 倒推、git bisect 配 AI 寫 predicate、minimal repro。香港 solo dev 同細 team 實戰角度。

難度 ★★★時間 50 分鐘用具 Claude Code CLI、你個 project + repro environment
【編者撰】一個香港人

情境

下晝 2 點,你撞到一個 bug。

3 點:你以為睇到原因,改完,bug 仲喺度。 4 點:你問 Claude Code「fix this bug」,貼咗 50 行 code 落去。Claude 出一個睇落幾合理嘅 patch。一 apply、一 run,bug 仲喺度。 5 點:你再貼多 200 行 context,Claude 出另一個 patch。Apply 落去,今次連帶整爛咗另外兩個 test。 6 點:你開始懷疑自己係咪做緊呢一行。

呢個係典型 AI 輔助 debugging 嘅 anti-pattern

有紀律咁 debug 嘅核心:收窄 search space,再請 Claude 落手。下面 3 個 pattern 係我自己 solo dev 撞牆撞出嚟嘅 SOP。

跟住做

1. 第一守則:唔好問 Claude「fix this」

撞到 bug 第一個動作,唔係開 Claude Code。係攞張紙寫低:

呢張紙先係你畀 Claude 嘅 context。冇呢張紙,你即係叫 Claude 喺漆黑入面摸路。

# 開個 scratch file 寫低,唔好淨係留喺腦
$ cat > .debug-notes.md <<'EOF'
SYMPTOM: API /api/orders 返 500,error log 寫 "undefined is not iterable"
EXPECTED: 返 order list
LAST KNOWN GOOD: 噚日 commit 8a3f2c1
WHAT CHANGED: pull 咗 main,merge 咗 feature/discount
TRIED:
- restart server → 冇用
- clear cache → 冇用
EOF

2. Pattern A:用 log 倒推

呢個係最少人用嘅 pattern。流程:

  1. 加 log(你親手加,唔好叫 Claude 加 — 你最清楚邊度可疑)
  2. Reproduce 一次
  3. 將 log 輸出完整貼畀 Claude,叫佢提 hypothesis
  4. Claude 出 hypothesis,你決定下一個 log 加喺邊

關鍵 prompt:

Log-driven investigation prompt
我撞到一個 bug。Symptom 同 context 喺 .debug-notes.md,請先讀。我啱啱喺 src/api/orders.ts line 42-58 加咗 log(見以下 output)。Reproduce 一次出嚟係:[log dump 貼喺度]
請:
由 log 倒推最有可能嘅 root cause(列 2-3 個 hypothesis,按可能性排)
對最有可能嗰個 hypothesis,建議下一個應該加 log 嘅位(精確到 file + line + log 乜 variable)
唔好提議 fix。我哋而家係 investigation phase。
如果 log 唔足以分辨幾個 hypothesis,直接講「需要更多 log」,唔好估。

呢個 prompt 嘅紀律:禁止 Claude 提議 fix。Investigation 同 fix 係兩個階段,溝埋一齊就會亂作。

3. Pattern B:git bisect 配 Claude 寫 test predicate

如果你知道某個 commit 之前正常、而家壞咗,但中間隔住 30-100 個 commit — git bisect 係黃金工具,但 90% 開發者都唔識用 automated mode。

# Manual mode(慢,每步要你手動 test)
git bisect start
git bisect bad HEAD
git bisect good 8a3f2c1

# Automated mode(快,畀 script run)
git bisect run ./check-bug.sh

關鍵:個 check-bug.sh 要 exit 0 = good、exit 1 = bad、exit 125 = skip。寫呢個 predicate script 正正係 Claude 嘅強項:

Bisect predicate script prompt
我要 git bisect run 一個 bug。Bug 嘅 minimal repro 步驟:
pnpm install
pnpm dev 起 server
curl localhost:3000/api/orders 應該返 200 + JSON array
而家壞咗:返 500,error message 含 "undefined is not iterable"
請寫一個 check-bug.sh:
Exit 0 如果 /api/orders 返 200
Exit 1 如果 返 500
Exit 125 如果 pnpm install 或 pnpm dev 起唔到(compile error 唔算 bug,bisect 應該 skip)
收尾:每次執行完要 kill 咗個 server,唔好霸住個 port
加 timeout 防 server hang。

跑完 git bisect run,Claude 寫嘅 bisect script 會自動做 binary search,5-7 步就揾到出事嗰個 commit。然後你再丟畀 Claude:「呢個 commit 點解搞爛咗個 endpoint?」呢個 context 窄好多,亂作嘅機率都低好多。

4. Pattern C:抽個 minimal repro 出嚟畀 Claude 專心睇

最後一個 pattern 用喺hypothesis 已經收窄、但就係 fix 唔到嘅情況。

開一個新 folder,將 bug 抽出嚟做一個獨立 repro:

mkdir ~/bug-repro-orders
cd ~/bug-repro-orders
# 抽出 minimum code:1-2 個 file,去除晒所有唔相關嘅 dependency

然後喺呢個 minimal folder 入面開 Claude Code:

Focused review on minimal repro
呢個 folder 係一個 minimal reproduction,得 2 個 file 同 30 行 code。Bug:[symptom]。請:
逐行讀晒 2 個 file(唔好 sample,逐行)
列出每個 expression 嘅 type 同預期 value
指出邊一行係 root cause + 點解
提議 fix,並解釋點解呢個 fix 唔會 break 其他 case
呢個 repro 已經 minimal,唔好叫我加 context。

呢個 pattern work 嘅原因:Claude 喺 200 行 code 入面注意力會散晒,但得 30 行佢就真係可以逐行 reasoning。你嘅工作係幫佢收窄,唔係餵多啲 context 落去

變化

變化 1:race condition / concurrency bug

Race condition 最陰濕 — 跑 100 次得 3 次 fail。直接貼 code 畀 Claude 冇用,因為 symptom 唔穩定、唔可重現。

策略:先加 timing log(每個 critical section 入口同出口都 print 低 timestamp 加 thread / request id),跑 50 次,揀 fail 嗰幾次嘅 log 一次過貼畀 Claude,問佢「邊兩個 event 嘅 interleave 會搞成呢個 state」。Claude 對 concurrent reasoning 真係幾叻,但前提係你要畀佢timing data,唔係淨係畀 code。

變化 2:Heisenbug(manifestation 變嘅 bug)

Heisenbug 嘅特徵:你一加 log 佢就唔再出現、你用 debugger 佢又消失。背後通常係 memory ordering、timing 或者 optimizer 嘅行為。

呢類 bug 唔好叫 Claude 直接 fix。問法:「呢個 bug 消失嘅 pattern 暗示係邊類 root cause?」Claude 會列 5-6 個 category(race / undefined behavior / GC timing 等等),你逐個排除。呢個係 meta-debugging — 將 Claude 當成一個推理夥伴,而唔係一部 patch 生成機。

變化 3:production-only bug(本地 reproduce 唔到)

本地正常、production 先壞 — 通常係 env variable、data shape、scale 或者 timezone 引起。

你冇辦法喺本地 reproduce,所以重點係收集 production 上面嘅證據:error trace、相關 request payload(要 sanitize 走啲 PII)、env diff(local 同 prod 嘅 env variable 對比表)、出事前後 5-10 分鐘窗口嘅 log。

將呢啲一次過貼畀 Claude,問:「邊個 env diff 最能解釋呢個 trace?」直接問 fix 冇用,問 diff 嘅解釋力先有用。揾到出事嗰個 env / data shape,再喺本地用返嗰個 env 重新 reproduce,就跌返入 Pattern A / C。

拆解:點解 work,同邊度會仆街

跟到上面就已經用得。下面呢段係畀**想由「今次揾到個 bug」做到「以後撞咩 bug 都唔會被 Claude 帶住遊花園」**嘅人——初學者可以跳過,唔影響你跟住做。

呢套流程最唔老實嘅地方係:Claude 永遠都肯答你,但「肯答」唔等於「答啱」。佢唔會話「我唔知」,佢會自信咁畀你一個聽落好順嘅 root cause。呢幾個位就係佢扮自信、而你會中招嘅地方,你要預咗:

1. log dump 太長,真正出事嗰行被 truncate 咗 你貼成 500 行 log 落去,以為畀得越多越好。但 Claude 嘅 context 有上限,貼到中段佢嘅注意力已經散,關鍵嗰行隨時被你自己一拼貼蓋過去。

2. git bisect 撞到「壞咗但唔係呢個 bug」嘅 commit 中間有啲 commit 本身 compile 唔到、或者壞咗第二樣嘢。你個 predicate script 淨係 check「/api/orders 返唔返 200」,分唔清「呢個 bug」同「另一個 bug」,bisect 就會指錯 commit。

3. minimal repro 抽嘅過程已經整走咗個 bug 你抽 2 個 file 出嚟,順手簡化埋,結果 repro 唔到。你以為 bug 喺呢 30 行,但其實佢死喺你抽走咗嗰個 dependency 或者 config。

4. Claude 改完一個 test 過,以為搞掂,其實 break 咗你冇睇嗰啲 佢提個 fix,你 run 返你關注嗰個 case 過咗,就 commit。但呢個 fix 隨時靜雞雞改咗共用 function 嘅行為,整爛其他 path。

5. 信錯 Claude 對你個 stack / 版本嘅「記憶」 問到行為細節(某個 API 喺邊個版本改咗、某個 flag default 係乜),Claude 會憑印象答,而你個 project 鎖嘅版本可能同佢記憶唔同。

呢幾個位,就係「今次好彩揾到」同「以後揾 bug 都穩陣」之間嘅距離。Claude 永遠肯答,你嘅紀律就係幫佢收窄到佢答嗰句真係信得過。

一個紀律

Debugging 卡住嘅 4 個鐘,唔係「Claude 唔夠強」,係你冇 isolate 個 bug 就叫 Claude 落手

AI 輔助 debugging 嘅心態唔應該係「Claude 係超人 senior,掟個 bug 過去佢自然識搞掂」。應該係「Claude 係個好叻嘅 pair partner,但收窄範圍嗰部分要你做埋」。

你嘅工作:

Claude 嘅工作:

呢個分工做得好,4 個鐘嘅 bug 變 40 分鐘。做唔好,4 個鐘變 8 個鐘,仲要拖埋兩個整爛咗嘅 patch。

下次撞到 stuck bug,收手 5 分鐘:寫 .debug-notes.md、揀 Pattern A / B / C、再開 Claude。卡足 4 個鐘嘅 bug 通常唔係難,係你太快叫 Claude 出招。

文中工具 · 連結

  • 開發者用 — terminal 入面同 Claude pair coding

睇完想同 Claude 一齊行一次?

撳一撳,就將成段 tutor 指示(連埋成篇文嘅內容)抄入剪貼簿。 貼入 Claude.ai 或 Claude Desktop,佢會用廣東話帶你一步一步行, 每步問你填關鍵位,最後畀返一個專為你情況寫嘅 prompt 帶走。

下期預告 · 相關情境
訂閱本副刊

每週日早上,
一道新菜送到你 inbox。

一篇 use case、一個香港情境、一個跟得到嘅做法。 冇 sell course、冇話你「再唔學就會失業」。

訂閱通道執緊緊
newsletter service 仲未接通。想第一時間收到新文章——
直接 email 我哋寫一句「訂閱」就得。

Email 「訂閱」畀我