Fable 5, Opus 4.8 i Sonnet 4.6: jak uczciwie porównać LLM na własnym kodzie
Kontrolowany eksperyment: Fable 5, Opus 4.8 i Sonnet 4.6 na jednym prompcie audytują rzeczywistą bazę kodu. Metodyka uczciwego porównania LLM na własnym projekcie.
Nie udało się wczytać tego obrazu.Gdy wychodzi nowy model, zapowiedź odpowiada na pytanie „na ile jest lepszy na benchmarkach” — i nie odpowiada na jedyne pytanie, które mnie interesuje: co zmieni w mojej pracy. Przeprowadziłem kontrolowany eksperyment: trzy modele Claude — Fable 5, Opus 4.8 i Sonnet 4.6 — otrzymały dosłownie identyczne zadanie audytu bazy kodu tego bloga, każdy w izolowanej kopii repozytorium, z wcześniej uzgodnioną rubryką oceny. W artykule — sama metodyka, którą można powtórzyć na dowolnym projekcie, wyniki, a osobno — jak eksperyment dwa razy się zepsuł i czego to nauczyło.
Dlaczego benchmarki nie odpowiadają na moje pytanie
Publiczne benchmarki mają dwa problemy i oba są fundamentalne. Pierwszy — zanieczyszczenie danych: przykłady testowe przeciekają do zbiorów treningowych, a model częściowo „przypomina sobie” odpowiedzi zamiast rozwiązywać zadanie. To nie marginalne podejrzenie, lecz przedmiot całego kierunku badań: przegląd Xu i współautorów (2024) systematyzuje badania nad zanieczyszczeniem benchmarków, a przegląd EMNLP 2025 odnotowuje odpowiedź branży — przejście od testów statycznych do dynamicznie generowanych.
Drugi problem jest prostszy: benchmark mierzy nie moje zadanie. Nie potrzebuję modelu, który najlepiej rozwiązuje zadania olimpijskie. Potrzebuję modelu, który znajdzie rzeczywiste błędy w moim blogu na Laravelu, nie wymyśli nieistniejących i udowodni, że jego poprawka działa.
Z tego wynika prosta myśl: najlepszym stanowiskiem testowym do porównania modeli jest własny projekt. Jego kodu w takim zestawieniu nie ma w zbiorach treningowych, zadania na nim — to dokładnie te, za które płacę, a wyniki mogę sprawdzić ręcznie, bo znam ten kod.
Projekt eksperymentu: jeden prompt, trzy izolowane światy
Zadanie dla wszystkich trzech modeli było dosłownie identyczne — różniły się tylko nazwa gałęzi i folder wyników. Cztery fazy: audyt dwujęzycznego systemu artykułów bloga z dowodem każdego znaleziska w postaci файл:строка z cytatem kodu; wybór rozwiązań dla trzech głównych znalezisk z opisem kompromisów; implementacja jednej poprawki z autoweryfikacją; notatka o wynikach po rosyjsku i angielsku. Pełny cykl pracy inżynierskiej, a nie izolowane „pytanie-odpowiedź” — takie podejście zaleca również Anthropic: oceniać agentów na zadaniach z rzeczywistego produktu, według rubryki uzgodnionej przed uruchomieniem.
Trzy zasady uczyniły porównanie uczciwym:
Izolacja. Każdy model pracował w osobnym git worktree — własnej kopii katalogu roboczego z własną gałęzią. Modele fizycznie nie mogły zobaczyć wyników innych ani sobie przeszkodzić.
Ochrona przed halucynacjami — w samym prompcie. Kluczowa linia zadania: „wymyślone znalezisko (nieistniejący kod, błędna linia) jest gorsze niż brak znaleziska”. Bez tego bodźca model, którego prosi się o znalezienie problemów, ma skłonność, by je „znajdować” w każdym przypadku. Z nim — każde znalezisko musi przejść ręczną weryfikację.
Wyłączenie podpowiedzi z zaliczenia. W repozytorium leży CLAUDE.md, gdzie opisane są znane pułapki projektu — na przykład względne ścieżki do zasobów, które psują się na URL z prefiksem językowym. Wszystkie trzy modele czytają ten plik, więc takie znaleziska są „darmowe”: liczą się za staranność, ale nie za głębię.
Rubryka: oceniać tylko to, co można sprawdzić ręcznie
Przed uruchomieniem ustaliłem sześć osi po pięć punktów: dokładność audytu (ręczna weryfikacja próbki znalezisk według файл:строка), głębia (potwierdzone znaleziska, których nie ma w podpowiedziach), jakość rozumowania o kompromisach, kod i realność autoweryfikacji, jakość tekstu rosyjskiego i angielskiego, dyscyplina (zero pytań do człowieka, ani jedno naruszenie ograniczeń). Zasada ta sama co w dobrym code review: im mniej oś opiera się na guście, a więcej na weryfikowalnym fakcie, tym bardziej można jej ufać.
Jak wszystko zepsuło się za pierwszym razem
Pierwsze uruchomienie zrobiłem nieprawidłowo — i to okazało się najbardziej przenośną częścią eksperymentu. Otworzyłem trzy interaktywne sesje równolegle w tym samym folderze repozytorium. Po kilku minutach w drzewie roboczym leżały niezacommitowane zmiany, których nie dało się przypisać: wspólny checkout oznacza, że gdy jedna sesja robi git checkout -b, gałąź przełącza się u wszystkich trzech, a ich zmiany i commity się mieszają. Jedna z sesji dodatkowo zrobiła git stash i zgarnęła do niego wszystko po kolei — w tym moje własne pliki, niezwiązane z eksperymentem.
„Równoległe agenty AI w jednym folderze to nie równoległy eksperyment. To jeden wielki konflikt z trzema autorami.”
– wniosek, który kosztował mnie restart
Wyniki dwóch sesji trzeba było uznać za nieprzydatne: nawet gdyby dopracowali je do końca, nie mógłbym uczciwie powiedzieć, czyje poprawki oceniam. Drugie uruchomienie — już w izolowanych worktree — natrafiło na limity taryfy: dwa agenty padły na starcie, a trzeci zawiesił się, nadal wyglądając w interfejsie na „działający”. Diagnozę postawił system plików, a nie wskaźnik statusu: w ciągu dwudziestu minut w jego kopii roboczej nie pojawił się ani jeden plik. To druga przenośna lekcja: żywotność agenta sprawdza się po zmianach na dysku. Po restarcie wszystkie trzy modele przeszły pełny cykl w równych warunkach.
Wyniki: gdzie modele są takie same, a gdzie się różnią
Najważniejszy wynik — to, czego nie było: halucynacji nie ma u żadnego modelu. Ręcznie sprawdziłem po trzy i więcej znalezisk każdego — wszystkie cytaty i numery wierszy są dokładne co do znaku. Dla zadań audytu to główny próg zaufania i przeszli go wszyscy trzej.
Dalej zaczynają się różnice:
| Fable 5 | Opus 4.8 | Sonnet 4.6 | |
|---|---|---|---|
| Potwierdzonych znalezisk | 11 | 5 | 9 |
| Nietrywialnych unikalnych | 3 | 1 | 2 |
| Samosprawdzenie poprawki | render integracyjny na tymczasowej bazie, xmllint, atrybucja cudzego padniętego testu | linter + render; złapał własny błąd | tylko linter i lista tras |
| Tokeny / czas | 164k / 21 min | 101k / 12 min | 131k / 12 min |
| Wynik według rubryki (z 30) | 30 | 24 | 25,5 |
Różnice jakościowe są bardziej informatywne niż punkty. Opus 4.8 — jedyny, który nie zauważył zepsutego nagłówka Content-Type w sitemap (znaleźli go dwaj pozostali) i zostawił go we własnej poprawce; a do jego rosyjskiego tekstu przeciekło angielskie słowo — „и even путь к картинке”. Sonnet 4.6 zrobiła poprawną poprawkę, ale jej samosprawdzenie było deklaratywne: linter zamiast uruchomienia. Fable 5 wyróżniła się właśnie na samosprawdzeniu: odkryła, że php na mojej maszynie to nakładka na kontener docker zamontowany na katalog główny, przebudowała wszystkie sprawdzenia przez jednorazowe kontenery i przepuściła swoją poprawkę integracyjnie na tymczasowej bazie. Różnica między „zrobiłem” a „udowodniłem, że zrobiłem” — to właśnie najbardziej różnicująca oś dla zadań agentowych.
Jeszcze jeden użyteczny sygnał — konwergencja: wszystkie trzy modele niezależnie nazwały głównym znaleziskiem ten sam problem z sitemap. Kiedy niezależni audytorzy zbiegają się w znalezisku numer jeden, to tani odpowiednik zgodności międzyeksperckiej: problem prawie na pewno jest realny.
Sędzia spośród uczestników
Ocenę według rubryki przeprowadziła Fable 5 — ten sam model, który brał udział w porównaniu. To metodologiczna dziura i trzeba o niej mówić wprost: sędziowie LLM systematycznie zawyżają oceny własnym tekstom, przy czym skłonność jest tym silniejsza, im lepiej model rozpoznaje swoje teksty — pokazano to w pracy Panickssery i współautorów na NeurIPS 2024. Złagodzić obciążenie można na dwa sposoby i użyłem obu: po pierwsze, maksymalnie przesunąć rubrykę od osi gustu ku sprawdzalnym faktom — dokładność wierszy, kompletność poprawki, przeciekłe obcojęzyczne słowo nie zależą od sympatii sędziego; po drugie, wyraźnie zadeklarować konflikt i oddać sporne osie do krzyżowej weryfikacji innemu modelowi lub człowiekowi. Subiektywne osie mojego wyniku — jakość tekstu, jakość rozumowania — warto czytać z tą poprawką.
Ograniczenia uczciwości
Jeden przebieg na model — to n=1: różnice w jeden-dwa punkty nic nie znaczą, wierzyć warto tylko jakościowym przepaściom — przeoczonemu bugowi, głębi samosprawdzenia. Eksperyment mierzy trzy modele na jednym zadaniu w jednej domenie; „Fable 5 jest lepszy w ogóle” z niego nie wynika. I warto pamiętać o cenie: topowy model zużył 1,6 razy więcej tokenów i prawie dwa razy więcej czasu niż najbardziej oszczędny uczestnik, a jego token według cennika jest jeszcze droższy sam w sobie — dla regularnych zadań to ważki argument na rzecz prostszych modeli.
Co zabieram dla siebie
Metodyka sprowadziła się do krótkiej listy kontrolnej, która działa dla każdego projektu i każdych modeli:
- Zadanie testowe — pełny cykl realnej pracy na własnym kodzie, a nie syntetyczna łamigłówka.
- Jeden prompt dla wszystkich, izolacja przez osobne worktree, wyniki — w osobnych gałęziach.
- W prompcie — wyraźna cena halucynacji: wymyślone znalezisko jest gorsze niż brak znaleziska.
- Podpowiedzi dostępne wszystkim (dokumentacja, notatki w repozytorium) wyłącza się z zaliczenia głębi.
- Rubryka jest ustalana przed uruchomieniem i opiera się na sprawdzalnych faktach, a nie na wrażeniu.
- Próbkę znalezisk sprawdzać ręcznie; zgodność znalezisk numer jeden u niezależnych modeli — sygnał ich realności.
- Sędzia-uczestnik — zadeklarowany konflikt: sporne osie oddawać do oceny krzyżowej.
- Żywotność agenta sprawdzać po dysku, a nie po wskaźniku w interfejsie.
Bonus, którego nie było w planie: eksperyment zwrócił się sam. Trzy niezależne audyty znalazły w blogu realne problemy — od sitemap bez angielskich stron po martwe zapytania w kontrolerze — i dwie gotowe poprawki już leżą w gałęziach, czekając na przeniesienie do produkcji. Porównanie modeli na własnym kodzie, w odróżnieniu od czytania benchmarków, zostawia po sobie nie tylko opinię.
Źródła i punkty odniesienia
- Benchmark Data Contamination of Large Language Models: A Survey (Xu et al., 2024) — systematyzacja problemu zanieczyszczenia benchmarków; główny argument na rzecz testów na własnym kodzie.
- Benchmarking LLMs Under Data Contamination: From Static to Dynamic Evaluation (EMNLP 2025) — jak branża odchodzi od testów statycznych ku dynamicznym; mój eksperyment jest szczególnym przypadkiem testu dynamicznego.
- Demystifying evals for AI agents (Anthropic Engineering, 2026) — praktyka oceny agentów: zadania z rzeczywistego produktu, weryfikowalne rubryki, rozróżnienie trajektorii i wyniku.
- LLM Evaluators Recognize and Favor Their Own Generations (NeurIPS 2024) — dlaczego model-sędzia zawyża oceny sobie i co z tym zrobić.
- Run parallel sessions with worktrees (Claude Code Docs) — standardowy mechanizm izolacji równoległych sesji agentowych, bez którego pierwsze uruchomienie eksperymentu się rozsypało.
