Claude Codeを使った反復可能なバグトリアージループ:再現、最小化、証拠に基づく原因特定、回帰テスト追加、狭い修正と検証。

バグは、毎回の報告が一度きりの謎になると偶発的に感じられます。コードをつついていくつか試し、問題が消えることを期待する。たまにそれで直ることもありますが、学びは少なく、同じ問題が別の形で再発します。
バグトリアージはその反対です。不確実性を速やかに減らす方法です。目的はすべてをただちに直すことではありません。目的はあいまいな訴えを明確でテスト可能な宣言に変え、その宣言がもはや成り立たないことを示す最小の変更をすることです。
だからこのループが重要です:再現し、最小化し、証拠を伴って考えられる原因を特定し、回帰テストを追加し、狭い修正を実装し、そして検証する。各ステップが特定の種類の推測を取り除きます。ステップを飛ばすと、後でより大きな修正、副作用、あるいは「直った」と見せかけたまま実際は直っていないバグに苦しむことになります。
現実的な例を示します。ユーザーが「保存ボタンが時々何もしない」と言ったとします。ループがなければUIコードを漁り、タイミングや状態、ネットワーク呼び出しを変更してしまうかもしれません。ループを使うと、まず「時々」を「この正確な条件下では毎回」に変えます。たとえば:「タイトルを編集して、すぐにタブを切り替えると、保存が無効のままになる。」この一文だけで進展です。
Claude Codeは思考の速度を上げる手助けになります:レポートを正確な仮説に変え、どこを見ればいいかを提案し、失敗するはずの最小のテストを示してくれます。コード、ログ、最近の差分を素早くスキャンしてもっともらしい説明を生成するのに特に役立ちます。
それでも重要なのはあなた自身の検証です。自分の環境でバグが実際に発生することを確認してください。良い話に聞こえるだけではなく、ログ、トレース、失敗するテストなどの証拠を優先してください。修正はできるだけ小さくし、回帰テストで証明し、明確なチェックで検証して別のバグを生まないようにします。
見返りは、小さく安全な修正です。説明でき、防衛でき、再発を防げる修正が得られます。
良い修正はクリーンなワークスペースと単一の明確な問題文から始まります。Claudeに聞く前に、ひとつの報告を選び、次のように書き直してください:
「私がXをすると、Yを期待するが、Zが起きる。」
その文が書けないなら、まだバグではなく謎を抱えています。
初めに基本情報を集めておけば、何度も戻る手間が省けます。これらの詳細が、提案をあいまいではなくテスト可能にします:アプリのバージョンやコミット(ローカル、ステージング、プロダクションのどれか)、環境詳細(OS、ブラウザ/デバイス、機能フラグ、リージョン)、正確な入力(フォームフィールド、APIペイロード、ユーザー操作)、誰が見ているか(全員、特定ロール、単一アカウント/テナント)、期待することの定義(文言、UI状態、ステータスコード、ビジネスルール)。
次に、証拠を保存してください。タイムスタンプひとつで何時間も節約できます。イベント周辺のログ(可能ならクライアントとサーバー)、スクリーンショットや短い録画、リクエストIDやトレースID、正確なタイムスタンプ(タイムゾーン込み)、問題を引き起こす最小のデータスニペットを取得します。
例:Koder.aiが生成したReactアプリで「Payment succeeded」と表示されるが注文は「Pending」のままになる。ユーザーロール、正確な注文ID、APIレスポンスボディ、該当リクエストIDのサーバーログ行を記録します。これでClaudeにあるフローに集中するように頼めます。
最後に終了ルールを設定します。コードを書き始める前に何をもって「直った」と見なすかを決めてください:特定のテストが通ること、UI状態が変わること、ログにエラーが出なくなること、さらに毎回実行する短い検証チェックリスト。こうすれば症状を「直した」として別のバグを出さずに済みます。
雑然としたバグ報告は事実、推測、感情が混ざっています。助けを求める前に、Claudeが証拠付きで答えられるような明確な質問に変えましょう。
まず、機能と失敗を名指しする1文の要約を作ります。良い例:「下書きを保存するときに、モバイルでタイトルが消えることがある。」悪い例:「下書きが壊れている。」その文がトリアージスレッド全体のアンカーになります。
次に見たものと期待したものを分けます。退屈で具体的に:押したボタン、画面のメッセージ、ログ行、タイムスタンプ、デバイス、ブラウザ、ブランチ、コミット。もしまだ無ければ、その旨を書きます。
貼り付け可能な簡単な構成:
欠けている詳細があれば、はい/いいえで答えられる質問にして尋ねてください:新しいアカウントで起きるか?モバイルのみか?リフレッシュ後だけか?最後のリリース以降か?シークレットウィンドウで再現するか?
Claudeは「レポート整形屋」としても有用です。元の報告(スクリーンショットのテキスト、ログ、チャットの断片を含む)を貼り付けて、こう頼んでください:
「これを構造化されたチェックリストに書き直して。矛盾を指摘して。トップ5の欠けている事実をはい/いいえ質問で挙げて。原因はまだ推測しないで。」
もしチームメイトが「ランダムに落ちる」と言ったら、それをテスト可能な形に押し上げてください:「iPhone 14、iOS 17.2で2/10回失敗、Saveを素早く2回タップすると発生」——これで意図的に再現できます。
バグを任意に発生させられないなら、その後の作業はすべて推測です。
まず、問題を示せる最小限の環境で再現します:ローカルのdevビルド、最小ブランチ、最小データセット、できるだけ少ないサービスで。
正確な手順を書き留め、他の人が質問せずにそのまま実行できるようにします。コマンド、ID、サンプルペイロードをそのままコピーできる形式で含めてください。
シンプルなキャプチャテンプレート:
頻度は戦略を変えます。"Always"のバグは反復が速くて扱いやすい。"Sometimes"はタイミング、キャッシュ、レースコンディション、隠れた状態を示すことが多い。
再現ノートができたら、Claudeにアプリを書き換えず不確実性を減らすための素早いプローブを頼んでください。良いプローブは小さいものです:失敗境界付近の1行のログ(入力、出力、キーとなる状態)、特定コンポーネントのデバッグフラグ、決定論的な挙動を強制する方法(固定乱数シード、固定時刻、単一ワーカー)、問題を引き起こす小さなシードデータセット、再生できる単一のリクエスト/レスポンスペア。
例:サインアップフローが「ときどき」失敗する場合、Claudeは生成されるユーザーID、メール正規化結果、ユニーク制約エラーの詳細をログに出し、同じペイロードを10回実行することを提案するかもしれません。もし失敗がデプロイ直後の最初の実行だけなら、マイグレーション、キャッシュウォームアップ、欠落したシードデータを疑うべきです。
良い再現は有用です。最小の再現は強力です。理解が速く、デバッグしやすく、誤って「直った」ことが起きにくいからです。
必要ないものはすべて削ぎ落とします。長いUIフローのあとでバグが出るなら、まだ発生する最短経路を見つけます。オプションの画面、機能フラグ、無関係な統合を取り除き、バグが消えるか残るかを確認します。
次にデータを縮めます。大きなペイロードが必要なら、壊れる最小のペイロードを探します。500件のリストが必要なら、5件、次に2件、次に1件で試します。フィールドを1つずつ削除します。目標は、バグを再現するために必要最小限の要素だけを残すことです。
実務的な方法は「半分に切って再テストする」:
例:クーポンを適用するときにチェックアウトページが時々クラッシュする。調べた結果、カートに少なくとも1つの割引対象アイテムがあり、クーポンが小文字で、配送方法が"pickup"のときだけ失敗することが分かった。これが最小ケースだ:1つの割引商品、1つの小文字クーポン、1つのピックアップ設定。
最小ケースが明確になったら、Claudeにそれを小さな再現スキャフォールドに変えてもらいましょう:失敗する関数を最小の入力で呼ぶテスト、縮小したペイロードで1つのエンドポイントを叩く短いスクリプト、1つのルートを訪れて1つのアクションを行う小さなUIテストなど。
問題を再現でき、最小テストケースを持っているなら、推測はやめてください。短い候補リストに絞り、それぞれを立証または否定するのが目的です。
有用なルールは仮説を3つに抑えること。3つを超えるならテストケースがまだ大きいか観察があいまいです。
見ているものを、どこで起きている可能性があるかに変換します。UIの症状が必ずしもUIバグを意味しないことに注意してください。
例:Reactページで「Saved」のトーストが出るが後でレコードが見つからない。これは(1)UI状態、(2)API挙動、(3)データベース書き込み経路のいずれかを示します。
Claudeに平易な言葉で起こりうる失敗モードを説明してもらい、それぞれを確かめる証拠を尋ねてください。目標は「もしかして」から「これをチェックして」と言える状態にすることです。
3つの一般的な仮説と集めるべき証拠:
ノートは簡潔に:症状、仮説、証拠、判定。1つの仮説が事実と合致すれば、回帰テストを固定し、必要最低限だけを直す準備ができます。
良い回帰テストは安全ベルトです。バグが存在したことを証明し、真に直ったかを教えてくれます。
まず、実際の失敗に合った最小のテストを選びます。バグが複数のパートの協調で起きるなら、ユニットテストでは見逃すことがあります。
関数が誤った値を返すならユニットテストを、境界の問題なら統合テストを(APIハンドラ+DB、クライアント+API)、フルユーザーフローが必要ならE2Eを選びます。
Claudeに何か書いてもらう前に、最小化ケースを厳密な期待動作として言い直してください。例:「ユーザーが空のタイトルを保存した場合、APIは'400'と'title required'メッセージを返すこと」。こうすればテストのターゲットが明確になります。
次にClaudeにまず失敗するテストを起草してもらいましょう。セットアップは最小限にし、バグを引き起こすデータだけをコピーしてください。テスト名は内部関数ではなくユーザー体験に基づいて名付けます。
ざっと自分で確認してください:
テストが正しい理由で失敗したら、狭い修正を自信を持って進められます。
小さな再現と失敗する回帰テストがあれば、「掃除しておこう」という誘惑に抵抗してください。目標はテストを正しい理由で通すための最小の変更です。
良い狭い修正は影響範囲が小さいものです。失敗が1つの関数にあるならその関数を直し、モジュール全体を変えないでください。境界チェックが欠けているなら境界でチェックを追加し、呼び出し全体に広げないでください。
Claudeに手伝ってもらうなら、2つの修正案を出してもらい、範囲とリスクで比較してください。例:フォームが空のフィールドでクラッシュする場合、
通常トリアージではAを選びます:小さく、レビューしやすく、壊す可能性が低い。
狭い修正を保つためのルール:できるだけ少ないファイルを触る、リファクタより局所修正を優先する、悪い値が入る境界でガードを追加する、挙動変更は1つの明確なビフォー/アフターにする。理由が明白でない場合にのみコメントを残します。
具体例:GoのAPIエンドポイントがオプションクエリパラメータがないとpanicするなら、狭い修正はハンドラの境界で空文字を処理する(デフォルトでパースするか、400を返す)。共有パーサユーティリティを変えるのは、回帰テストが共有コードに原因があると証明した場合に限ります。
変更後は失敗したテストと近接する1〜2テストを再実行します。関係ない多くのテストを更新する必要があるなら、変更が広すぎるサインです。
検証では、1つのテストを通すだけで見逃しがちな問題を捕まえます:ある修正が1つのテストは通すが近いパスを壊す、エラーメッセージを変える、遅いクエリを導入する、など。
まず追加した回帰テストを再実行してください。通ったら近接するテスト(同じファイル、モジュール、同じ入力を扱うもの)を実行します。バグは共有ヘルパー、パース、境界チェック、キャッシュに潜むことが多く、関係ある失敗は近くに出ることが多いです。
その後、元の報告手順に従った簡単な手動チェックを行います。短く具体的に:同じ環境、同じデータ、同じクリックやAPI呼び出しの順序。報告があいまいだったら、あなたが再現に使った正確なシナリオで試します。
必要ならClaudeにあなたの変更と失敗シナリオを共有して短い検証プラン(単体、統合、手動チェック)を作ってもらってください。最高のプランは短く実行可能で、5〜8個のチェックに分かれており、それぞれに明確な合否基準があります。
最後に、PRやノートに何を検証したかを書いておきます:実行したテスト、試した手動手順、テストしていない範囲(例:「モバイルは未確認」)など。こうすれば修正が信頼しやすくなります。
最速で時間を無駄にする方法は、再現できる前に「直した」と受け入れることです。確実に失敗させられないなら、何が本当に改善したか分かりません。
実務的ルール:正確な手順、入力、環境、何が"間違っている"かを記述できるまでは修正を求めないでください。報告があいまいなら、最初の数分を使って2回実行して同じ結果が出るチェックリストに変えてください。
再現ケースなしで修正する。 最小の「毎回失敗する」スクリプトや手順を要求してください。もし「ときどき」なら、タイミングやデータサイズ、フラグ、ログを記録してランダム性を取り除くまで続けてください。
早すぎる最小化。 元の失敗をロックダウンする前にケースを削りすぎると信号を失います。まずベースライン再現を確認し、そこから一つずつ縮めていってください。
Claudeに推測させる。 Claudeは可能性を提案できますが、証拠が必要です。2〜3の仮説と、それぞれを支持/棄却するための具体的観察(ログ行、ブレークポイント、クエリ結果)を求めてください。
間違った理由で通る回帰テスト。 テストが通る理由が失敗パスに到達していないことがあります。修正前にテストが失敗すること、期待するメッセージやアサーションで失敗することを確認してください。
症状を処理してしまい、トリガーを直さない。 nullチェックを追加しただけで「その値はそもそもnullになってはいけない」という本当の問題を隠してしまうことがあります。悪い状態を生む条件を優先して直す方が望ましい場合があります。
新しい回帰テストと元の再現手順を変更前と変更後で実行してください。もしチェックアウトのバグが、配送変更後にプロモコードを適用したときだけ起きるのなら、その全シーケンスを"真実"として保持してください(最小化したテストが小さくても)。
「今は見た目問題ない」で検証が終わるなら、次の人が素早く確かめられるように1つの具体的なチェック(ログ、メトリクス、特定の出力)を追加してください。
時間がないときは、小さく繰り返せるループが英雄的なデバッグに勝ります。
最終決定は数行で書いておき、次の人(多くの場合は将来の自分)が信頼できるようにします。役立つフォーマット:"Root cause: X. Trigger: Y. Fix: Z. Why safe: W. What we did not change: Q."。
次のステップ:自動化できるものは自動化してください(保存した再現スクリプト、標準テストコマンド、根本原因ノートのテンプレートなど)。
もしあなたがKoder.ai(koder.ai)でアプリを作るなら、Planning Modeはコードに触る前に変更のアウトラインを作るのに役立ち、スナップショット/ロールバックは難しい再現作業中に安全に実験するのを容易にします。修正が検証されたら、ソースをエクスポートしたり、更新したアプリをホストしてデプロイしたりできます(必要ならカスタムドメインも設定可能)。
バグトリアージとは、あいまいな報告を「テストできる明確な文」に変え、その文がもう成り立たないことを証明するために最小限の変更を加える習慣です。
それは「すべてを直す」ことよりも不確実性を段階的に減らすことに重きを置きます:再現、最小化、証拠に基づく仮説作成、回帰テスト、狭い修正、検証。
それぞれのステップが別の種類の推測を取り除くからです。
次のように書き直してください:「私がXをすると、Yを期待するが、Zが起きる」。
その後、テスト可能にするために必要なコンテキストだけを集めます:
まずはローカル開発環境など、問題を示せる最小の環境で再現できるか確認してください。
「ときどきしか起きない」なら、変数を制御して決定論的にする努力をします:
再現できるようになるまでは先に進まないでください。できなければ推測になってしまいます。
最小化とは、バグを引き起こすために必要なもの以外を削ることです。
実務的な方法は「半分に切って再テストする」:
手順(短いユーザーフロー)とデータ(小さなペイロード、少ないアイテム)の両方を縮め、最小の再現トリガーを見つけます。
Claude Codeは分析を速めますが、検証を置き換えません。
良いリクエスト例:
その後、ローカルで再現し、ログ/トレースを確認し、テストが正しい理由で失敗することを確かめてください。
同時に考える仮説は3つに抑えてください。それ以上だと再現ケースがまだ大きいか、観察があいまいなことが多いです。
各仮説について書くもの:
バグに合った最小のテストレベルを選んでください:
良い回帰テストは:
失敗する回帰テストを通す最小限の変更を行ってください。
経験則:
短いチェックリストで手早く検証してください:
実行したことと実行しなかったことをPRやノートに記録しておくと信頼できる修正になります。
これにより作業が前に進みます。