
Skill Bench: systematic-debugging kontra linia bazowa
Część 3 Skill Bench stawia węższe pytanie niż dwie pierwsze: nie „czy umiejętność pomaga”, ale „czy umiejętność stworzona do konkretnego zadania przewyższa model bez wsparcia wykonujący dokładnie to samo zadanie”. Debugowanie jest najczystszym testem, jaki mamy, ponieważ możemy sami zaimplementować błędy, dokładnie wiedzieć, co jest nie tak, i sprawdzić raport w porównaniu z rzeczywistym stanem linia po linii.
Napisaliśmy więc grę Snake na canvasie, celowo zepsuliśmy ją na trzy konkretne sposoby i uruchomiliśmy tę samą zepsutą grę oraz tę samą skargę w dwóch identycznych sesjach Claude Sonnet. Jedna miała zainstalowaną umiejętność systematic-debugging. Druga nie. Ten sam prompt, ten sam model, ten sam błąd. Różni się tylko umiejętność.
Wynik nie był tak jednoznacznym zwycięstwem, jakiego się spodziewaliśmy, i to jest część warta przeczytania.
Pułapka, którą zbudowaliśmy
Zaczęliśmy od działającej implementacji Snake'a, a następnie celowo wprowadziliśmy trzy błędy:
- Odwrócone wektory kierunku. ArrowUp i ArrowDown były podłączone do wektorów, których użyłbyś w normalnych współrzędnych kartezjańskich, a nie współrzędnych canvasa, gdzie y rośnie w dół. Naciśnij w górę, wąż idzie w dół.
- Generowanie jedzenia w przestrzeni pikseli zamiast przestrzeni siatki.
spawnFoodużywałocv.width(400 pikseli) jako granicy dla współrzędnej, która miała być indeksem siatki w siatce 20-komórkowej (GRID). Pomnożenie kroku siatki przez zakres 400 pikseli skutkuje współrzędnymi jedzenia, które lądują poza widoczną planszą w około 95% przypadków. - Zwiększanie wyniku co takt.
score++znajdowało się w głównej pętli gry zamiast w gałęzi „wąż zjadł jedzenie”, więc wynik wzrastał w każdej klatce, niezależnie od tego, co faktycznie robił wąż.
Nie powiedzieliśmy żadnej z sesji Claude'a, co było nie tak. Obu ramionom daliśmy ten sam raport o błędach w stylu gracza, sformułowany tak, jak sformułowałby go zirytowany tester: „sterowanie jest dziwne, jedzenie nigdy się nie pojawia, wynik rośnie sam”. Następnie poprosiliśmy każdą sesję o znalezienie i naprawienie wszystkiego, co to powodowało.
Trzy błędy, jedna szczera skarga, dwóch Claude'ów. Oto, co otrzymaliśmy.
Co zgłosiło każde ramię
Linia bazowa (bez umiejętności)
Sesja linii bazowej przeanalizowała kod bez narzuconej metody, czytając kolejno obsługę wejścia, generator jedzenia i pętlę gry. Znalazła wszystkie trzy zaimplementowane błędy:
- Wektory kierunku były odwrócone dla osi y w stosunku do tego, jak renderowanie canvasa traktuje „dół”.
spawnFoodmnożyłocv.widthtam, gdzie powinno było użyć stałej siatki, produkując współrzędne w skali pikseli w grze indeksowanej komórkami.- Zwiększanie wyniku znajdowało się poza sprawdzeniem kolizji z jedzeniem, więc uruchamiało się bezwarunkowo w każdej klatce.
Następnie kontynuowała czytanie i znalazła czwarty problem, którego nikt nie zaimplementował: sprawdzenie samokolizji porównywało głowę węża z komórką ogona, zanim ogon został usunięty dla tej klatki. Kiedy wąż wchodzi na pole, które opuszcza jego własny ogon, sprawdzenie nadal traktuje to pole jako zajęte i uznaje to za kolizję. To jest prawdziwy, dobrze znany przypadek brzegowy w grze Snake. Istniał w naszym kodzie, ponieważ napisaliśmy logikę kolizji, zanim cokolwiek zaimplementowaliśmy, a linia bazowa po prostu czytała wystarczająco daleko, aby na niego natrafić.
Ramię z umiejętnością (zainstalowany systematic-debugging)
Ramię z umiejętnością najpierw przeczytało SKILL.md systematic-debugging z obra/superpowers (umiejętność, którą osobno oceniliśmy na 9.6/10 za ustalanie przyczyn źródłowych oparte na hipotezach), a następnie zastosowało swoją metodę: sformułuj hipotezę dla każdego objawu, przetestuj ją w kodzie, potwierdź przed dotknięciem czegokolwiek.
Znalazło te same trzy zaimplementowane błędy, z bardziej zwięzłym i precyzyjnym językiem opisu przyczyn źródłowych:
- „Odwrócenie kierunku wynika z konwencji canvasa y-w-dół:
ArrowUpmapuje na{x:0,y:-1}zakładając kartezjańskie y-w-górę, ale canvas renderuje y rosnące w dół, więc góra i dół są zamienione.” - „Generowanie jedzenia używa granicy w przestrzeni pikseli (
cv.width= 400), gdzie obliczenia powinny używać granicy w przestrzeni siatki (GRID= 20). Potwierdzone przez niezgodność jednostek: pomnożenie losowej frakcji w skali siatki przez granicę w skali pikseli powoduje, że ~95% generowanych obiektów znajduje się pozacanvas.width.” - „Wynik zwiększa się bezwarunkowo w pętli taktowania zamiast być ograniczonym przez gałąź zjedzenia jedzenia. Potwierdzone przez śledzenie ciała pętli:
score++wykonuje się przed uruchomieniem sprawdzenia kolizji, w każdej klatce.”
Nie znalazło czwartego błędu. Problem samokolizji nigdy się nie ujawnił, ponieważ zgłoszone objawy (błędne sterowanie, brak jedzenia, niekontrolowany wzrost wyniku) nie wskazywały na logikę kolizji, a metoda umiejętności oparta na hipotezach pozostaje zakotwiczona w objawach, które otrzymała. Zamknęło raport, będąc pewnym, że wszystkie problemy zostały rozwiązane, i zgodnie z literą skargi, tak było.
Zwrot akcji z czwartym błędem
To jest zwrot akcji, który zweryfikowaliśmy ręcznie, ponownie czytając oba diffy w porównaniu z rzeczywistym kodem: ramię z umiejętnością było bardziej precyzyjne w kwestii błędów, które miało znaleźć, a ramię bazowe znalazło jeden dodatkowy, prawdziwy błąd, o który nikt nie pytał.
To nie jest krytyka systematic-debugging jako umiejętności. Debugowanie oparte na hipotezach jest stworzone, aby robić dokładnie to, co zrobiło tutaj: wziąć zgłoszony objaw, zawęzić go do możliwej do przetestowania przyczyny, potwierdzić przed naprawą i zatrzymać się, gdy objaw zostanie wyjaśniony. Ta dyscyplina jest dokładnie tym, czego potrzebujesz, gdy patrzysz na incydent produkcyjny ze śladem stosu i tykającym zegarem. Jest również, z założenia, ograniczona do objawów. Nie wędruje do kodu, który nie jest związany ze skargą.
Sesja linii bazowej nie miała takiego zakresu. Przeczytała więcej pliku, niż było to ściśle konieczne, a czytanie większej ilości pliku to sposób, w jaki natrafiasz na błąd, o którym nikt nie wspomniał. Swobodna eksploracja jest z założenia nieefektywna, a tutaj ta nieefektywność się opłaciła.
Uczciwa interpretacja: żadne z ramion nie jest „lepsze” w ogólnym ujęciu. Jedno ramię jest precyzyjne i oszczędne w uwadze, zakotwiczone w tym, co mu powiedziano. Drugie jest niefokusowane i, tym razem, wystarczająco dokładne, aby wychwycić coś, czego zgłoszenie nie wspominało. Jeśli Twój raport o błędach jest kompletny, to raport ramienia z umiejętnością jest tym, który chcesz przeczytać. Jeśli w Twoim raporcie o błędach może czegoś brakować, chcesz drugiej pary oczu, którą linia bazowa dała Ci za darmo.
Liczby
| Linia bazowa (bez umiejętności) | Ramię z umiejętnością (systematic-debugging) | |
|---|---|---|
| Znalezione błędy (z 3 zaimplementowanych) | 3 / 3 | 3 / 3 |
| Znaleziony niezaplanowany prawdziwy błąd | Tak (kolizja z opuszczaniem ogona) | Nie |
| Precyzja przyczyn źródłowych | Poprawne, mniej sformalizowane | Poprawne, nazwany mechanizm dla każdego błędu |
| Struktura raportu | Ad hoc | Hipoteza → test → potwierdzenie, dla każdego błędu |
| Użyte tokeny | 50,338 | 58,357 |
| Delta tokenów | — | +16% |
Umiejętność kosztowała 16% więcej tokenów za raport, który czyta się lepiej i precyzyjniej określa mechanizm, ale nie przewyższyła linii bazowej, której po prostu pozwolono kontynuować czytanie. To jest odkrycie, którego się nie spodziewaliśmy, i to jest powód, dla którego publikujemy surowe porównanie zamiast werdyktu, który schlebiałby umiejętności.
DARMOWY PAKIET STARTOWY
Chcesz trzy najwyżej oceniane umiejętności z naszego katalogu, zanim wybierzesz następną instalację? Wyślemy Ci je e-mailem wraz z listą kontrolną instalacji, którą uruchamiamy na każdej maszynie testowej. Za darmo.
Pobierz darmowy pakiet startowyKiedy potrzebujesz systematic-debugging
Test Snake'a nie docenia prawdziwej wartości umiejętności, ponieważ gra z zaimplementowanymi błędami i pełnym plikiem źródłowym w zasięgu wzroku jest bliska najlepszemu scenariuszowi dla modelu bez wsparcia: wszystko, co istotne, mieści się w jednym odczycie. Debugowanie produkcyjne rzadko tak wygląda.
Debugowanie przyczyn źródłowych oparte na hipotezach sprawdza się w przypadku błędu, który powraca. W naszych własnych notatkach katalogowych dotyczących systematic-debugging jednym z przypadków testowych był warunek wyścigu, który Claude już „naprawił” trzy razy w tej samej bazie kodu, za każdym razem łatając prawdopodobnie wyglądające przypuszczenie zamiast rzeczywistej przyczyny. Dyscyplina umiejętności (sformułuj hipotezę, zaprojektuj test, który by ją sfalsyfikował, nie dotykaj kodu, dopóki test jej nie potwierdzi) była tym, co ostatecznie ustaliło prawdziwą interakcję, zamiast generować czwarte przypuszczenie. Taki jest kształt błędu, do którego systematic-debugging jest przeznaczone: powtarzający się, trudny do uchwycenia, już trzykrotnie zgadywany, w bazie kodu zbyt dużej, by czytać ją od początku do końca na zawołanie.
Jest to również właściwe narzędzie w momencie, gdy zajmujesz się incydentem produkcyjnym. Masz objaw, tykający zegar i nie masz ochoty, aby model błądził, czytając niepowiązane moduły. Ogranicz się do raportu, potwierdź przyczynę, wdróż poprawkę. To jest cecha, a nie ograniczenie, dokładnie w takim środowisku.
Kiedy swobodne przeszukiwanie wygrywa
Nasz wynik ze Snake'a przemawia również za przeciwnym przypadkiem: kiedy podejrzewasz, że raport o błędach jest niekompletny, lub kiedy wykonujesz przegląd przed wydaniem, zamiast ścigać jeden zgłoszony objaw, nieograniczone czytanie kodu robi coś, czego metoda oparta na hipotezach strukturalnie nie zrobi. Patrzy na kod, na który nikt jeszcze nie narzekał.
To jest ten sam kształt co ręczny przegląd kodu versus ukierunkowana reakcja na incydent. Oba mają swoje miejsce. Błędem jest zakładanie, że umiejętność debugowania zastępuje przegląd, zamiast działać obok niego. Jeśli chcesz ogólnego spojrzenia na przegląd kodu, zobacz nasze stanowisko, dlaczego umiejętności nie zawsze uruchamiają się tak, jak oczekujesz oraz jak strukturyzujemy te testy.
Odtwórz to samodzielnie
Test jest na tyle mały, że można go odtworzyć w dwadzieścia minut, jeśli chcesz sprawdzić nasze liczby, zamiast wierzyć im na słowo. Napisz grę Snake na canvasie (ruch po siatce, generator jedzenia, licznik punktów, pętla gry) i zaimplementuj te trzy defekty:
- Podłącz
ArrowUp/ArrowDowndo wektorów w stylu kartezjańskim (y: 1dla góry,y: -1dla dołu) zamiast wektorów w stylu canvasa, gdzie zwiększające się y przesuwa się w dół ekranu. - W funkcji generującej jedzenie pomnóż swoją losową frakcję przez szerokość pikselową canvasa zamiast przez liczbę komórek siatki, tak aby wynikowa współrzędna była wartością pikselową traktowaną jako indeks siatki.
- Przenieś zwiększanie wyniku z gałęzi „czy głowa właśnie wylądowała na jedzeniu” do bezwarunkowego ciała pętli gry.
Daj sesji Claude'a tylko skargę gracza („sterowanie jest dziwne, jedzenie nigdy się nie pojawia, wynik rośnie sam”), nigdy listy błędów, i zobacz, co otrzymasz. Następnie przeczytaj własną logikę kolizji dla przypadku opuszczania ogona: sprawdź następną pozycję głowy w stosunku do bieżącej komórki ogona, zanim ogon się przesunie, i zobacz, czy tam też to jest. U nas było, bez naszego zaimplementowania.
PAKIET SKILLPROOF
systematic-debugging jest dostarczane w naszym Pakiecie Bezpieczeństwa wraz z umiejętnościami audytu i przeglądu, których używamy do pracy nad incydentami: ustalanie przyczyn źródłowych oparte na hipotezach dla błędu, który ciągle powraca, plus narzędzia do wychwytywania tego, co może przeoczyć przegląd ograniczony do objawów.
Pobierz Pakiet Bezpieczeństwa — 10 $FAQ
Czy umiejętność systematic-debugging sprawia, że Claude gorzej znajduje błędy?
Nie. Znalazła każdy zaimplementowany błąd z bardziej precyzyjnymi przyczynami źródłowymi niż linia bazowa. Czego nie zrobiła, to przekroczenie zakresu zgłoszonych objawów, co pozwoliło linii bazowej natknąć się na czwarty, niezaplanowany błąd. Dyscyplina zakresu jest zamierzonym celem projektowym umiejętności, a nie wadą.
Dlaczego linia bazowa znalazła błąd, który umiejętność przeoczyła?
Linia bazowa nie miała hipotezy, do której mogłaby się zakotwiczyć, więc przeczytała więcej bazy kodu, niż było to ściśle wymagane przez zgłoszone objawy. Czytanie większej ilości kodu to sposób, w jaki znajdujesz rzeczy, o które nikt nie pytał. To nieefektywna strategia, która raz się opłaciła, a nie ogólna przewaga.
Czy 16% wzrost liczby tokenów jest wart umiejętności debugowania?
Zależy od błędu. W przypadku powracającego, trudnego do zlokalizowania problemu, dyscyplina jest warta znacznie więcej niż 16% tokenów, ponieważ alternatywą jest Claude wielokrotnie zgadujący tę samą przyczynę, tak jak to miało miejsce w naszym własnym teście katalogowym, zanim zastosowaliśmy tę umiejętność. W przypadku błędu, który jest już dobrze określony i płytki, narzut zapewnia czystszy raport i niewiele więcej.
Czy powinienem używać systematic-debugging do każdej poprawki błędu?
Nie do każdej. Sięgnij po nią, gdy błąd powraca, gdy poprzednia próba naprawy nie powiodła się, lub gdy zajmujesz się incydentem na żywo i musisz pozostać w zakresie zgłoszonego objawu. Do pierwszego przeglądu świeżego raportu o błędach, lub gdy chcesz szerszego przeszukania, które może wychwycić sąsiednie problemy, zwykła sesja debugowania lub dedykowany przegląd kodu mogą pokryć obszar, którego umiejętność nie obejmie. Zobacz nasze najlepsze umiejętności kodowania, aby dowiedzieć się, jak oceniamy umiejętności debugowania i przeglądu kodu względem siebie.
Skill Bench, część 3 z 4. Przeczytaj inne kontrolowane porównania: część 1, budowa strony docelowej, część 2, bot Telegrama i część 4, audyt Google zx.
★ 9.6/10 × 3
Darmowy pakiet startowy
3 skille z naszymi najwyższymi ocenami z testów plus checklista instalacji — zestaw, który sami wgralibyśmy na świeżą maszynę. Za darmo, na e-mail.