コンテンツにスキップ

エージェントで失敗テストをデバッグ

このガイドでは、print 文では説明のつかない失敗に対して、エージェントにデバッガーを使わせる方法を説明します。

debug ツールは実際の Debug Adapter Protocol セッションを操作します。停止したフレームは、その瞬間に関するあらゆる問い——すべてのローカル変数、すべての呼び出し元、フレーム自身のスコープで評価した式——に一度に答えます。一方、print 文が答えるのは、実行前にあなたが尋ねようと思った問いだけです。

このツールは表面に出たままにするので、エージェントはなぜ何も使えないのかを推測せずに尋ねることができます。アダプターが実際に起動できるのは、次の両方が満たされたときだけです:

  • チェックアウトにプロジェクトのマーカーがあること
  • アダプターのバイナリが解決できること

エージェントに次の確認を依頼します:

debug(op: "adapters")

見つかったものを返すか、アダプターには両方の条件が必要だと説明します。

言語 アダプター マーカー インストール
Dart / Flutter dart debug_adapter pubspec.yaml SDK に同梱 — 作業は不要
Python python3 -m debugpy.adapter pyproject.toml, setup.py, requirements.txt pip install debugpy
Rust / C / C++ lldb-dap Cargo.toml, CMakeLists.txt LLVM に同梱
Go dlv dap go.mod go install github.com/go-delve/delve/cmd/dlv@latest

まずブレークポイントを設定し、それから起動する

「まずブレークポイントを設定し、それから起動する」というセクション

順序が重要で、ツールがそれを強制します。ブレークポイントはセッションが存在する前に設定できます。プロトコルが要求する順序がそれだからです。

エージェントに次のように依頼します:

bin/main.dart の compute 関数が誤った値を返します。product を代入している行にブレークポイントを設定し、デバッガーで起動して、a と b が実際に何なのかを教えてください。

エージェントはおおよそ次のように実行します:

debug(op: "breakpoints", file: "bin/main.dart", lines: [7])
debug(op: "launch", program: "bin/main.dart")

起動は停止した場所を報告します:

Launched bin/main.dart on dart (session dart-1). Stopped: breakpoint. Use `stack` to see where.
debug(op: "stack")
→ #1 compute (bin/main.dart:7:3)
#2 main (bin/main.dart:2:18)

次にその中へ進みます:

debug(op: "scopes", frame_id: 1)
→ Locals (reference 12)
debug(op: "variables", reference: 12)
→ a (int) = 6
b (int) = 7
product (int) = 42

子を持つオブジェクトは [expand: reference N] を報告します。ただし、その背後に本当に何かがある場合だけで、エージェントが使えない展開が提示されることはありません。

ローカル変数として見えないものについては:

debug(op: "evaluate", expression: "config.timeout.inSeconds", frame_id: 1)
やりたいこと 操作
次の停止位置まで実行 continue
同じフレームで次の行 step_over
呼び出しの中へ step_in
呼び出し元へ出る step_out
実行中のプログラムを停止 pause

これから起動するプロセスではなく、ハングしたプロセスに対して:

debug(op: "attach", port: 5858)
debug(op: "terminate")

セッションは必ず終了してください。デバッグアダプターは停止したプロセスを所有し、そのプロセスが保持しているもの——ポート、ロック、データベース接続——を握ったままになります。

深いオブジェクトグラフに対する variables の展開は、本質的に上限がありません。Flutter のウィジェット1つで要素ツリー全体に到達します。スコープごとの子は50、値は400文字、スタックフレームは30に制限されます。コンテキストウィンドウを埋め尽くすツール結果は、手助けしていた実行を終わらせるツールです。