Debuguj padający test z agentem
W tym poradniku pokazujemy, jak skłonić agenta do użycia debuggera przy awarii, której nie wyjaśniają instrukcje print.
Narzędzie debug prowadzi prawdziwą sesję Debug Adapter Protocol. Zatrzymana ramka odpowiada naraz na każde pytanie o ten moment — o każdą zmienną lokalną, każdego wywołującego i o wyrażenie obliczone w zasięgu samej ramki — podczas gdy instrukcja print odpowiada tylko na pytanie, które przyszło Ci do głowy przed uruchomieniem.
Zanim zaczniesz
Dział zatytułowany „Zanim zaczniesz”Narzędzie pozostaje na powierzchni, żeby agent mógł zapytać, dlaczego nic nie da się użyć, zamiast zgadywać. Adapter może faktycznie wystartować tylko wtedy, gdy zachodzą oba poniższe warunki:
- znacznik projektu w checkoutcie oraz
- rozwiązanie ścieżki pliku binarnego adaptera.
Poproś agenta o sprawdzenie:
debug(op: "adapters")Odpowiada tym, co znalazł, albo wyjaśnia, że adapter potrzebuje obu połówek.
| Język | Adapter | Znacznik | Instalacja |
|---|---|---|---|
| Dart / Flutter | dart debug_adapter |
pubspec.yaml |
Dostarczany z SDK — nic nie trzeba robić |
| Python | python3 -m debugpy.adapter |
pyproject.toml, setup.py, requirements.txt |
pip install debugpy |
| Rust / C / C++ | lldb-dap |
Cargo.toml, CMakeLists.txt |
Dostarczany z LLVM |
| Go | dlv dap |
go.mod |
go install github.com/go-delve/delve/cmd/dlv@latest |
Najpierw ustaw punkt przerwania, potem uruchom
Dział zatytułowany „Najpierw ustaw punkt przerwania, potem uruchom”Kolejność ma znaczenie i narzędzie jej pilnuje: punkty przerwania można ustawiać przed istnieniem sesji, bo takiej sekwencji wymaga protokół.
Poproś agenta o coś w tym stylu:
Funkcja
computewbin/main.dartzwraca nieprawidłową wartość. Ustaw punkt przerwania w wierszu, który przypisujeproduct, uruchom to pod debuggerem i powiedz mi, jakie faktycznie sąaib.
Wykona w przybliżeniu:
debug(op: "breakpoints", file: "bin/main.dart", lines: [7])debug(op: "launch", program: "bin/main.dart")Uruchomienie zgłasza, gdzie się zatrzymało:
Launched bin/main.dart on dart (session dart-1). Stopped: breakpoint. Use `stack` to see where.Odczytaj ramkę
Dział zatytułowany „Odczytaj ramkę”debug(op: "stack")→ #1 compute (bin/main.dart:7:3) #2 main (bin/main.dart:2:18)Następnie wejdź w głąb:
debug(op: "scopes", frame_id: 1)→ Locals (reference 12)
debug(op: "variables", reference: 12)→ a (int) = 6 b (int) = 7 product (int) = 42Obiekt z dziećmi zgłasza [expand: reference N] — ale tylko wtedy, gdy naprawdę coś za nim stoi, więc rozwinięcie, którego agent nie może użyć, nigdy nie jest proponowane.
Dla wszystkiego, co nie jest widoczne jako zmienna lokalna:
debug(op: "evaluate", expression: "config.timeout.inSeconds", frame_id: 1)Przechodzenie krok po kroku
Dział zatytułowany „Przechodzenie krok po kroku”| Co chcesz zrobić | Operacja |
|---|---|
| Bieg do następnego zatrzymania | continue |
| Następny wiersz, ta sama ramka | step_over |
| Wejście do wywołania | step_in |
| Wyjście do wywołującego | step_out |
| Zatrzymanie działającego programu | pause |
Podłącz się do czegoś, co już działa
Dział zatytułowany „Podłącz się do czegoś, co już działa”Dla zawieszonego procesu, a nie takiego, który dopiero uruchamiasz:
debug(op: "attach", port: 5858)Zakończ
Dział zatytułowany „Zakończ”debug(op: "terminate")Zawsze kończ sesję. Adapter debuggera posiada zatrzymany proces, który trzyma wszystko, co trzyma ten proces — port, blokadę, połączenie z bazą danych.
Ograniczone dane wyjściowe
Dział zatytułowany „Ograniczone dane wyjściowe”Rozwinięcie variables na głębokim grafie obiektów jest z natury nieograniczone — jeden widget Fluttera sięga całego drzewa elementów. Liczba dzieci na zasięg jest ograniczona do 50, wartości do 400 znaków, a ramek stosu do 30. Wynik narzędzia, który zapełnia okno kontekstu, to narzędzie, które kończy uruchomienie, któremu pomagało.
Zobacz też
Dział zatytułowany „Zobacz też”- Inteligencja kodu — dlaczego debugger, kompilator i dopasowywacz strukturalny odpowiadają na różne pytania
- Wbudowane narzędzia agentów — każda operacja
debugi jej argument - Diagnozuj agenta — gdy problem tkwi w agencie, a nie w kodzie