Przejdź do głównej zawartości

Debugowanie z AI w Cursorze

Polowanie na błędy z AI w Cursorze to pętla w trzech fazach: agent bada awarię bez edytowania kodu, odtwarza ją nieprzechodzącym testem albo skryptem obciążeniowym i dopiero potem nanosi w trybie Agent jedną celowaną poprawkę. Reprodukcja służy zarazem jako dowód, więc poprawkę przyjmuje się po przejściu testu z czerwonego na zielony, a nie po przekonująco wyglądającym diffie.

Ten poradnik jest dla programistów, którzy debugują z agentem Cursora, i dla tech leadów, którzy ustalają, jakie dowody musi nieść pull request z poprawką błędu. Sytuacja, którą rozwiązuje: od wtorkowego wdrożenia produkcja zwraca 500 mniej więcej na co siódme żądanie do kasy, diff to drobny refaktor kodu płatności, a jedyny tekst błędu to Transaction failed. Wklejasz błąd do trybu Agent i prosisz o poprawkę. Agent zmienia trzy pliki, inna grupa użytkowników dostaje teraz 403, a po dwudziestu minutach pierwotne 500 wraca.

Agent nie zawiódł jako programista. Kazano mu edytować, zanim ktokolwiek znał przyczynę. Debugowanie to problem przeszukiwania, a agent przeszukuje dobrze, kiedy nie pozwalasz mu edytować w trakcie szukania.

Co zyskujesz dzięki temu procesowi polowania na błędy

Dział zatytułowany „Co zyskujesz dzięki temu procesowi polowania na błędy”
  • Plan „jeden tryb na fazę”, który trzyma agenta w trybie tylko do odczytu, dopóki przyczyna nie jest udowodniona
  • Osiem promptów do skopiowania: triaż objawów, reprodukcja, instrumentacja, porównanie logów, ograniczona poprawka, test regresyjny, który najpierw nie może przechodzić, kaskada błędów builda i diagnoza wyścigu
  • Przepis na git bisect run dla regresji, które zaczęły się od konkretnego wdrożenia
  • Listę dowodów, na podstawie której recenzent zatwierdzi poprawkę bez czytania każdej linii
  • Sposoby wyjścia z sześciu typowych sytuacji, w których debugowanie z AI idzie źle

Który tryb Cursora pasuje do której fazy debugowania?

Dział zatytułowany „Który tryb Cursora pasuje do której fazy debugowania?”

Każda faza ogranicza to, co agent może zmienić. To ograniczenie, a nie model, zatrzymuje pętlę „napraw, zepsuj, napraw”.

FazaCelTryb w CursorzeAgent może zmienićWychodzisz z fazy, gdy
1. ZbadajUszeregowane, sprawdzalne hipotezyPlan Mode (albo tryb Ask, jeśli jest w twoim selektorze)NicKażda hipoteza wskazuje obserwację, która by ją obaliła
2. Odtwórz i zbierz dowodyAwaria wywoływana na żądanieTryb Agent ograniczony do testów, skryptów i logowania (albo tryb Debug, jeśli jest w twoim selektorze)Nowe pliki testów, skrypty obciążeniowe, oznaczone linie logówTest albo skrypt kończy się błędem z przewidzianego powodu
3. Napraw i udowodnijUsunięta jedna przyczynaTryb AgentTylko pliki wskazane w diagnozieReprodukcja przechodzi, zestaw testów jest zielony, a logowanie diagnostyczne zniknęło

Plan Mode „tworzy szczegółowe plany implementacji, zanim napisze jakikolwiek kod”, więc to bezpieczne miejsce na myślenie. Zanim zaczniesz, zacommituj albo odłóż (git stash) swoją pracę, żeby git diff pokazywał tylko to, co agent zmieni w trakcie polowania. Punkt powrotu w obrębie jednej sesji opisuje poradnik o checkpointach i gałęziach.

Najpierw spisz wszystkie obserwowalne fakty: treść błędu, częstość, środowiska, w których występuje i w których nie, moment startu i to, co się zmieniło. Potem proś o hipotezy, które da się sprawdzić, a nie o poprawkę.

Spodziewaj się odpowiedzi w rodzaju: wyczerpanie puli połączeń, wyścig na współdzielonym stanie, niezgodne timeouty albo ścieżka błędu, która pomija sprzątanie. Najważniejszy jest punkt 3. Hipoteza, której żadna obserwacja nie może obalić, zjada popołudnie i nic nie daje.

