← Wróć do bloga

Benchmark Claude Code, 6 konfiguracji — wygrał Sonnet

Sześć kontrolowanych runów na tym samym tickecie inżynierskim, konfiguracje od A do F. Sonnet 4.6 z czteropunktowym promptem efektywnościowym zużył 27% mniej turnów i 24% mniej output tokenów niż ten sam model bez instrukcji — a droższy Opus 4.7 nie dał żadnej przewagi jakościowej, kosztując 1.5–2× więcej.

Terminal: wynik benchmarku — sześć konfiguracji od A do F, output tokeny per run, zwycięzca: Sonnet plus grep-first plus max 15 wywołań narzędzi, z wynikiem −27% turnów, −24% output tokenów, −26% cache reads.

Jeśli używasz Claude Code do czegokolwiek poza chatem — sub-agenci, długie sesje, zautomatyzowane pipeline’y — to pewnie patrzyłaś/patrzyłeś na swój usage dashboard i zadałaś sobie pytanie: która konfiguracja zrobi to samo, tylko taniej?

Tym razem postanowiłam to sprawdzić u siebie. Sześć kontrolowanych konfiguracji na tym samym tickecie inżynierskim. Dwa modele, trzy kształty promptu. To samo środowisko, to samo zadanie, te same kryteria akceptacji.

Wynik:

Sonnet 4.6 + 4-punktowy “addendum efektywnościowy” wygrał z każdą inną konfiguracją — pod kątem output tokenów, turnów, cache reads i czasu wall-clock. Bez utraty jakości. Ten sam model bez tego promptu zużył 27% turnów i 24% output tokenów więcej. Opus 4.7 spalił 1.5–2× więcej tokenów niż Sonnet na tym samym zadaniu, nie poprawiając AC.

Niżej: setup, liczby, prompt który właśnie wstawiam do produkcji, i parę rzeczy które mnie zaskoczyły.

Skąd się to wzięło

Buduję Drift — prywatny agent runner, któremu mogę oddelegować pracę. Pomysł jest egoistyczny i prosty: wystawiam ticket z telefonu, kiedy jestem na spacerze z psem, agenty go odbierają, robią robotę, a po powrocie do biurka mam gotowy diff do code review.

Każdy ticket kosztuje tokeny. Sonnet vs Opus, z tuningiem promptu albo bez — rachunek skacze 2–3× na tym samym zadaniu. Zanim wyskaluję Drift na większe projekty klienckie, chciałam mieć twarde liczby, która konfiguracja jest najtańsza przy tej samej jakości.

Stąd benchmark A–F.

Co mierzyłam (i dlaczego akurat te modele)

Dwa modele × trzy kształty promptu = sześć konfiguracji:

KonfigModelKształt promptu
ASonnet 4.6standardowy (baseline)
BSonnet 4.6grep-first + max 15 wywołań narzędzi
COpus 4.7standardowy
DOpus 4.7grep-first + max 15 wywołań narzędzi
ESonnet 4.6parallel tool batching
FOpus 4.7parallel tool batching

Dlaczego te dwa modele? Sonnet 4.6 to koń roboczy — szybki, tani, w większości przypadków wystarczająco dobry do kodu. Opus 4.7 jest pozycjonowany pod trudniejsze rozumowanie, ale kosztuje ~5× więcej za token. Cały sens testu: sprawdzić czy Opus realnie zarabia na swoją cenę w rutynowej pracy inżynierskiej, czy może Sonnet plus mądrzejszy prompt pokrywa to samo taniej.

Trzy kształty promptu:

Co mierzyłam:

Zadanie było realistycznym ticketem inżynierskim: dodać per-type limity równoległości do 3000-liniowego workera w Pythonie. Siedem mechanicznie weryfikowalnych AC — stałe, sygnatury funkcji, stringi w logach, syntax check przez ast.parse. Nietrywialne (agent musi się odnaleźć w dużym pliku i przerobić główną pętlę), ale to nie jest też architektura od zera. Sensowny proxy na typowy ticket implementacyjny.

Runda 1 — trzy konfiguracje na rozgrzewkę

Zaczęłam od trzech konfiguracji, żeby zweryfikować że cały setup w ogóle ma sens, zanim odpalę pełną macierz:

KonfigModelPromptACTurnsOut tokCache read
ASonnetstandardowy7/7243 744864 K
BSonnetgrep-first + max 15 wywołań narzędzi7/7193 276640 K
COpusstandardowy7/7337 5901 584 K

Dwa wnioski z pierwszej rundy:

  1. Prompt efektywnościowy działa. B zużył 21% mniej turnów i 13% mniej output tokenów niż A — ten sam model, to samo zadanie, ta sama jakość końcowa.
  2. Opus jest drogi — i wcale nie lepszy. To samo 7/7 AC, ale 2× output tokenów i 2.5× cache reads vs Sonnet baseline. Na dobrze zdefiniowanym tickecie z weryfikowalnymi AC Opus nie ma żadnej przewagi.

Runda 2 — pełna macierz A–F

