← Essäer

Fable 5, Opus 4.8 och Sonnet 4.6: hur man ärligt jämför LLM:er på sin egen kod

Kontrollerat experiment: Fable 5, Opus 4.8 och Sonnet 4.6 granskar samma kodbas utifrån en identisk prompt. Metodik för en ärlig jämförelse av LLM:er i det egna projektet.

8 min läsning
TelegramOriginal
Fable 5, Opus 4.8 och Sonnet 4.6: hur man ärligt jämför LLM:er på sin egen kod

När en ny modell släpps svarar annonseringen på frågan "hur mycket bättre är den på benchmarks" — och inte på den enda fråga som intresserar mig: vad den kommer att förändra i mitt arbete. Jag genomförde ett kontrollerat experiment: tre Claude-modeller — Fable 5, Opus 4.8 och Sonnet 4.6 — fick en ordagrant identisk uppgift att granska kodbasen för den här bloggen, var och en i en isolerad kopia av repot, med en i förväg överenskommen bedömningsrubrik. Artikeln innehåller själva metodiken, som kan upprepas i vilket projekt som helst, resultaten, och separat — hur experimentet gick sönder två gånger och vad det lärde mig.

Varför benchmarks inte svarar på min fråga

Publika benchmarks har två problem, och båda är fundamentala. Det första är datakontaminering: testexempel läcker in i träningsdata, och modellen "minns" delvis svaren i stället för att lösa uppgiften. Det är inte en marginell misstanke, utan föremål för en hel forskningsinriktning: översikten av Xu med flera (2024) systematiserar forskningen om kontaminering av benchmarks, och EMNLP 2025-översikten fångar industrins svar — övergången från statiska tester till dynamiskt genererade.

Det andra problemet är enklare: benchmarken mäter inte min uppgift. Jag behöver ingen modell som är bäst på olympiaduppgifter. Jag behöver en modell som hittar verkliga buggar i min Laravel-blogg, inte hittar på icke-existerande sådana och bevisar att dess fix fungerar.

Av detta följer en enkel tanke: den bästa testbänken för att jämföra modeller är det egna projektet. Dess kod finns inte i den kombinationen i träningsdata, uppgifterna på den är exakt de jag betalar för, och resultaten kan jag verifiera för hand eftersom jag kan den här koden.

Experimentets design: en prompt, tre isolerade världar

Uppgiften var ordagrant identisk för alla tre modellerna — endast branchnamn och resultatmapp skilde sig. Fyra faser: granskning av bloggens tvåspråkiga artikelsystem med bevis för varje fynd i form av файл:строка med kodcitat; val av lösningar för de tre viktigaste fynden med beskrivning av avvägningar; implementering av en fix med självkontroll; en anteckning om resultaten på ryska och engelska. En fullständig ingenjörscykel, inte en isolerad "fråga-svar" — ett sådant tillvägagångssätt rekommenderar även Anthropic: att utvärdera agenter på uppgifter från en verklig produkt, enligt en rubrik som överenskommits före start.

Tre regler gjorde jämförelsen ärlig:

Isolering. Varje modell arbetade i en separat git worktree — en egen kopia av arbetskatalogen med egen branch. Modellerna kunde fysiskt inte se varandras resultat eller störa varandra.

Skydd mot hallucinationer — i själva prompten. Uppgiftens nyckelmening: "ett påhittat fynd (icke-existerande kod, fel rad) är värre än inget fynd". Utan denna sporre är en modell som ombeds hitta problem benägen att "hitta" dem oavsett. Med den måste varje fynd klara en manuell kontroll.

Undantag av ledtrådar från poängsättningen. I repot finns CLAUDE.md, som beskriver projektets kända fallgropar — till exempel relativa sökvägar till assets som går sönder på URL:er med språkprefix. Alla tre modellerna läser den filen, så sådana fynd är "gratis": de räknas för noggrannhet, men inte för djup.

Rubriken: bedöm bara det som kan verifieras för hand

Före start fastställde jag sex axlar med fem poäng vardera: granskningsnoggrannhet (manuell kontroll av ett urval fynd mot файл:строка), djup (bekräftade fynd som inte finns i ledtrådarna), kvalitet i resonemanget om avvägningar, kod och självkontrollens verklighet, kvalitet i rysk och engelsk text, disciplin (noll frågor till människan, inte en enda överträdelse av begränsningarna). Principen är densamma som för en bra kodgranskning: ju mindre en axel vilar på smak och ju mer på verifierbart faktum, desto mer kan man lita på den.

Hur allt gick sönder första gången

Första körningen gjorde jag fel — och det visade sig vara experimentets mest överförbara del. Jag öppnade tre interaktiva sessioner parallellt i samma mapp i repot. Efter några minuter låg ocommittade ändringar i arbetsträdet som inte gick att tillskriva någon: en gemensam checkout innebär att när en session gör git checkout -bbyter branchen för alla tre, och deras ändringar och commits blandas ihop. En av sessionerna gjorde dessutom git stash och sopade in allt möjligt i den — inklusive mina egna filer som inte hade med experimentet att göra.

"Parallella AI-agenter i en mapp är inte ett parallellt experiment. Det är en enda stor konflikt med tre författare."

– slutsatsen som kostade mig en omstart

