Community程式設計與開發github.com

診斷錯誤 (mattpocock/diagnosing-bugs)

針對棘手錯誤與效能回歸的診斷流程。請在使用者說出「診斷此問題」/「除錯此問題」,或回報某些功能故障、拋出錯誤、執行緩慢時使用此技能。

diagnosing-bugs) 是什麼?

這是一套嚴謹的除錯方法論,專為處理難以重現的硬體錯誤與效能回歸問題而設計。其核心在於「建立回饋迴路」:先設法創造一個可靠、快速且能明確區分失敗/成功的測試案例,再進行後續的假設與驗證。此技能支援任何可執行指令、腳本或測試框架的開發環境,例如 CLI 工具、Playwright 瀏覽器測試、Curl 請求,甚至是手動觸發的半自動化腳本。流程由六大階段構成:建立回饋迴路、重現並最小化錯誤、生成可證偽的假設、針對預測進行儀器化、修正並撰寫回歸測試,以及最終清理。整個流程強烈反對在沒有可靠回饋迴路的情況下直接閱讀程式碼並跳入假設,因為這是最常見的除錯失敗模式。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/mattpocock/skills/tree/main/skills/engineering/diagnosing-bugs

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

診斷錯誤

處理棘手錯誤的學科。只有在有明確理由時才可以跳過階段。

在探索程式碼庫時,請先閱讀 CONTEXT.md(如果存在),以建立相關模組的清晰心理模型,並檢查您正在觸及的區域中的 ADR。

紅化

此技能要求您顯示指令、輸出和捕獲的工件。首先對每個機密進行紅化處理:以 <REDACTED> 取代。針對環境變數建立迴圈,讓憑證保留在環境中,而不是顯示在您展示的內容中。捕獲的工件帶有認證標頭:僅引用包含所需訊號的行。

如果紅化後的輸出不足以診斷錯誤,請明確說明並詢問使用者。

階段 1:建立回饋迴路

這就是此技能的核心。 其他一切都是機械性的。如果您有一個緊湊的通過/失敗訊號來指示此錯誤(一個能對_這個_特定錯誤顯示紅色失敗的訊號),您將能找到原因;二分搜尋、假設測試和儀器化都只是利用這個訊號。如果您沒有這樣的訊號,那麼再怎麼盯著程式碼看也無濟於事。

在此投入不成比例的努力。要積極。要有創意。拒絕放棄。

構建回饋迴路的方法,大致按此順序

  1. 失敗的測試,在能到達該錯誤的任何接合處:單元測試、整合測試、端到端測試。
  2. Curl / HTTP 腳本,針對正在執行的開發伺服器。
  3. CLI 調用,使用固定輸入,並將 stdout 與已知正確的快照進行比對。
  4. 無頭瀏覽器腳本(Playwright / Puppeteer),驅動 UI 並對 DOM / Console / 網路進行斷言。
  5. 重放捕獲的軌跡。 將真實的網路請求 / 負載 / 事件日誌儲存到磁碟;在隔離環境中透過程式碼路徑重放它。
  6. 一次性測試用框架。 啟動系統的最小子集(一個服務,模擬依賴項),透過單個函數呼叫來執行錯誤程式碼路徑。
  7. 屬性 / 模糊測試迴圈。 如果錯誤是「有時輸出錯誤」,則執行 1000 次隨機輸入並尋找失敗模式。
  8. 二分搜尋框架。 如果錯誤出現在兩個已知狀態(提交、資料集、版本)之間,自動化「在狀態 X 啟動、檢查、重複」的流程,以便您可以使用 git bisect run。
  9. 差異化迴圈。 對相同輸入執行舊版 vs 新版(或兩種設定),並比對輸出。
  10. 人機協作 Bash 腳本。 最後手段。如果需要人類點擊,則使用 scripts/hitl-loop.template.sh 來_驅動_他們,使迴圈仍然結構化。捕獲的輸出會回饋給您。

建立正確的回饋迴路,錯誤就解決了 90%。

緊湊化迴圈

將迴圈視為一個產品。一旦有了一個_迴圈_,請緊湊化它:

  • 我能讓它更快嗎?(快取設定、跳過無關的初始化、縮小測試範圍。)
  • 我能讓訊號更清晰嗎?(針對特定症狀進行斷言,而不是「沒有崩潰」。)
  • 我能讓它更具確定性嗎?(固定時間、設定隨機數種子、隔離檔案系統、凍結網路。)

一個 30 秒的不穩定迴圈比沒有迴圈好不了多少;一個 2 秒的確定性迴圈則是緊湊的,是除錯的超能力。

