systematic-debugging について
開発者やコーディングエージェント向けのデバッグスキルです。再現、切り分け、検証可能な仮説、確認の順に調査し、当てずっぽうの変更ではなく、根本原因を証拠に基づいて修正します。
主な機能
- 01バグを安定して再現
- 02コード経路や層を切り分け
- 03検証可能な仮説を立案
- 04小さなテストで仮説を検証
- 05修正による回帰を確認
活用シーン
- 01git bisectで回帰を追跡
- 02フロントエンド、バックエンド、APIへの切り分け
- 03断続的な障害の調査
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ spencerpauly/ awesome-cursor-skills --skill systematic-debuggingインストール後、Claude Code で/systematic-debuggingを入力して読み込まれたか確認します。
詳細
系統的なデバッグ
コードを手当たり次第に変更するのではなく、手順に沿ってデバッグします。
プロセス
1. 再現する
何よりも先に、バグを確実に再現します。
- 問題を発生させる正確な手順を確認します
- 期待される動作と実際の動作を記録します
- 毎回発生することを確認します(断続的ではないこと)
- 環境(OS、Node のバージョン、ブラウザーなど)を記録します
再現できなければ、修正できません。詳細を確認してください。
2. 切り分ける
バグがどこにあるかを絞り込みます。
コードベースを二分探索する:
- システムの半分をコメントアウトします → バグは引き続き発生しますか?
- 発生する場合、バグは残りの半分にあります → 繰り返します
- 発生しない場合、バグはコメントアウトした半分にあります → 繰り返します
Git bisect:
git bisect start
git bisect bad # current commit is broken
git bisect good <sha> # this commit was working
# Git checks out the midpoint — test it
git bisect good # or git bisect bad
# Repeat until it finds the first bad commit
git bisect reset # when done
レイヤーごとに切り分ける:
- フロントエンドですか、それともバックエンドですか?(ネットワークタブを確認します)
- データベースですか?(直接クエリを実行します)
- API ですか?(エンドポイントに
curlを実行します) - コンポーネントですか?(単独でレンダリングします)
3. 仮説を立てる
具体的で検証可能な仮説を立てます。
- 「Y が原因で、X によってバグが発生している」
- 「データに何か問題がある」では不十分です
- 良い例:「このルートでは認証ミドルウェアが実行されないため、
userIdが null になっている」
4. 仮説を検証する
仮説を証明または否定できる、可能な限り小さなテストを書きます。
- 疑わしい箇所に
console.logを追加するか、ブレークポイントを設定します - 疑わしい変数の値を確認します
- 仮説が間違っていた場合は、新しい情報をもとにステップ 3 に戻ります
- 仮説が正しければ、バグを特定できています
5. 修正して検証する
- 最小限の修正を適用します
- 元の再現手順でバグが発生しなくなったことを確認します
- リグレッションを確認します — 修正によってほかの何かが壊れていませんか?
- このバグを検出できたはずのテストを書きます
デバッグツール
| 状況 | ツール |
|---|---|
| 「以前は動いていた」 | git bisect |
| 「どこで実行されているかわからない」 | 疑わしい関数の入口と出口にログを追加する |
| 「データがおかしい」 | 各変換ステップで確認する |
| 「本番環境でしか失敗しない」 | 環境変数を比較し、ログを確認して、本番データを使ってローカルで再現してみる |
| 「断続的に発生する」 | 競合状態、タイミングの問題、未初期化の状態を調べる |
| 「エラーメッセージが役に立たない」 | そのエラーがスローされる箇所をコードベース内で検索する |
よくあるバグのパターン
- Off-by-one:配列のインデックス、ページネーション、日付範囲
- Null/undefined:オプショナルチェーンの不足、未初期化の状態
- 競合状態:非同期処理が予期しない順序で完了する
- 古いクロージャ:React の useEffect/useCallback が古い値をキャプチャしている
- 型変換:
==と===の違い、文字列と数値の比較 - await の不足:非同期関数で
awaitを忘れている - 環境の不一致:環境変数やバージョンの違いにより、ローカルでは動作するが CI/本番環境では失敗する
ルール
- 推測しないでください — 必ず証拠で検証します
- 症状ではなく、根本原因を修正します
- 15 分間進展がなければ、いったん立ち止まって切り分け直します
- 失敗した方法を繰り返さないよう、試したことを記録します
コメント
Markdown 対応