Resultaten från två sessioner måste betraktas som oanvändbara: även om de hade slutfört arbetet skulle jag inte ärligt kunna säga vems ändringar jag bedömer. Den andra körningen – nu i isolerade worktrees – stötte på tariffens gränser: två agenter dog vid starten, och den tredje hängde sig medan den fortsatte att se "fungerande" ut i gränssnittet. Diagnosen ställdes av filsystemet, inte av statusindikatorn: under tjugo minuter uppstod inte en enda fil i dess arbetskopia. Detta är den andra överförbara lärdomen: en agents livlighet verifieras genom ändringar på disken. Efter omstarten genomgick alla tre modellerna en fullständig cykel under lika villkor.

Resultat: var modellerna är lika och var de skiljer sig

Det viktigaste resultatet är det som inte hände: inga hallucinationer hos någon av modellerna. Jag kontrollerade manuellt tre eller fler fynd från varje – alla citat och radnummer är exakta in i minsta tecken. För granskningsuppgifter är detta den viktigaste förtroendetröskeln, och alla tre klarade den.

Sedan börjar skillnaderna:

Fable 5 Opus 4.8 Sonnet 4.6
Bekräftade fynd 11 5 9
Icke-triviala unika 3 1 2
Självverifiering av fixen integrationsrendering på temporär databas, xmllint, attribution av ett annans misslyckade test linter + rendering; fångade en egen bugg endast linter och lista över rutter
Token / tid 164k / 21 min 101k / 12 min 131k / 12 min
Resultat enligt rubric (av 30) 30 24 25,5

Kvalitativa skillnader är mer informativa än poäng. Opus 4.8 var den enda som inte märkte den trasiga rubriken Content-Type i sitemap (de två andra hittade den) och lämnade den kvar i sin egen fix; och i dess ryska text läckte ett engelskt ord in – "и even путь к картинке". Sonnet 4.6 gjorde en korrekt fix, men dess självverifiering var deklarativ: linter istället för körning. Fable 5 utmärkte sig just i självverifieringen: upptäckte att php på min maskin är en wrapper runt en docker-container monterad på baskatalogen, byggde om alla kontroller genom engångscontainrar och körde sin fix integrerat på en temporär databas. Skillnaden mellan "jag gjorde det" och "jag bevisade att jag gjorde det" är just den mest differentierande axeln för agentuppgifter.

En annan användbar signal är konvergens: alla tre modellerna utpekade oberoende av varandra samma problem med sitemap som huvudfynd. När oberoende granskare sammanstrålar i toppfyndet är det en billig analog till interexpertkonsistens: problemet är nästan säkert verkligt.

Domare från deltagarnas skara

Bedömningen enligt rubric gjordes av Fable 5 – samma modell som deltog i jämförelsen. Detta är ett metodologiskt hål, och det måste sägas rakt ut: LLM-domare överskattar systematiskt egna texter, och benägenheten är starkare ju bättre modellen känner igen sina egna texter – detta visas i arbetet av Panickssery och medförfattare på NeurIPS 2024. Biasen kan mildras på två sätt, och jag använde båda: för det första att i maximal utsträckning förskjuta rubricen från smakaxlar till verifierbara fakta – radprecision, fixens fullständighet, det läckta främmande ordet beror inte på domarens sympatier; för det andra att explicit deklarera intressekonflikten och lämna omtvistade axlar till korsgranskning av en annan modell eller människa. De subjektiva axlarna i mitt resultat – textkvalitet, resonemangskvalitet – bör läsas med denna korrigering.

Ärlighetens begränsningar

En körning per modell är n=1: skillnader på en eller två poäng betyder ingenting, det är bara kvalitativa gap som är värda att lita på – en missad bugg, självverifieringens djup. Experimentet mäter tre modeller på en uppgift i en domän; "Fable 5 är bättre överlag" följer inte av det. Och man bör komma ihåg kostnaden: toppmodellen förbrukade 1,6 gånger fler token och nästan dubbelt så mycket tid som den mest sparsamma deltagaren, och dess token enligt prislistan är dessutom dyrare i sig – för regelbundna uppgifter är detta ett tungt argument för enklare modeller.

Vad jag tar med mig

Metodiken kokade ner till en kort checklista som fungerar för vilket projekt och vilka modeller som helst:

  • Testuppgiften är en fullständig cykel av verkligt arbete på egen kod, inte en syntetisk uppgift.
  • En prompt för alla, isolering via separata worktrees, resultat i separata grenar.
  • I prompten – ett explicit pris för hallucination: ett påhittat fynd är sämre än inget fynd.
  • Ledtrådar som är tillgängliga för alla (dokumentation, anteckningar i repot) utesluts från djupbedömningen.
  • Rubricen fastställs före körningen och vilar på verifierbara fakta, inte på intryck.
  • Urvalet av fynd ska kontrolleras manuellt; sammanfallande toppfynd hos oberoende modeller är en signal om att de är verkliga.
  • Domare-deltagare – en deklarerad intressekonflikt: omtvistade axlar lämnas till korsbedömning.
  • Agentens livlighet verifieras via disken, inte via indikatorn i gränssnittet.

En bonus som inte ingick i planen: experimentet betalade sig självt. Tre oberoende granskningar hittade verkliga problem i bloggen – från sitemap utan engelska sidor till döda förfrågningar i kontrollern – och två färdiga fixar ligger redan i grenar och väntar på att flyttas till prod. Att jämföra modeller på egen kod, till skillnad från att läsa benchmarks, lämnar efter sig mer än bara en åsikt.

Källor och riktmärken