非確定性錯誤

目標不是一個乾淨的重現,而是一個更高的重現率。將觸發條件循環 100 次、平行化、增加壓力、縮小時間視窗、注入睡眠。一個 50% 發生率的錯誤是可除錯的;1% 則不是,所以持續提高重現率直到它可以被除錯。

當您真的無法建立迴圈時

停止並明確說明。列出您嘗試過的方法。詢問使用者: (a) 存取能重現錯誤的環境權限,(b) 一個已紅化的捕獲工件(HAR 檔案、日誌轉儲、核心轉儲、帶有時間戳的螢幕錄影),或 (c) 允許添加暫時的生產環境儀器。在沒有迴圈的情況下,不得繼續進行假設。

完成標準:一個能顯示紅色的緊湊迴圈

階段 1 完成時,迴圈必須是緊湊的且能夠顯示紅色:您能指定一個指令(腳本路徑、測試調用、curl 命令),並且您已經至少執行過一次(請顯示該調用及其輸出,已紅化),而且該指令滿足:

  • 能夠顯示紅色:它驅動了實際的錯誤程式碼路徑,並斷言了使用者描述的明確症狀,因此它能在這個錯誤上顯示紅色失敗,並在修復後顯示綠色成功。不只是「執行沒有錯誤」;它必須能夠_捕捉到這個特定的錯誤_。
  • 確定性:每次執行結果相同(對於不穩定錯誤:根據上述,需有一個固定且高的重現率)。
  • 快速:幾秒鐘,而非幾分鐘。
  • 可被代理程式執行:您可以無人值守地執行它;只有透過 scripts/hitl-loop.template.sh 才需要人類介入。

如果您發現自己在建立此指令之前就開始閱讀程式碼來構建理論,請停止:直接跳到假設正是此技能旨在防止的失敗模式。 在沒有能夠顯示紅色的指令之前,不進行階段 2。

階段 2:重現 + 最小化

執行迴圈。觀察它顯示紅色,表示錯誤出現。

確認:

  • 該迴圈產生了使用者描述的失敗模式,而不是恰好發生在附近的其他失敗。錯誤的 bug = 錯誤的修復。
  • 此失敗在多次執行中可重複(或者,對於非確定性錯誤,重現率高到足以在此基礎上進行除錯)。
  • 您已捕獲了確切的症狀(錯誤訊息、錯誤輸出、緩慢的時間),以便後續階段能驗證修復是否真正解決了問題。

最小化

一旦迴圈變成紅色,將重現案例縮小到仍能顯示紅色的最小場景。一次只減少一個輸入、呼叫者、設定、資料或步驟,每次減少後重新執行迴圈,只保留對失敗至關重要的部分。

為什麼要這麼做:最小化的重現案例能縮小階段 3 的假設空間(需要懷疑的移動部件更少),並在階段 5 成為一個乾淨的回歸測試。

當每個剩餘元素都是至關重要的時,即完成:移除其中任何一個都會使迴圈變成綠色。

在您成功重現並最小化之前,不得繼續進行。

階段 3:假設

在測試任何假設之前,先產生 3–5 個排序後的假設。單一假設生成會錨定在第一個看似合理的想法上。

每個假設必須是可證偽的:陳述它所做出的預測。

格式:「如果 是原因,那麼 <改變 Y> 將使錯誤消失 / <改變 Z> 將使錯誤惡化。」

如果您無法陳述預測,那麼這個假設只是一種感覺:丟棄它或讓它更明確。

在測試之前,向使用者顯示排序後的清單。 使用者通常擁有領域知識,能立即重新排序(「我們剛剛部署了一個對第 3 項的更改」),或者知道他們已經排除了哪些假設。這是一個便宜的檢查點,能節省大量時間。但如果使用者不在,請不要阻塞進度;按您的排序繼續進行。

階段 4:儀器化

每次探查必須對應到階段 3 中的一個特定預測。一次只改變一個變數。

工具偏好:

  1. 如果環境支援,使用除錯器 / REPL 檢查。一個中斷點勝過十個日誌。
  2. 有針對性的日誌,放在能區分假設的邊界上。
  3. 永遠不要「記錄所有內容然後用 grep」。

為每個除錯日誌加上唯一的標籤,例如 [DEBUG-a4f2]。最後清理時只需一個 grep 即可完成。未標記的日誌保留;標記的日誌刪除。

效能分支。 對於效能回歸,日誌通常是錯誤的。相反:先建立基準測量(計時框架、performance.now()、分析器、查詢計畫),然後進行二分搜尋。先測量,後修復。

階段 5:修復 + 回歸測試