Wciągnij dowody z produkcji do sesji przez serwer MCP

Dział zatytułowany „Wciągnij dowody z produkcji do sesji przez serwer MCP”

Gdy awaria występuje tylko na produkcji, daj agentowi prawdziwe zdarzenia zamiast swojego streszczenia. Oficjalny serwer Sentry MCP (getsentry/sentry-mcp, pakiet stdio @sentry/mcp-server 0.42.0, sprawdzony przez npm view 26 września 2026) udostępnia issues, zdarzenia i trace’y. Jego zdalny endpoint to https://mcp.sentry.dev/mcp, a Cursor deklaruje zdalny serwer przez URL w pliku projektu .cursor/mcp.json:

{ "mcpServers": { "sentry": { "url": "https://mcp.sentry.dev/mcp" } } }

Zdalny serwer loguje cię przez OAuth, więc żaden token nie trafia do pliku. Pierwsze połączenie otwiera logowanie w przeglądarce, więc dodaj serwer i zaloguj się przed incydentem, a nie w jego trakcie. Każdy załadowany serwer dokłada też definicje swoich narzędzi do kontekstu agenta: jak utrzymać ten koszt w ryzach, pokazuje strona ograniczanie kosztu tokenów MCP. Potem zapytaj w tym samym trybie tylko do odczytu: „Find the most frequent unresolved error on the checkout endpoint in the last 24 hours, open its trace, and map each frame to a file in this repository. Do not edit anything.” Zysk jest taki, że agent czyta stack trace połknięty przez twój handler, zamiast zgadywać z opakowanego komunikatu. Inne serwery obserwowalności porównuje strona serwery MCP do obserwowalności.

Faza 2: odtwórz awarię i zbierz dowody z czasu wykonania

Dział zatytułowany „Faza 2: odtwórz awarię i zbierz dowody z czasu wykonania”

Reprodukcja jest warta więcej niż diagnoza, bo później jest też testem, który udowadnia poprawkę. Przy sporadycznej awarii pod obciążeniem niech tryb Agent napisze skrypt i nic poza nim.

Uruchom go poleceniem k6 run tests/load/checkout-stress.js. Jeśli odsetek błędów rośnie razem z liczbą wirtualnych użytkowników, masz reprodukcję. Jeśli zostaje na zerze, różnica między twoim laptopem a produkcją (wolumen danych, rozmiar puli, opóźnienia sieci) jest kolejną hipotezą do sprawdzenia.

Przy błędzie deterministycznym reprodukcją jest test jednostkowy albo integracyjny, który dziś nie przechodzi. Jak napisać go najpierw, opisuje TDD w Cursorze.

Jeśli selektor trybów oferuje tryb Debug, możesz go użyć w tym kroku. Ręczna wersja poniżej daje te same dowody w każdym trybie, a instrumentację łatwo potem usunąć.

Potem uruchom reprodukcję dwa razy i zachowaj jeden nieudany i jeden udany przebieg. Dopiero ich porównanie umożliwia diagnozę.

Punkt 4 to twoje kryterium akceptacji dla fazy 3. Typowe znalezisko w tym scenariuszu: processPayment pobiera połączenie z puli, a gałąź nieudanej walidacji wraca, zanim je zwolni. Pod obciążeniem pula się opróżnia, kolejne żądania dostają timeout w oczekiwaniu na połączenie, a blok catch opakowuje ten timeout jako Transaction failed. To opakowanie sprawia, że treść błędu nigdy nie wskazywała przyczyny.

Gdy błąd zaczął się od konkretnego wdrożenia, a masz reprodukcję, która przy awarii kończy się niezerowym kodem wyjścia, niech historię przeszuka git. Próg k6 z promptu o teście obciążeniowym już daje taki kod wyjścia. Test obciążeniowy potrzebuje świeżego serwera aplikacji na każdym commicie, więc zamknij kroki w małym skrypcie, na przykład tests/load/bisect.sh:

#!/bin/sh
npm ci >/dev/null || exit 125 # zależności z lockfile'a tego commita, nie poprzedniego
npm run build >/dev/null || exit 125 # commit, który się nie buduje, zostaje pominięty, a nie obwiniony
node dist/server.js & pid=$! # uruchom sam serwer, nie wrapper npm
trap 'kill $pid 2>/dev/null' EXIT # zatrzymaj go, jakkolwiek skończy się skrypt
sleep 5 # czas na start serwera na localhost:3000
k6 run --quiet tests/load/checkout-stress.js

