
Diagnose と Triage:まずフィードバックループを確立し、次に誰に任せるかを決定する
Matt Pocock の /diagnose と /triage という2つのエンジニアリングスキルを分解します。一方は再現可能なフィードバックループを使ってバグの根本原因を特定し、もう一方は issue を needs-info、ready-for-agent、ready-for-human、または wontfix に進めます。
2つのスキルをまとめて説明する理由
/diagnose と /triage は README では独立したスキルですが、同じエンジニアリング問題の2つの側面を解決します。
/diagnoseは、このバグが何であるか、どのように再現するか、どのように修正されたことを証明するかに関心があります。/triageは、この issue が現在、情報待ち、エージェントに任せるべきか、人間に任せるべきか、それとも何もしないべきかに関心があります。
一方は事実を担当し、もう一方はプロセスを担当します。実際のプロジェクトでは、これら2つはしばしば連携しています。まずバグ issue をトリアージし、情報が不足している場合は needs-info にします。情報が十分であれば、diagnose を使用してフィードバックループを構築します。再現が明確になったら、ready-for-agent にするか ready-for-human にするかを決定します。
/diagnose の核心:フィードバックループがすべて
/diagnose で最も覚えておくべきことは、まずエージェントが実行できる pass/fail シグナルを確立するということです。
Matt は診断を6つの段階に分けています。
| 段階 | 目標 |
|---|---|
| Build a feedback loop | 迅速で確実、繰り返し実行可能な失敗シグナルを構築する |
| Reproduce | このシグナルでユーザーが記述したのと同じバグを再現する |
| Hypothesise | 3〜5つの反証可能な仮説を立てる |
| Instrument | 最小限のプローブで仮説を検証する |
| Fix + regression test | 適切なテスト面で回帰テストを書き、修正する |
| Cleanup + post-mortem | 一時的なプローブをクリーンアップし、真の根本原因を記録する |
これは、多くの人がバグをデバッグする順序とは逆です。一般的なデバッグプロセスは、コードを見て、原因を推測し、修正し、ページを更新するというものです。Matt は逆で、まずバグを再現可能な機械シグナルに変えてから、仮説を立てます。
良いフィードバックループとは
/diagnose は、優先順位の高いものから低いものまで、一連のフィードバックループを提供しています。
| ループ | 適切なシナリオ |
|---|---|
| 失敗テスト | 適切なテスト面があり、バグを直接表現できる |
| curl / HTTP script | API バグ、サーバーサイドの動作はリクエストで再現可能 |
| CLI + fixture | コマンドラインツール、パーサー、トランスフォーマー |
| Headless browser | UI バグ、コンソールエラー、ネットワーク動作 |
| Replay captured trace | オンラインの実際のペイロード、イベントストリーム、ログトレース |
| Throwaway harness | システムの一部のみを起動し、複雑な依存関係を隔離する |
| Property / fuzz loop | 偶発的なエラー出力、トリガー率を上げる必要がある |
| Bisection / differential loop | あるバージョン以降で壊れた場合、二分探索または旧バージョンとの比較が必要 |
| HITL script | 手動でクリックする必要がある場合でも、スクリプトに従って安定した出力を提供させる |
ここで非常に重要な判断があります。ループがなければ、仮説段階に進まないでください。シグナルがなければ、すべての分析は「〜のように見える」になってしまいます。
非決定性バグにはどう対処するか
/diagnose は、偶発的なバグに対するアプローチも非常に実用的です。目標は、最初から100%再現することではなく、まず再現率をデバッグ可能なレベルにまで高めることです。
例えば:
- 100回ループでトリガーする
- 並行してトリガーする
- スリープを注入して競合ウィンドウを拡大する
- ランダムシードまたは時間を固定する
- 環境変数と外部依存関係を縮小する
1% の偶発的なバグはデバッグが困難ですが、50% の偶発的なバグはすでにデバッグ可能な対象です。この考え方は、フロントエンドの非同期処理、メッセージキュー、支払いコールバック、ストリーミング出力などに非常に役立ちます。
仮説は反証可能でなければならない
Matt は、検証に着手する前に3〜5つの仮説を立て、各仮説について予測を記述することを求めています。
X が原因であれば、Y を変更するとバグは消えるはずです。
または、Z を観察すると、特定の特性が現れるはずです。これにより、エージェントが最初に合理的に見える説明に固執するのを防ぎます。さらに重要なのは、特定の実験が情報量を持っているかどうかを判断できるようになることです。
悪い仮説:
キャッシュの問題かもしれません。反証可能な仮説:
ブラウザのキャッシュが古いスクリプトの実行を引き起こしている場合、キャッシュを無効にして強制的に更新すると、コンソール内の古いバンドルハッシュが消え、ボタンのクリックイベントも回復するはずです。後者こそ検証する価値があります。
修正段階で最も犯しやすい間違い
/diagnose は、適切なテスト面がある場合、まず最小限の再現を失敗テストに変換し、それからコードを修正することを要求します。
重要なのは「適切なテスト面」です。単にユニットテストを追加するだけでは回帰テストにはなりません。適切なテスト面は、実際のバグパターンをカバーする必要があります。
- バグが複数の呼び出し元の組み合わせによってトリガーされる場合、単一の関数だけをテストしてはいけません。
- バグが実際のペイロード構造によってトリガーされる場合、手書きの玩具オブジェクトだけをテストしてはいけません。
- バグがブラウザのイベント順序によってトリガーされる場合、純粋な関数だけをテストしてはいけません。
適切なテスト面が見つからない場合、それ自体が結論です。コード構造がバグを特定できる場所を残していません。修正後、この情報を /ja/docs/notes/matt-pocock-skills/improve-codebase-architecture に渡すべきです。
/triage の核心:issue はステートマシン
/triage は、AI に「issue を見て」と漠然と頼むものではありません。issue を小さなステートマシンとして扱います。
各 issue は同時に以下を持つべきです。
- カテゴリ:
bugまたはenhancement - 状態:
needs-triage、needs-info、ready-for-agent、ready-for-human、wontfix
この状態セットの価値は、メンテナーが迅速に以下の質問に答えられるようにすることです。
- まだ誰も見ていないものはどれか?
- 報告者からの情報待ちのものはどれか?
- AFK エージェントに任せられるほど明確なものはどれか?
- 人間が自分でやらなければならないものはどれか?
- 閉じるべきで、その理由を記録すべきものはどれか?
ready-for-agent の基準
ready-for-agent は、このプロセスで最も重要な状態です。「このタスクは AI に試させることができる」という意味ではなく、
タスクは、不在のエージェントが独立して受け取り、実装し、検証できるほど明確である。
これは通常、issue に少なくとも以下のものが含まれていることを意味します。
- 背景と問題の記述
- 関連するコードパスまたはモジュール
- 明確な受け入れ基準
- 既知の制約
- バグの場合、再現方法があることが望ましい
- 追加の製品/設計判断は不要
これらが不足している場合、needs-info または ready-for-human であるべきであり、無理にエージェントに投げつけるべきではありません。
needs-info は具体的な質問をする
/triage は needs-info のテンプレートを非常にシンプルにしていますが、重要なのは質問が具体的でなければならないことです。
## Triage Notes
**What we've established so far:**
- ...
**What we still need from you (@reporter):**
- ...悪い質問:
詳細情報を提供してください。良い質問:
問題が発生したブラウザのバージョン、エラーページの URL、クリック順序、および Network パネルの `/api/orders/:id` のレスポンスボディを提供してください。AI は丁寧な定型文を書きがちですが、このスキルは「私たちがすでに知っていること」と「まだ不足していること」を区別するように強制します。
wontfix も蓄積する
/triage は、enhancement の wontfix について興味深い設計をしています。単に issue を閉じるだけでなく、拒否理由を .out-of-scope/ 知識ベースに書き込み、コメントでリンクします。
これにより、次回同様の要求があったときに、AI は同じ議論を最初からやり直すことはありません。まず .out-of-scope/ を読み、メンテナーに「この方向は以前に X という理由で拒否されました」と注意を促すことができます。
これは ADR の精神とよく似ています。すべての決定を記録するのではなく、将来的に疑問を抱かせ、繰り返し発生する決定のみを記録します。
両者の連携方法
典型的なバグ issue は次のように進みます。
/triageが issue、コメント、ラベル、関連コードを読み込むbug + needs-triageと判断する- まず再現を試みる。手順が不足している場合は
needs-infoに変更する - 情報が十分になったら、
/diagnoseを起動する /diagnoseが再現ループを確立し、仮説を立て、根本原因を特定する- 修正パスが明確で、テスト面が明確な場合、issue は
ready-for-agentになる - 製品判断、外部権限、手動検証が必要な場合、issue は
ready-for-humanになる - 修正後、根本原因と回帰テストを issue または PR に書き戻す
このプロセスの鍵は「AI が自動的にバグを修正する」ことではなく、issue を曖昧な記述から実行可能な作業パッケージに変えることです。
私の使用提案
もし1つだけ覚えるなら:
/diagnoseはまず「それが壊れていることをどう証明するか」と問い、/triageはまず「それは今どの状態にあるべきか」と問います。
この2つの質問は、大量の低品質な AI プログラミングを防ぐことができます。
- 再現せずに修正する
- 受け入れ基準なしで作業を開始する
- 根本原因なしでリファクタリングする
- 情報なしでエージェントに丸投げする
Matt のこれら2つのスキルは派手ではありませんが、実際のチームのベテランエンジニアがすることによく似ています。まず事実を整理し、次にプロセスを進めます。
参考リソース
diagnose 源文件
困難なバグとパフォーマンスの回帰のための規律ある診断プロセス。
triage 源文件
一連のトリアージロールを通じて issue の状態を遷移させる。