Bygg robusta test-suiter för LLM-appar. Evals och regression-test.
Traditionella tester är deterministiska: samma indata ger samma utdata, och ett rött test betyder en bugg. LLM-appar bryter mot det antagandet. Samma fråga kan ge olika svar, och två olika formuleringar kan båda vara korrekta. Det gör att vanliga enhetstester inte räcker, och det är därför så många team flyger blint - de byter modell eller justerar en prompt och hoppas på det bästa. Evals är svaret, men de måste byggas med lite eftertanke för att faktiskt fånga regressioner.
Jag har satt upp utvärderingssviter för svenska bolag där ett felaktigt svar har verkliga konsekvenser, och nedan är mönstren som gör skillnaden mellan en eval som ger trygghet och en som bara ger en grön bock utan innehåll. Poängen med evals är inte att bevisa att appen är perfekt - det blir den aldrig - utan att kunna säga om en ändring gjorde den bättre eller sämre. Utan det blir varje modellbyte och varje prompt-justering en chansning där man hoppas att man inte råkade gå bakåt.
Bygg en datamängd som speglar verkligheten
En eval är aldrig bättre än sin datamängd. Jag börjar med att samla in riktiga frågor - från supportloggar, från användartester, från det som faktiskt ställts. Sedan kompletterar jag med svåra kantfall: tvetydiga frågor, frågor utanför domänen, och de fall som tidigare gått fel. Målet är inte hundratals exempel direkt utan ett urval som täcker bredden av det appen möter.
- Vanliga fall: det som utgör majoriteten av trafiken.
- Kantfall: tvetydigheter, tomma svar, frågor utanför scope.
- Regressionsfall: varje bugg som hittats blir ett permanent testfall.
Välj rätt metod för att bedöma svaret
Det finns tre huvudsakliga sätt att avgöra om ett svar är bra, och de passar olika situationer. Exakt matchning fungerar när det finns ett rätt svar - en kod, ett tal, ett klassificeringsbeslut. Regelbaserade kontroller fångar format och förbjudna fraser. Och för öppna svar använder jag en modell som domare, men med försiktighet.
LLM-as-judge: kraftfullt men förrädiskt
Att låta en LLM bedöma en annan LLM:s svar är effektivt för öppna uppgifter där det inte finns ett facit. Men en domarmodell har sina egna systematiska fel: den tenderar att gilla längre svar, sin egen stil, och kan vara inkonsekvent. Jag begränsar därför domaren till tydligt definierade kriterier, ger den en rubrik att följa, och kalibrerar den mot mänskliga bedömningar på ett urval. En domare man inte kalibrerat är en domare man inte kan lita på.
Ett konkret knep som höjer tillförlitligheten är att be domaren bedöma en sak i taget snarare än att ge ett samlat helhetsbetyg. "Är svaret grundat i källan?" och "Är tonen korrekt?" som separata frågor ger stabilare resultat än "Hur bra är svaret på en skala?". Jag ber också domaren motivera sitt omdöme, dels för att resultatet blir bättre, dels för att jag då kan läsa motiveringarna och upptäcka när domaren själv har fel. Och jag använder helst en annan eller starkare modell som domare än den som producerade svaret, för att undvika att en modell systematiskt belönar sin egen stil.
Mät rätt saker, inte bara ett medelvärde
Ett enda aggregerat poäng döljer mer än det visar. Jag följer flera dimensioner: korrekthet, att svaret är grundat i källorna när det gäller RAG, format, ton och kostnad. För RAG-appar mäter jag dessutom hämtningssteget separat, eftersom ett dåligt svar lika gärna kan bero på fel dokument som på fel generering - något jag utvecklar i RAG i produktion.
Koppla evals till varje förändring
En eval som körs en gång är en mätning; en eval som körs vid varje ändring är ett skyddsnät. Jag kör sviten automatiskt när någon ändrar en prompt, byter modell eller justerar en parameter, och jämför mot baslinjen. Då syns det direkt om en förbättring på ett område försämrade ett annat. Det här hänger tätt ihop med hur jag versionerar prompts, vilket jag beskriver i artikeln om prompt-arkitektur.
Att etablera den här rutinen är ofta ett av de första stegen jag tar i ett uppdrag inom AI Engineering, eftersom allt annat - modellbyten, kostnadsoptimering, nya funktioner - blir gissningar utan den.
Offline-sviter räcker inte - mät även i produktion
En utvärderingssvit körd före release fångar regressioner mot kända fall, men den ser inte de frågor du inte tänkt på. Därför kompletterar jag alltid med mätning på riktig trafik: ett urval av faktiska svar loggas och bedöms löpande, och jag följer enkla signaler som hur ofta användare omformulerar sin fråga eller överger ett flöde. De svaren matas sedan tillbaka in i offline-sviten som nya testfall. På så sätt blir sviten en levande spegel av verkligheten istället för en samling exempel som speglar hur appen såg ut för ett halvår sedan.
Undvik att överanpassa till testsviten
Det finns en fälla i att finslipa mot evalen tills siffran ser perfekt ut. Då riskerar du att optimera för testet snarare än för verkligheten. Jag håller därför en del av datamängden separat som jag inte tittar på under utveckling, och roterar in nya riktiga fall löpande så att sviten inte stelnar. Samma logik som inom vanlig maskininlärning: tränar du mot testmängden mäter du till slut bara hur bra du memorerat den.
Relaterat
- RAG i produktion: Chunking, embeddings, reranking och evals
- LangChain vs LangGraph vs LlamaIndex: Vilken passar ert use case?
- Voice AI för kundtjänst: OpenAI Realtime + Twilio i svensk produktion
Ett exempel på hur evals fångat en regression innan release finns bland mina kundcase.
Vill du ta det vidare?
Om ni driftar en LLM-app utan utvärdering och vill kunna byta modell utan att hålla andan hjälper jag er bygga en svit som passar er domän. Boka ett förutsättningslöst samtal så går vi igenom era viktigaste fall.
“En eval som körs en gång är en mätning; en eval som körs vid varje ändring är ett skyddsnät.”
- Simon Axelsson
Vanliga frågor
- Hur många testfall behöver jag för att börja?
- Färre än man tror. Ett par dussin välvalda fall som täcker vanliga frågor, ett antal kantfall och dina kända buggar ger redan ett användbart skyddsnät. Det är bredden och relevansen som räknas, inte antalet. Utöka sedan löpande med nya riktiga fall.
- Kan jag lita på en LLM som bedömer svaren?
- Till en gräns. En domarmodell har systematiska fel - den gillar gärna längre svar och sin egen stil. Ge den tydliga kriterier och en rubrik, och kalibrera den mot mänskliga bedömningar på ett urval. Då blir den användbar för öppna svar där det saknas facit.
- Hur ofta ska evals köras?
- Vid varje förändring som kan påverka beteendet: prompt-ändringar, modellbyten och parameterjusteringar. Att köra automatiskt mot en baslinje gör att en förbättring på ett område inte tyst försämrar ett annat. En eval som bara körs ibland missar precis de regressioner den ska fånga.