Potem oddaj sterowanie gitowi:

Okno terminala
git bisect start HEAD abc1234 # najpierw zły commit, potem ostatni znany dobry
git bisect run sh tests/load/bisect.sh
git bisect reset # powrót do punktu wyjścia

Zamień abc1234 na commit wdrożony w poniedziałek. Git w każdym kroku dzieli zakres na pół, więc 12 commitów wymaga najwyżej czterech przebiegów. Kod wyjścia 125 mówi bisectowi, żeby pominął commit, którego nie da się przetestować, więc zepsuty build nigdy nie zostanie obwiniony o regresję. Zamień dist/server.js na punkt wejścia swojego builda: zabicie wrappera npm start potrafi zostawić prawdziwy serwer na porcie 3000, a wtedy kolejny krok testuje niewłaściwy commit. Port 3000 musi być wolny przed uruchomieniem git bisect run i przed każdym krokiem. Trzymaj bisect.sh poza testowanymi commitami (nieśledzony plik przetrwa każdy checkout) i wydłuż sleep, jeśli serwer startuje wolno.

Dopiero teraz przełącz się na tryb Agent i wklej diagnozę, żeby agent pracował na dowodach, a nie na nowej własnej teorii.

Reguła „bez ponowień” jest tam dlatego, że wrapper z ponowieniami to częsta, wiarygodnie wyglądająca, ale błędna poprawka: przez godzinę obniża odsetek błędów, a pod stałym obciążeniem opróżnia pulę jeszcze szybciej.

Napisz test regresyjny, który najpierw nie przechodzi

Dział zatytułowany „Napisz test regresyjny, który najpierw nie przechodzi”

Test regresyjny dowodzi poprawki tylko wtedy, gdy nie przechodzi na nienaprawionym kodzie. Poproś o ten dowód wprost.

Jeśli test przechodzi na nienaprawionym kodzie, nie testuje tego błędu. Usuń go i opisz warunek awarii dokładniej. Jak nie dopuścić, żeby ktoś później dopasował test do kodu, wyjaśnia strona chroń wyrocznię.

Skąd wiesz, że poprawka jest dobra, bez czytania każdej linii?

Dział zatytułowany „Skąd wiesz, że poprawka jest dobra, bez czytania każdej linii?”

Poprawkę przyjmujesz na podstawie dowodów, a nie tego, jak czyta się diff. Dołącz do pull requesta:

DowódJak go uzyskaćCo udowadnia
Test regresyjny najpierw czerwony, potem zielonyPrzebieg ze stash opisany wyżej, wynik wklejony do PRTest wykrywa ten błąd, a poprawka go usuwa
Reprodukcja przed i pok6 run tests/load/checkout-stress.js na starym i nowym commicieOdsetek awarii spada tak, jak przewidziała faza 2
Wszystkie bramki zieloneTesty, sprawdzenie typów i lint w CINic innego się nie zepsuło
Zakres zgodny z diagnozągit diff --stat pokazuje tylko wskazany plik i nowe testyAgent nie refaktoryzował przy okazji
Instrumentacja usuniętagit grep -c CHECKOUT_DEBUG nic nie zwracaŻadne logowanie diagnostyczne nie trafia na produkcję
Niezależny przeglądBugbot albo drugi agent przegląda PR pod kątem diagnozyRecenzent, który nie pisał poprawki, szukał skutków ubocznych

Zatwierdzenie: za dowody odpowiada programista, który prowadził polowanie. Recenzent, przy poprawce incydentu zwykle tech lead, zatwierdza, gdy każdy wiersz jest obecny, a diff czyta tylko tam, gdzie wiersza brakuje albo coś zaskakuje. Po wdrożeniu obserwuj ten sam błąd w monitoringu przez jeden szczyt ruchu, zanim zamkniesz incydent. Taki alert opisuje poradnik o monitoringu. Szerszą praktykę przedstawia strona dowody zamiast czytania kodu.

Jak debugować kaskady błędów builda i wyścigi w Cursorze?

Dział zatytułowany „Jak debugować kaskady błędów builda i wyścigi w Cursorze?”

Dwa powtarzalne rodzaje błędów potrzebują własnego przepisu: ściana błędów kompilatora z kilkoma ukrytymi przyczynami i utracona aktualizacja, która pojawia się tylko przy współbieżności.

Czterdzieści błędów po podbiciu zależności ma zwykle dwie albo trzy przyczyny. Poprawianie ich po kolei według plików to najwolniejsza droga.