在修復之前撰寫回歸測試,但僅當存在一個正確的接合處時才這樣做。

正確的接合處是指測試能在呼叫點觸發真實的錯誤模式。如果唯一可用的接合處太淺(當錯誤需要多個呼叫者時卻只有單一呼叫者的測試,無法複製觸發錯誤的鏈條的單元測試),那麼在那裡的回歸測試會提供虛假的安全感。

如果不存在正確的接合處,那麼這本身就是一個發現。 記錄下來。程式碼庫的架構阻止了對這個錯誤的鎖定。將此標記出來供下一階段參考。

如果存在正確的接合處:

  1. 將最小化的重現案例轉換為該接合處的一個失敗測試。
  2. 觀察它失敗。
  3. 套用修復。
  4. 觀察它通過。
  5. 針對原始(未最小化的)場景重新執行階段 1 的回饋迴路。

階段 6:清理

在宣告完成之前必須滿足以下條件:

  • 原始重現案例不再重現(重新執行階段 1 的迴圈)
  • 回歸測試通過(或記錄了缺乏接合處的事實)
  • 所有 [DEBUG-...] 儀器已被移除(使用 grep 檢查該前綴)
  • 一次性原型已刪除(或移動到明確標記的除錯位置)
  • 最終被證明正確的假設已在提交 / PR 訊息中說明,以便下一個除錯者學習

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

mattpocock/ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

mattpocock/caveman

Ultra-compressed communication mode. Cuts token usage ~75% by dropping filler, articles, and pleasantries while keeping full technical accuracy. Use when user says "caveman mode", "talk like caveman", "use caveman", "less tokens", "be brief", or invokes /caveman.

mattpocock/claude-handoff

Hand the current conversation off to a fresh background agent that picks up the work immediately.

mattpocock/codebase-design

Shared vocabulary for designing deep modules. Use when the user wants to design or improve a module's interface, find deepening opportunities, decide where a seam goes, make code more testable or AI-navigable, or when another skill needs the deep-module vocabulary.

mattpocock/design-an-interface

Generate multiple radically different interface designs for a module using parallel sub-agents. Use when user wants to design an API, explore interface options, compare module shapes, or mentions "design it twice".

mattpocock/diagnose

Disciplined diagnosis loop for hard bugs and performance regressions. Reproduce → minimise → hypothesise → instrument → fix → regression-test. Use when user says "diagnose this" / "debug this", reports a bug, says something is broken/throwing/failing, or describes a performance regression.

mattpocock/domain-modeling

Build and sharpen a project's domain model. Use when the user wants to pin down domain terminology or a ubiquitous language, record an architectural decision, or when another skill needs to maintain the domain model.

mattpocock/edit-article

Edit and improve articles by restructuring sections, improving clarity, and tightening prose. Use when user wants to edit, revise, or improve an article draft.

mattpocock/git-guardrails-claude-code

Set up Claude Code hooks to block dangerous git commands (push, reset --hard, clean, branch -D, etc.) before they execute. Use when user wants to prevent destructive git operations, add git safety hooks, or block git push/reset in Claude Code.

mattpocock/grilling

Grill the user relentlessly about a plan or design. Use when the user wants to stress-test a plan before building, or uses any 'grill' trigger phrases.

mattpocock/grill-me

Interview the user relentlessly about a plan or design until reaching shared understanding, resolving each branch of the decision tree. Use when user wants to stress-test a plan, get grilled on their design, or mentions "grill me".

mattpocock/grill-with-docs

Grilling session that challenges your plan against the existing domain model, sharpens terminology, and updates documentation (CONTEXT.md, ADRs) inline as decisions crystallise. Use when user wants to stress-test a plan against their project's language and documented decisions.

mattpocock/handoff

Compact the current conversation into a handoff document for another agent to pick up.

mattpocock/implement

Implement a piece of work based on a PRD or set of issues.

mattpocock/implement-spec

Implement a specification in code.

mattpocock/improve-codebase-architecture

Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick.

mattpocock/loop-me

Grill me about specs for the workflows I want to build, within this workspace.

mattpocock/migrate-to-shoehorn

Migrate test files from `as` type assertions to @total-typescript/shoehorn. Use when user mentions shoehorn, wants to replace `as` in tests, or needs partial test data.

mattpocock/obsidian-vault

Search, create, and manage notes in the Obsidian vault with wikilinks and index notes. Use when user wants to find, create, or organize notes in Obsidian.

mattpocock/prototype

Build a throwaway prototype to flesh out a design — a runnable terminal app for state/business-logic questions, or several radically different UI variations toggleable from one route.

相關技能