7月31日、Abdul Dattijが「How to Debug AI Coding Agents When They Change the Wrong Thing」と題した記事を公開した。この記事では、AIコーディングエージェントが誤った箇所を変更した際に、何を調査し・何を変更し・何を実行したかを証拠として記録・検証するデバッグ手法について詳しく紹介されている。以下に、その内容を紹介する。
「fixed」の一言が隠しているもの
ClaudeやCursor、OpenAI Codexといったコーディングエージェントに修正を依頼すると、エージェントはいくつかの処理を実行したのち「fixed」と短く返答する。しかしその返答には、「何を調べたか」「どこを変えたか」「何を実行したか」「何をもって修正完了とみなしたか」が一切含まれていない。
ビルドが通っても、ボタンは壊れたままかもしれない。テストが通っても、アサーションが弱くなっただけかもしれない。ルートを変更したように見えても、レスポンスを返すハンドラは手付かずかもしれない。
この問題はUIに限らない。記事では以下のようなケースが挙げられている:
- 「チェックアウトのバグを直して」→ バグはStripeフローにあるのに、エージェントがPayPalフローを修正してしまう
- 「このテストを通して」→ 壊れたコードを直す代わりに、テストのアサーションを弱める
- 「APIレスポンスを更新して」→ TypeScriptの型定義は更新するが、実際のハンドラは変えない
- 「関数をきれいにして」→ リファクタのつもりで、関数の挙動を変えてしまう
いずれも問いは同じだ。モデルは何をするよう指示されたか、実際に何が変わったか、ユーザーの報告した問題が解決されたと何が証明するか。
「証拠」を残すエージェントの設計
記事ではUIバグの修正を題材に、エージェントが実行した各ステップを記録する手法を解説している。UIは失敗がブラウザで目視確認しやすいため、例として適している。
題材となるバグは、モバイル画面(390×844)でプライシングカードのボタンが右にはみ出す問題だ。
.primary-action {
width: 360px;
padding: 0 28px;
color: #ffffff;
background: #111827;
white-space: nowrap;
}
カードの幅が354pxなのに対し、ボタンは360pxの固定幅を持つため、29px分だけカードの右端からはみ出す。

エージェントが答えるべき5つの問い
記事では、有用なコーディングエージェントの実行結果が答えるべき問いを5つ定義している:
- エージェントはどのファイルを調査したか?
- 対象のセレクタやコンポーネントをどれと特定したか?
- 具体的にどのパッチを適用したか?
- アプリはビルドできたか?
- 報告された問題が変化したことを、適切なチェックが証明したか?
diffだけでは不十分だ。差分が正しそうに見えても、ページはまだ壊れているかもしれない。 エージェントの最終回答は「成功した」という主張ではなく、証拠のまとめであるべきだ、と記事は強調する。
ツール構成と記録の仕組み
記事のチュートリアルでは、Pythonスクリプトがモデルのツールループをラップし、すべてのツール呼び出しとその結果をログに記録する。モデルに与えるツールは以下のように整理されている:
| ツール | 役割 |
|---|---|
list_files |
関連ファイルを一覧表示(盲目的な編集を防ぐ) |
read_file |
ファイルを1つずつ読む(参照コンテキストを可視化) |
apply_patch |
限定的なCSSパッチを適用(変更を追跡可能に) |
run_build |
npm run buildを実行(ビルド破損を検出) |
inspect_dom |
ChromiumでDOMを測定(レンダリング結果を検証) |
capture_screenshot |
ブラウザのスクリーンショットを保存(視覚的証拠) |
このラッパーが重要なアイデアだ、と記事は述べている。モデルが何をしたかを知りたければ、ツールのリクエストと実際の関数実行結果を記録すればよい。
なお、これらのツール関数はModel Context Protocol (MCP)に従ってパッケージ化することも可能だ。
「間違ったセレクタ」を捕まえる
このチュートリアルの核心部分がここだ。実際のAPIによる実行では、モデルは最初に.primary-action(はみ出しているボタン)ではなく.support-link(近くにある別の要素)を変更しようとした。ラッパーはそのリクエストをPythonがパッチを適用する前に記録した。
ブラウザチェックの結果:
{
"label": "wrong_selector_attempt",
"buttonInsideCard": false,
"overflowRightPx": 29,
"computed": {
"width": "360px",
"whiteSpace": "nowrap"
}
}
overflowRightPxはまだ29のまま。間違った編集は、構文上は正当なコードであっても、ブラウザチェックで捕捉できる。 ターゲットのブラウザチェックが通るまで修正を受け入れてはならない、というのが記事の結論だ。
ブラウザチェックにはPlaywrightを使っており、コアとなる確認ロジックは以下の通り:
const card = document.querySelector('[data-component="pricing-card"]');
const button = document.querySelector('[data-component="pricing-card"] .primary-action');
const cardBox = card.getBoundingClientRect();
const buttonBox = button.getBoundingClientRect();
const buttonInsideCard =
buttonBox.left >= cardBox.left &&
buttonBox.top >= cardBox.top &&
buttonBox.right <= cardBox.right &&
buttonBox.bottom <= cardBox.bottom;
このチェックは「デザインが美しいか」を証明するものではない。プロンプトに書かれた具体的な失敗——ターゲットのボタンが指定のモバイルビューポートでカードからはみ出ていないこと——だけを証明する。
既存の観測ツールとの違い
Weights & Biases Weave、LangSmith、Arize Phoenix、LangfuseといったLLM観測ツールはすでに存在し、モデル呼び出し・コスト・レイテンシ・エラーを記録できる。コーディングエージェントに特化した観測としては、DynatraceやArizeも取り組みを進めている。
ただし記事が扱う問題はより狭い。ホスト型のダッシュボードやコスト追跡よりも前の段階として、1回のモデル駆動のコーディングタスクについて、ツールリクエスト・ファイル変更・コマンド結果・スクリーンショット・失敗内容を開発者が確認できる形で記録することを目標としている。同じ実行ログを後からWeaveやLangSmithに送ることは可能だが、まず記録すべき内容を正しく残すのが先決だ、と記事は述べる。
チュートリアルのコードはGitHubのabduldattijo/coding-agent-run-recorderで公開されており、Python 3.10以上・Node.js・Playwright(Chromium)・OpenAI APIキーがあれば実行できる。APIキーなしでも--mode replayオプションで同じ証拠ファイルを再生成できる。
詳細はHow to Debug AI Coding Agents When They Change the Wrong Thingを参照していただきたい。