debug-hypothesis について
コーディングエージェント向けの仮説駆動型デバッグスキルです。観察、仮説、実験、結論の4段階で進め、証拠による確認前の修正を禁じ、調査記録を DEBUG.md に残します。
主な機能
- 014段階のデバッグループ
- 02根本原因の仮説を作成・順位付け
- 03実験の変更を5行以内に制限
- 04DEBUG.md に調査を記録
- 05原因確認後に回帰テストを追加
活用シーン
- 01原因が明確でないテスト失敗の調査
- 02修正後に再発する不具合の追跡
- 03未知のクラッシュやエラーの診断
- 04環境間で異なる挙動の調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ lichamnesia/ lich-skills --skill debug-hypothesisインストール後、Claude Code で/debug-hypothesisを入力して読み込まれたか確認します。
詳細
仮説駆動デバッグ
デバッグを「適当に修正を試して、うまくいくことを期待する」やり方から、規律ある調査へと変える4段階のループです。各フェーズには目標、厳格なルール、そしてフェーズを省略するためにエージェントが持ち出す言い訳に対する反論の表があります。
基本原則:**仮説が正しいという証拠を得るまでは、修正を書いてはいけません。**推測はデバッグではありません。
使用する場面
- テストが失敗し、原因がすぐにはわからない
- 同じバグが二度「修正」されたのに、再発した
- エージェントが試した修正がうまくいかなかったとき、次の修正を試すのを止める
- 見たことのないクラッシュやエラーメッセージが発生した
- 明らかな原因が見当たらないパフォーマンスの低下
- 環境(ローカルと CI、開発環境と本番環境)によって挙動が異なる
- エージェントがループに陥り、同じ誤った修正を繰り返している
使用しない場面
- タイポ、インポート漏れ、構文エラー — そのまま修正してください
- 明らかな1行の原因があるビルド失敗
- 原因と場所を正確に示すコンパイラーやリンターのメッセージ
- 根本原因がすでにわかっており、修正を書くだけでよい場合
修正を一度試してもバグが残るなら、すぐにこのスキルに切り替えてください。
デバッグループ
OBSERVE ──▶ HYPOTHESIZE ──▶ EXPERIMENT ──▶ CONCLUDE
│ │ │ │
▼ ▼ ▼ ▼
Gather List 3-5 One minimal Root cause
symptoms, possible test per confirmed
reproduce causes + hypothesis, or loop
reliably evidence max 5 lines back
│ │ │ │
└──────────────┴──────────────────┴───────────────┘
write everything to DEBUG.md
厳格なルール:
- すべてを
DEBUG.mdに記録します。会話にしか残していない推論は、コンテキストの圧縮によって失われます。 - 観察、仮説、実験の各フェーズでは、修正コードを書いてはいけません。
- 仮説を省略してはいけません。「原因はわかっていると思う」も仮説です。書き留め、ほかの仮説と同じように検証してください。
- 1回の実験で変更できるのは最大5行です。実験にそれ以上必要なら、仮説が曖昧すぎるので、分割してください。
フェーズ1:観察
目標。 生の事実を収集します。バグを再現します。わかっていることと思い込んでいることを切り分けます。
手順。
- バグを再現します。正確なエラーメッセージ、スタックトレース、または誤った出力を取得します。再現できない場合、それが最初の発見です。
- 最小の再現手順を見つけます。バグがまだ発生する状態を保ちながら、無関係なコードを取り除きます。
- 環境を記録します。OS、ランタイムのバージョン、依存関係、設定を記録してください。
- 正常に動作するものを書き留めます。正常に動作する部分と壊れている部分の境界に、バグの原因があります。
- すべての観察事項を
DEBUG.mdの## Observationsに記録します。
終了条件。
- バグを再現した(または、条件を添えて再現できないことを記録した)
- 正確なエラーメッセージ、または誤った挙動を記録した
- 最小の再現手順を特定した
- 観察事項を
DEBUG.mdに記録した
よくある言い訳
| 言い訳 | 実際のところ |
|---|---|
| 「何が悪いかはもうわかっている」 | それなら仮説として書き、証明してください。正しければ2分で済みます。 |
| 「先にこの簡単な修正だけ試させて」 | そうして、45分も費やし、6回も失敗することになります。 |
| 「エラーメッセージだけで十分わかる」 | エラーメッセージが示すのは症状であって原因ではありません。NullPointerException は何が停止したかを示しますが、なぜ停止したかは示しません。 |
| 「コードを見ればバグがわかるから、再現する必要はない」 | 本当にわかるのですか? では、なぜまだ修正されていないのでしょうか? |
フェーズ 2:仮説を立てる
目標。 考えられる根本原因を 3~5 個挙げます。それぞれについて、フェーズ 1 の裏付けとなる証拠と、反証となる証拠を列挙します。可能性の高い順に並べます。
手順。
- 仮説を 3~5 個挙げます。1 個ではなく、「原因は X だと思います」だけでもいけません。最低 3 個です。以下のカテゴリを幅広く検討してください。
- データ:入力の誤り、フィールドの欠落、型の不一致、エンコーディング
- ロジック:条件の誤り、オフバイワン、競合状態、順序の誤り
- 環境:設定、バージョン、依存関係、権限
- 状態:古いキャッシュ、状態の漏出、初期化順序
- 各仮説について、次の項目を書きます。
- 裏付け: この仮説を支持する観察結果からの証拠
- 反証: この仮説に反する証拠
- テスト: 仮説を証明または反証できる、最小限の実験
- 根本原因の仮説を示します。これは、裏付けとなる証拠があり、反証となる証拠がない仮説です。複数が該当する場合は、最もテストしやすいものを選びます。
- すべてを
DEBUG.mdの## Hypothesesの下に書きます。
DEBUG.md の形式例:
## Hypotheses
### H1: Race condition in session middleware (ROOT HYPOTHESIS)
- Supports: only happens under concurrent requests, timing-dependent
- Conflicts: none yet
- Test: add mutex lock around session read, check if bug disappears
### H2: Stale cache returning expired token
- Supports: works after restart (cache cleared)
- Conflicts: cache TTL is 5min, bug appears within 30s
- Test: disable cache, reproduce
### H3: Wrong env variable in CI
- Supports: works locally, fails in CI
- Conflicts: env diff shows identical values
- Test: print actual runtime value in CI logs
完了条件。
- 仮説を 3 個以上記載している
- それぞれに裏付けとなる証拠と反証となる証拠がある
- それぞれに具体的で最小限のテストがある
- 根本原因の仮説を特定している
- すべてを
DEBUG.mdに記載している
よくある言い訳
| 言い訳 | 実際 |
|---|---|
| 「仮説が 1 つしかありません」 | それは一番気に入っている仮説が 1 つあるということです。もっと考えてください。違うとしたらどうでしょうか? |
| 「これを書き出すのは時間がかかります」 | 書き出さずにデバッグするほうが時間がかかります。圧縮で仮説 2 が消えたあと、忘れてしまいます。 |
| 「最初の仮説が明らかに正しいです」 | なら、証明には 2 分しかかかりません。証明を省くと、間違いだと判明したときに 30 分費やすことになります。 |
| 「反証となる証拠がありません」 | それは十分に調べていないか、本当に根本原因であるかのどちらかです。いずれにしてもテストしてください。 |
フェーズ 3:実験する
目標。 根本原因の仮説を、可能な限り小さな変更でテストします。 あなたは科学者です。仮説を確認するのではなく、反証することを目指してください。
手順。
- 実行する前に実験について書きます。何を変更しますか? どの結果が仮説を裏付けますか? どの結果が仮説を否定しますか?
- 変更を加えます。最大 5 行までです。 それ以上必要なら、仮説が曖昧すぎます。
- フェーズ 1 の再現手順を実行します。
- 結果を
DEBUG.mdの## Experimentsの下に記録します。
実験のルール。
- 一度に変更する変数は 1 つだけです。「時間を節約するため」に 2 つの修正を組み合わせてはいけません。
- 本番環境向けの修正コードは書かないでください。診断用コードを書きます。ログ出力、アサーション、簡略化したロジック、ハードコードした値などです。
- 結果を記録したら、実験内容を元に戻します。作業ツリーをクリーンに保ってください。
- 実験で結論が出なくても、それも結果です。記録し、次の仮説をテストしてください。
完了条件。
- 実験を実行している(変更 1 つ、変数 1 つ)
- 結果を記録している:裏付け、否定、または結論が出ない
- 実験用コードを元に戻している
- 結果を
DEBUG.mdに記載している
よくある言い訳
| 言い訳 | 実際 |
|---|---|
| 「テストせずに、そのまま修正させてください」 | 原因を確認せずに修正するのは、間違った修正を出荷し、別の問題を引き起こす原因です。 |
| 「時間を節約するため、一度に 2 つテストします」 | 両方を変更してバグが消えたら、どちらが直したのでしょうか? 結局、もう一度テストすることになります。 |
| 「5 行では足りません」 | ログ、アサーション、ハードコードした値、またはショートサーキットを追加するには 5 行で十分です。足りないなら、あなたの仮説は「どこかで何かがおかしい」であり、仮説とは言えません。 |
| 「元に戻す必要はありません。修正がそのまま実験です」 | 実験は診断用です。修正は本番環境向けのコードです。求められる品質基準は異なります。 |
フェーズ 4:結論を出す
目標。 根本原因を確認し、実際の修正を行い、回帰テストを追加します。
手順。
- 根本仮説が確認された場合:
- 根本原因を一文で
DEBUG.mdに記述します。 - ここで初めて、本番環境向けの修正コードを書きます。
- 修正がなければ失敗し、修正があれば成功する回帰テストを追加します。
- 修正とテストを一緒にコミットします。
- 根本原因を一文で
- 根本仮説が否定された場合:
- 否定したことと、その根拠を
DEBUG.mdに記録します。 - 次の仮説を根本仮説に昇格させます。フェーズ 3 に戻ります。
- すべての仮説が否定された場合は、新たな観察事項を得るためにフェーズ 1 に戻ります。
- 否定したことと、その根拠を
DEBUG.mdを更新し、最終的な## Root Causeと## Fixのセクションを記述します。
終了条件。
- 根本原因を特定し、一文で記述した
- 修正をコミットした
- 回帰テストをコミットした
-
DEBUG.mdに調査の全経緯を記録した - 元の再現ケースが成功する
よくある言い訳
| 言い訳 | 実際のところ |
|---|---|
| 「回帰テストは必要ありません。簡単な修正です」 | 簡単なバグに対する簡単な修正なら、このスキルは必要ありません。ここにいるのは、簡単ではなかったからです。テストを追加してください。 |
「DEBUG.md はデバッグ用にすぎないので、削除します」 | 残してください。同じ箇所をデバッグする未来のあなたは、今のあなたに感謝するでしょう。 |
| 「すべての仮説が外れて、行き詰まりました」 | 「観察」に戻ってください。何かを見落としています。バグが存在する以上、原因も存在します。 |
ブルドーザー禁止ルール
AI によるデバッグで最もよくある失敗は、エージェントが仮説を立て、「修正」コードを 150 行書き、うまくいかないと、同じ誤った仮説をさらに掘り下げて、また 150 行書くことです。
このスキルは、それを防ぐためのものです。 自分やエージェントが次のような状態になったら:
- 仮説を確認する前に 5 行を超えるコードを書いている → STOP。フェーズ 2 に戻ります。
- 同じアプローチを 2 回目に試そうとしている → STOP。仮説は否定されました。次に進みます。
- 矛盾する証拠を無視している → STOP。記録し、仮説の順位を付け直します。
- 3 回失敗した後で「もう少しでできそう」と感じている → STOP。ブルドーザーのように突き進んでいます。
記録してください。テストしてください。立証してください。それから修正してください。