Logowanie potrafi zmienić zależności czasowe na tyle, że wyścig znika. Jeśli błąd przestaje występować po dodaniu instrumentacji, zapisuj znaczniki czasu z process.hrtime.bigint() do tablicy w pamięci i wypisz je po przebiegu, żeby gorąca ścieżka nie robiła żadnego I/O.

W tej samej sesji, w Plan Mode albo trybie Ask, poproś agenta o post-mortem z podsumowaniem, osią czasu, przyczyną, poprawką, luką w wykrywaniu, prewencją i zadaniami do wykonania, zapisany w docs/postmortems/. Luka w wykrywaniu („dlaczego monitoring pokazywał Transaction failed zamiast timeoutu?”) zwykle daje najcenniejsze zadanie. Przed publikacją sprawdź oś czasu z dziennikiem incydentu: agent wie tylko to, co widziała sesja.

Które powtarzalne błędy zasługują na zapisany prompt?

Dział zatytułowany „Które powtarzalne błędy zasługują na zapisany prompt?”

Prompty, do których wracasz, zapisz jako Rule albo Agent Skill, żeby dostał je cały zespół. Format pokazuje poradnik o Rules. Jeśli wolisz gotową metodę, skill systematic-debugging z obra/superpowers jest przeznaczony do użycia „when encountering any bug, test failure, or unexpected behavior, before proposing fixes” i prowadzi agenta przez badanie przyczyny, analizę wzorców i testowanie hipotez, zanim przejdzie do implementacji. Zainstaluj go dla Cursora przez CLI skills (1.7.0, sprawdzone 26 września 2026):

Okno terminala
npx skills add obra/superpowers --skill systematic-debugging -a cursor

Przeczytaj SKILL.md przed instalacją: otwarte zgłoszenie #2277 (10 września 2026) opisuje, że katalog skilla zawiera pliki scenariuszy testów presji (pressure tests), które kopiują się do katalogu uruchomieniowego. Więcej opcji porównuje strona skille do testowania i debugowania.

Pętla „napraw, zepsuj, napraw”. Agent edytuje, psuje się coś innego, agent edytuje znowu. Wyjście: git stash albo przywrócenie ostatniego czystego commita, powrót do Plan Mode i niewychodzenie z fazy 1, dopóki każda hipoteza nie ma obserwacji, która może ją obalić.

Pewna siebie, ale błędna przyczyna. Wyjaśnienie brzmi dobrze, a poprawka niczego nie zmienia. Wyjście: przewidywanie z fazy 2 to ujawnia. Jeśli test obciążeniowy nie zmienia się tak, jak przewidziała diagnoza, diagnoza jest błędna, choćby brzmiała przekonująco. Wróć do porównania przebiegów z nowymi danymi.

Poprawka ukrywa objaw. Ponowienia, większa pula albo dłuższy timeout sprawiają, że błąd występuje rzadziej, ale jego przyczyna zostaje. Wyjście: odrzuć diff i powtórz regułę „napraw przyczynę wskazaną w diagnozie; bez ponowień, bez zmian puli i timeoutów”.

Agent zmienia test zamiast kodu. Test regresyjny nagle przechodzi, bo zmieniła się jego asercja. Wyjście: napisz „The test is correct. The implementation is wrong. Do not modify tests/payment/connection-leak.test.ts.” i zanim cokolwiek przyjmiesz, sprawdź w git diff --stat, czy nie zmieniły się pliki testów.

Instrumentacja nie łapie awarii. Logi nie pokazują różnicy między przebiegiem nieudanym a udanym. Wyjście: błąd siedzi gdzie indziej w łańcuchu wywołań. Rozszerz logowanie o jedną warstwę na zewnątrz (middleware, sterownik bazy, klient HTTP) i zbierz kilka nieudanych próbek, bo pojedyncza próbka sporadycznej awarii potrafi zmylić.

Nic nie odtwarza się lokalnie. Niektóre awarie wymagają produkcyjnych wolumenów danych, prawdziwych opóźnień albo konkretnej infrastruktury. Wyjście: dodaj ustrukturyzowane, oznaczone logowanie za flagą, wdróż je, przeanalizuj wyjście z produkcji w Plan Mode albo trybie Ask i poproś agenta o sprawdzenie changeloga i issue trackera biblioteki, która zawodzi, pod kątem znanych wycieków i timeoutów w twojej wersji.