Każda konfiguracja na świeżym git worktree z tego samego commita. Świeży kontekst, zero cross-contamination:

KonfigModelPromptACTurnsToolsBatchedOut tokCache readCzas
ASonnetstandardowy7/7221303 882769 K55s
BSonnetgrep-first + max 15 wywołań narzędzi7/7161102 938566 K50s
COpusstandardowy7/7291605 9241 427 K80s
DOpusgrep-first + max 15 wywołań narzędzi7/7171004 895793 K60s
ESonnetparallel batching7/7342004 9631 204 K80s
FOpusparallel batching7/7271806 8641 270 K80s

Co mówią liczby:

Opus słucha promptu — i wciąż przegrywa z Sonnetem na każdej metryce.

Środowisko testowe — dla zainteresowanych replikacją

Czysty benchmark to taki, gdzie nic z runa nie przecieka do realnych systemów. Trzy elementy załatwiły tę robotę:

Git worktrees, jeden per konfiguracja. Każdy agent dostał własną kopię roboczą repo, gałąź z tego samego commita:

git worktree add /tmp/exp/wt-A HEAD
git worktree add /tmp/exp/wt-B HEAD
# ... C, D, E, F

To samo źródło, sześć odizolowanych workspace’ów. Agent mógł grepować, czytać, edytować, młotkować kod — nic z tego nigdy nie dotknęło produkcyjnego checkoutu, nic nie wpadało do merge’a. Po każdym runie worktree był resetowany do HEAD, żeby kolejny agent zaczął z czystym stanem.

Fake HTTP server w miejscu prawdziwego API. Agenci Drifta normalnie wołają REST API, żeby oznaczyć ticket jako rozpoczęty, zalogować postęp, zamknąć. Na potrzeby eksperymentu zastąpiłam to minimalnym serwerem, który akceptuje każde wywołanie i ignoruje payload:

GET   /api/tickets/9901           → zwraca fake ticket
POST  /api/tickets/9901/events    → 200 OK (drops payload)
PATCH /api/tickets/9901           → 200 OK (drops payload)

Brak produkcyjnej bazy, brak triggerowania realnych workerów, brak ryzyka że eksperyment niechcący promotuje się do rzeczywistości. Agent myśli że robi robotę; system łyka wynik bez efektu.

Czemu nie odpalić tego po prostu na produkcji? Z dwóch powodów:

Prompty (do skopiowania)

Addendum efektywnościowy (konfiguracje B i D — zwycięzca):

## INSTRUKCJA EFEKTYWNOŚCI

Pracuj liniowo i minimalnie:
1. ZAWSZE zrób grep/search zanim otworzysz plik —
   nie czytaj pliku "żeby zobaczyć co tam jest"
2. Czytaj tylko te fragmenty których potrzebujesz
   (użyj offset+limit w Read)
3. Nie exploruj dookoła — jeśli AC mówi
   "dodaj funkcję przy linii 302", idź tam bezpośrednio
4. Limit: 15 wywołań narzędzi łącznie.
   Po 15 — zakończ z tym co masz.

Cztery punkty. Tyle. −27% turnów, −24% output tokenów, AC bez zmian.

Addendum parallel batching (konfiguracje E i F — to które się odbiło):

## INSTRUKCJA PARALLEL TOOL USE

Gdy masz kilka niezależnych operacji do wykonania —
wywołaj je wszystkie w jednym turnie, nie sekwencyjnie.
Dotyczy to zarówno czytania różnych fragmentów tego
samego pliku (Read offset=0, Read offset=300,
Read offset=3100 równocześnie), jak i niezależnych
grepów czy sprawdzeń w różnych plikach.

Model rozumie intencję (widać że narratywuje w outputcie co zrobi równolegle), ale stream wywołań we wszystkich sześciu runach zawiera dokładnie zero batchowanych tool callów. Promptowe wymuszenie batchowania wygląda na non-feature w trybie -p.

Parę rzeczy które mnie zaskoczyły

Co z tym robię

Drift wjeżdża z addendum efektywnościowym w każdym tickecie typu impl. 4-punktowy blok siedzi w konfiguracji workera i jest doklejany do system promptu przed każdym runem agenta. Ten sam model, to samo zadanie, około 25% mniej kosztu per ticket. Biorę.

Przy większych projektach — gdzie agent czyta po wielu plikach i pisze po wielu modułach — odpalę benchmark ponownie, zanim założę że ten sam prompt wciąż wygrywa. Aktualne stwierdzenie jest wąskie, ale solidne: na dobrze zdefiniowanym tickecie implementacyjnym w znanym kodzie, Sonnet plus grep-first wygrywa z każdą inną konfiguracją Claude Code którą sprawdziłam.

Jeśli używasz Claude Code w jakimkolwiek pipelinie i masz weryfikowalny test case, odpal sobie taki benchmark na własnym zadaniu, zanim wybierzesz model. Domyślne ustawienia nie są najtańsze. Najdroższy model nie jest najlepszy. A 4-punktowy addendum do promptu potrafi ściąć ćwiartkę rachunku za tokeny zanim w ogóle ruszysz model.

← Wróć do bloga