debug-agent について
debug-agentは、ランタイムの証拠に基づく調査をコーディングエージェントに指示するスキルです。仮説、ログ、再現、分析、修正の検証までの手順を定めています。
主な機能
- 01ランタイム証拠に基づくデバッグ手順
- 02仮説に沿ったログの設置
- 03NDJSONログサーバーの設定
- 04ログによる修正の検証
- 05デバッグログ保持のルール
活用シーン
- 01コードだけでは原因を特定しにくい問題の調査
- 02再現時に複数の原因候補を検証
- 03修正前後のランタイムログによる確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ millionco/ expect --skill debug-agentインストール後、Claude Code で/debug-agentを入力して読み込まれたか確認します。
詳細
デバッグモード
現在、デバッグモードです。実行時の証拠に基づいてデバッグしてください。
このアプローチを取る理由: 従来の AI エージェントは、100%の確信があると主張してすぐに修正に取りかかりますが、実行時の情報が不足しているため失敗します。 コードだけを根拠に推測するのです。この方法でバグを修正することはできませんし、絶対にしてはいけません。実際の実行時データが必要です。
体系的な作業手順:
- バグが発生する理由について、具体的な仮説を3~5個立てます(詳細にし、少なくするより多くすることを目指します)
- すべての仮説を並行して検証するため、ログを使ってコードを計測します(「ログ記録」セクションを参照)
- ユーザーにバグを再現してもらいます。明確な番号付き手順を示してください。計測対象のファイルがキャッシュまたはバンドルされている場合は、アプリやサービスを再起動するよう伝えてください。完了したら知らせてもらうよう依頼してください。
- ログを分析します。引用したログ行を根拠に、各仮説を評価します(確認/棄却/判断不能)
- 100%の確信とログによる証明がある場合に限り修正します。計測コードはまだ削除しないでください
- ログで検証します。もう一度実行するようユーザーに依頼し、引用した記録をもとに修正前後のログを比較します
- ログで成功が証明され、ユーザーが確認したら、ログを削除して説明します。失敗した場合は、まず棄却された仮説に基づくコード変更をすべて削除します(計測コードと、証明済みの修正だけは残します)。その後、別のサブシステムを対象に新しい仮説を立て、計測コードを追加します
- 成功が確認されたら、問題を説明し、修正の簡潔な要約(1~2行)を提示します
重要な制約:
- 実行時の証拠を得る前に、絶対に修正しないでください
- 必ず実行時の情報とコードの両方を根拠にしてください(コードだけを根拠にしてはいけません)
- 修正後の検証ログで成功が証明され、問題がほかにないことをユーザーが確認するまでは、計測コードを削除しないでください
- 修正がうまくいかないことはよくあります。試行錯誤を重ねることが望まれます。時間をかけてより多くのデータを集めることで、より適切で精密な修正につながります
ログ記録
STEP 0:ログサーバーを起動する(計測を始める前に必須)
重要:サーバーは長時間稼働するプロセスです。必ずバックグラウンドで実行してください。
計測を始める前に、デバッグサーバーをバックグラウンドプロセスとして起動します。サーバーはデバッグセッション全体を通じて稼働し続けます。1回限りのコマンドではありません。
npx debug-agent 2>&1 &
このコマンドは必ずバックグラウンドで実行してください。 フォアグラウンドで実行してはいけません。完了を待ってはいけません。永続的に稼働するサーバーなので、処理が完了することはありません。&(シェルのバックグラウンド実行)、nohup、またはエージェントのバックグラウンド/非同期コマンド実行を使用してください。エージェントの実行環境が block_until_ms: 0 または同等の機能に対応している場合は、それを使用してください。別のターミナルでコマンドを実行できる場合は、その方法を使ってください。このコマンドでワークフローをブロックしてはいけません。
サーバーは起動時に、単一の JSON 行を標準出力に出力します。
{
"sessionId": "a1b2c3",
"port": 54321,
"endpoint": "http://127.0.0.1:54321/ingest/a1b2c3",
"logPath": "/tmp/debug-agent/debug-a1b2c3.log"
}
以下の値を記録しておいてください。
- サーバーのエンドポイント:
endpointの値(POST リクエストでログを送信する HTTP エンドポイント URL) - ログパス:
logPathの値(NDJSON 形式のログが書き込まれるパス) - セッション ID:
sessionIdの値(このデバッグセッション固有の識別子)
サーバーの起動に失敗した場合は、直ちに停止してユーザーに知らせてください。
- 有効なログ設定が整うまで、計測に進んではいけません。
- サーバーは冪等です。すでに起動している場合は、重複して起動せず、既存のサーバー情報を返します。
- ログファイルを事前に作成する必要はありません。計測コードが初めてログを書き込むときに、自動的に作成されます。
STEP 1:ログ形式を理解する
- ログはNDJSON 形式(1行に1つの JSON オブジェクト)で、ログパスに指定されたファイルに書き込まれます。
- JavaScript/TypeScript の場合、実行時にサーバーのエンドポイントへ POST リクエストを送信し、ログサーバーがその内容を NDJSON の行としてログパスのファイルに書き込みます。
- それ以外の言語(Python、Go、Rust、Java、C/C++、Ruby など)では、言語標準のファイル入出力を使って、ログパスに NDJSON の行を直接追記する方法を優先してください。
ログエントリーの例:
{
"sessionId": "a1b2c3",
"id": "log_1733456789_abc",
"timestamp": 1733456789000,
"location": "test.js:42",
"message": "User score",
"data": { "userId": 5, "score": 85 },
"runId": "run1",
"hypothesisId": "A"
}
STEP 2: 計測ログを挿入する
- JavaScript/TypeScript ファイルでは、ファイルシステムへのアクセスが可能な場合でも、次の1行の fetch テンプレートを使用してください(
ENDPOINTとSESSION_IDをステップ0の値に置き換えてください)。
fetch('ENDPOINT',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({sessionId:'SESSION_ID',location:'file.js:LINE',message:'desc',data:{k:v},timestamp:Date.now()})}).catch(()=>{});
-
JavaScript 以外の言語(Python、Go、Rust、Java、C、C++、Ruby)では、標準ライブラリのファイル I/O を使ってログパスを追記モードで開き、ペイロードを NDJSON の1行として書き込んでから、ファイルを閉じて計測してください。これらのスニペットは、できるだけ小さくコンパクトにしてください(理想的には1行、または数行程度)。
-
調査対象のコードの複雑さと検証する仮説に応じて、挿入する計測ログの数を決めてください。問題の範囲が明確に限定されている場合は、適切な場所に1つログを置くだけで十分なことがあります。複雑な複数ステップのフローでは、より多くのログが必要になる場合があります。すべての仮説を確認または否定できる最小限の数を目指してください。ガイドライン:
- ログを少なくとも1つ追加してください。計測を完全に省略してはいけません。
- ログは10個を超えないでください。さらに必要だと思う場合は、まず仮説の範囲を絞ってください。
- 通常は2~6個ですが、状況に応じて判断してください。
-
仮説に関係する次のカテゴリから、必要なログの配置場所を選んでください。
- パラメーターを伴う関数の開始時
- 戻り値を伴う関数の終了時
- 重要な操作の前の値
- 重要な操作の後の値
- 分岐の実行経路(どの if/else が実行されたか)
- 疑わしいエラー値やエッジケースの値
- 状態の変更と中間値
-
各ログは少なくとも1つの仮説に対応させてください(ペイロードに
hypothesisIdを含めてください)。 -
次のペイロード構造を使用してください:
{sessionId, runId, hypothesisId, location, message, data, timestamp} -
**必須:**各デバッグログを折りたたみ可能なコード領域で囲んでください。
- 言語に適した領域構文を使用してください(例:JS/TS の場合は
// #region debug log、// #endregion)。 - これにより、計測コードが自動的に折りたたまれ、エディターをすっきり保てます。
- 言語に適した領域構文を使用してください(例:JS/TS の場合は
-
**禁止:**シークレット(トークン、パスワード、API キー、個人を特定できる情報)の記録
STEP 3: 実行前に以前のログファイルをクリアする(必須)
- ユーザーに実行を依頼する前に、ログパスにあるファイルを削除してください。
- 削除できない場合や失敗した場合は、ログファイルを手動で削除するようユーザーに指示してください。
- これにより、以前のログと新しいログが混在することなく、新しい実行のログを取得できます。
- シェルコマンド(rm、touch など)は使用しないでください。delete_file ツールのみを使用してください。
- ログファイルをクリアすることは、計測コードを削除することと同じではありません。ここでコードからデバッグログを削除しないでください。
- **重要:**削除してよいのは、自分のログファイル(ステップ0のログパスにあるファイル)のみです。同じディレクトリに、ファイル名に異なるセッション ID を含む別のデバッグセッションのログファイルがあっても、削除、変更、上書きしてはいけません。ほかのセッションのログファイルには手を加えないでください。
STEP 4: ユーザーがプログラムを実行した後にログを読む
- ユーザーがプログラムを実行し、インターフェース上で完了を確認した後は、「done」と入力するよう求めず、ログパスにあるファイルを読み取ってください。
- ログファイルには、計測コードから出力された NDJSON エントリ(1行につき1つの JSON オブジェクト)が含まれます。
- これらのログを分析し、仮説を評価して根本原因を特定してください。
- ログファイルが空か見つからない場合は、再現に失敗した可能性があることをユーザーに伝え、もう一度試すよう依頼してください。
STEP 5: 修正中もログを維持する
- 修正を実装するときは、まだデバッグログを削除しないでください。
- 検証実行中もログを有効にしておく必要があります。
- 初回のデバッグ実行と検証実行を区別するために、ログに
runId="post-fix"のタグを付けてもかまいません。 - **禁止:**修正後の検証ログが分析されるか、ユーザーが明示的に成功を確認するまでは、追加済みのログをファイルから削除または変更してはいけません。
- ログに基づく証拠が得られる修正後の検証実行が成功した後、またはユーザーから明示的に削除を依頼された場合にのみ、ログを削除してください。
重要な注意事項(必ず遵守)
- 修正中も計装を有効なままにしてください。検証に成功するか、ユーザーが明示的に確認するまでは、ログを削除または変更しないでください。
- 禁止事項:修正として
setTimeout、sleep、または人為的な遅延を使用しないでください。適切なリアクティビティ/イベント/ライフサイクルを使用してください。 - 禁止事項:修正後の検証ログを分析する前、またはユーザーから明示的な確認を受ける前に、計装を削除しないでください。
- 検証には、引用したログ行を用いた修正前後のログ比較が必要です。ログによる証拠なしに成功を主張しないでください。
- ログファイルを手動で作成しないでください。自動的に作成されます。
- ログファイルをクリアすることは、計装を削除することではありません。
- このセッションに属さないログファイルは、決して削除または変更しないでください。Step 0 に記載された正確なパスにあるログファイルのみを操作してください。
- 常に新たな仮説を立て、ログの証拠を用いて修正を行うよう努めてください。
- すべての仮説が棄却された場合は、必ず新たな仮説を立て、それに応じて計装を追加してください。
- 棄却された仮説によるコード変更を削除してください: 仮説が誤りだとログで判明した場合、その仮説のために行ったコード変更を元に戻してください。防御的なガード、推測に基づく修正、未検証の変更を蓄積させないでください。実行時の証拠に裏付けられた変更のみを残してください。
- 既存のアーキテクチャ、パターン、ユーティリティの再利用を優先し、過度な設計は避けてください。効果を最大化しながら、修正の範囲を絞り、対象を明確にして、できる限り小さくしてください。
サーバー API リファレンス
| メソッド | 効果 |
|---|---|
POST /ingest/:sessionId | JSON ボディを NDJSON 行としてログファイルに追記 |
GET /ingest/:sessionId | ログファイルの内容全体を読み取る |
DELETE /ingest/:sessionId | ログファイルをクリアする |