Tillbaka till bloggen
Bygga23 april 20268 min läsning

RAG är inte magi. Här är var det går sönder

Ett tänkt scenario: en organisation har byggt sitt eget RAG-system på tre veckor. Vektordatabas, embeddingmodell, proffsigt chattgränssnitt. Allt fungerar på demofrågorna. Sedan ställer någon en specifik fråga och systemet svarar med rätt fakta om fel sak.

Kapaciti

Tänk ett scenario som upprepas i marknaden just nu. En organisation har byggt sitt eget RAG-system på tre veckor. De har en vektordatabas, en embeddingmodell, och ett chattgränssnitt som ser proffsigt ut. Allt fungerar utmärkt på demofrågorna. Sedan ställer en säljare en fråga om garantivillkor för en specifik produktserie, och systemet svarar med information från en helt annan produktkategori. Inte fel i den meningen att det hittade på fakta, utan fel i den meningen att det hittade rätt fakta om fel sak. Det är den typen av fel som är farligast, för ingen reagerar på ett svar som låter rimligt.

RAG har blivit standardarkitekturen för företag som vill att en språkmodell ska kunna svara på frågor om intern dokumentation. Konceptet är elegant: istället för att stoppa in alla dokument i modellens kontext söker du fram de mest relevanta textbitarna och skickar bara dem. Men elegansen i konceptet döljer att varje steg i kedjan kan gå sönder på sätt som inte syns förrän systemet är i produktion. Mönstret är tydligt nog att man kan peka ut var det brukar haverera.

Chunking är inte ett löst problem

Det första steget i en RAG-pipeline är att dela upp dokument i mindre bitar, så kallade chunks, som sedan indexeras. Det låter trivialt. Det är det inte. Den vanligaste metoden är att dela efter ett fast antal tokens, ibland med lite överlapp mellan bitarna. Det fungerar hyfsat på löpande text, men de flesta företagsdokument är inte löpande text. De är avtal med numrerade paragrafer som refererar till varandra. De är tekniska manualer där en tabell på sida fyra förklarar en procedur på sida tre. De är policydokument där ett undantag i slutet av ett stycke ändrar innebörden av allt som stod innan.

Ett illustrativt scenario: ett bolag indexerar sina ramavtal med chunkstorlek satt till 512 tokens, vilket är en vanlig default. Problemet uppstår när en klausul om ansvarsbegränsning börjar i slutet av en chunk och fortsätter i nästa. När systemet hämtar den första chunken får användaren information om att ansvarsbegränsningen gäller, men missar undantaget som står i nästa bit. Svaret blir tekniskt korrekt baserat på den hämtade texten, men juridiskt vilseledande. Den typen av fel upptäcks inte av automatiska utvärderingar som bara kontrollerar om svaret innehåller rätt nyckelord.

Lösningen är sällan att bara öka chunkstorleken. Större chunks ger mer kontext men försämrar sökprecisionen, för nu tävlar fler orelaterade meningar om att representera samma vektor. Det vi har landat i hos de flesta kunder är en kombination av semantisk chunking, där man delar vid naturliga ämnesbyten istället för vid en fast tokengräns, och att behålla metadata om dokumentstruktur. Om systemet vet att chunk 14 och 15 tillhör samma paragraf kan det hämta båda när den ena matchar. Det kräver mer arbete vid indexering, men det sparar tid i felsökning senare.

Svenska facktermer försvinner i embeddingmodellen

De flesta embeddingmodeller är tränade på engelska. Även de som marknadsförs som flerspråkiga har sett betydligt mer engelsk text under träningen. Det fungerar överraskande bra för vardagssvenska, men det faller isär när man arbetar med fackspråk. Ta ett typscenario från tillverkningsindustrin med termer som "härdningsprocess", "glödgning" och "sträckgräns" i dokumentationen. Embeddingmodellen placerar dessa termer nära varandra i vektorrymden, vilket i sig inte är fel, men den kan inte skilja dem åt med tillräcklig precision. En fråga om sträckgräns kan ge svar om härdning, för modellen behandlar hela det metallurgiska fältet som en enda klump.

Det finns flera sätt att hantera det. Ett är att finjustera embeddingmodellen på kundens egna data, men det kräver träningsexempel och kompetens som inte alla har tillgång till. Ett enklare steg som ofta ger märkbar förbättring är att bygga en synonymlista eller termexpansion som körs innan sökningen. Om användaren skriver "sträckgräns" kan systemet automatiskt lägga till "yield strength" som en parallell sökterm, eftersom embeddingmodellen förmodligen har bättre representation av det engelska begreppet. Det är inte vackert, men det fungerar, och i produktion är funktion viktigare än elegans.

Ett annat mönster vi sett är att domänspecifika förkortningar skapar problem. Inom bygg kan "BBR" betyda Boverkets byggregler, men embeddingmodellen har ingen aning om det. Den ser tre bokstäver och placerar dem nära andra trebokstavskombinationer. Att lägga till en förbearbetning som expanderar kända förkortningar till deras fulla form innan embedding förbättrar retrieval markant. Det är det ingen som nämner i tutorials, för tutorials arbetar med Wikipedia-artiklar på engelska där det problemet inte existerar.

Reranking är inte en lyx

De flesta RAG-implementationer vi ser hos nya kunder saknar ett reranking-steg. Pipeline ser ut så här: fråga in, vektorsökning, topp fem chunks skickas till modellen. Det fungerar okej i demos, men i produktion märker man snabbt att vektorsökning är bra på att hitta ungefär rätt område men dålig på att ranka inom det området. De fem chunks som kommer tillbaka är alla relevanta på något sätt, men ordningen är ofta fel, och den chunk som faktiskt innehåller svaret kan ligga på plats fyra eller fem.

Ett reranking-steg tar de kandidater som vektorsökningen returnerar och kör dem genom en mer sofistikerad modell som bedömer hur väl varje chunk faktiskt besvarar frågan, inte bara hur nära den ligger i vektorrymden. Det lägger till latency, typiskt 50 till 200 millisekunder beroende på antalet kandidater och modellens storlek. Men förbättringen i svarkvalitet är ofta dramatisk. På interna supportverktyg är det inte ovanligt att andelen frågor där det korrekta svaret finns i topp tre chunks går från runt 60 procent till nära 90 procent efter att man lagt till reranking med en cross-encoder, baserat på publicerade benchmarks och branschstandard. Det är skillnaden mellan ett system som användarna litar på och ett de slutar använda efter två veckor.

Invändningen vi ofta hör är att det kostar för mycket i latency. Men om alternativet är att användaren får ett dåligt svar och måste ställa frågan igen, eller ännu värre, agerar på felaktig information, så är 150 millisekunder en billig försäkring. Vi brukar hämta fler kandidater från vektorsökningen, säg tjugo istället för fem, och sedan låta rerankern välja de bästa tre. Det ger rerankern mer att arbeta med och förbättrar resultaten ytterligare.

Hybrid sök löser problem du inte visste att du hade

Vektorsökning är semantisk. Den förstår att "uppsägning av anställd" och "avsluta ett arbetsförhållande" handlar om samma sak. Det är dess styrka. Men den har en blind fläck: exakta termer. Om en användare söker efter "avtal 2024-0847" så finns det inget semantiskt att fånga. Det är en identifierare, och vektorsökningen kommer att returnera chunks som handlar om avtal i allmänhet istället för det specifika avtalet.

BM25, den klassiska nyckelordsbaserade sökningen, är motsatsen. Den bryr sig inte om semantik utan letar efter exakta ordmatchningar. Den hittar "avtal 2024-0847" utan problem, men den missar att "uppsägning" och "avsluta arbetsförhållande" är relaterade. Hybrid sök kombinerar båda. Du kör vektorsökning och BM25 parallellt, normaliserar poängen, och slår ihop resultaten. Det låter som en kompromiss, men i praktiken vinner hybriden nästan alltid.

I typscenarier där fastighetsbolag indexerat hyresavtal har skillnaden mellan ren vektorsökning och hybrid sök varit påtaglig. Vektorsökning ensam landar ofta runt 70 procent precision på rätt avtal. BM25 ensam ligger lägre, kring 55 till 60 procent. En hybrid där vektorsökning viktas runt 60 procent och BM25 runt 40 procent kan nå över 85 procent. Den extra komplexiteten i att köra två sökningar parallellt är minimal, och BM25 kräver inga GPU-resurser. Det enda som krävs är att du indexerar dina dokument i både ett vektorindex och ett inverterat index, vilket de flesta moderna databaser som stödjer vektorsökning redan erbjuder.

Mätning bortom magkänsla

Det vanligaste sättet att utvärdera ett RAG-system är att ställa några frågor och se om svaren "känns rätt". Det är ungefär lika tillförlitligt som att testa en bil genom att titta på den. Du behöver mäta, och du behöver mäta rätt saker. De tre mått vi alltid sätter upp hos kunder är retrieval precision, faithfulness och answer relevance.

Retrieval precision mäter om de chunks som hämtas faktiskt innehåller information som behövs för att besvara frågan. Du kan ha ett system som ger bra svar trots dålig retrieval precision, för språkmodellen är bra på att ignorera irrelevant kontext, men det betyder att du slösar tokens och pengar på att skicka in text som inte bidrar. Faithfulness mäter om svaret faktiskt baseras på den hämtade kontexten eller om modellen fyller i med egen kunskap. Ett RAG-system som hallucinerar trots att det har rätt kontext framför sig har ett problem med prompten, inte med sökningen. Answer relevance mäter om svaret faktiskt besvarar frågan som ställdes, inte en närliggande fråga.

Vi bygger utvärderingsset med minst 50 fråga-svar-par som domänexperter hos kunden har validerat. Det tar tid att skapa, men utan det flyger du blint. Varje gång du ändrar chunking-strategi, byter embeddingmodell eller justerar sökparametrar kör du utvärderingssettet och ser om siffrorna gick upp eller ner. Utan den disciplinen är varje förändring en gissning. Vi har sett team som "optimerade" sitt system i veckor och slutade med sämre resultat än de började med, för de aldrig mätte utgångsläget.

Var du börjar spelar roll

Om du ska bygga eller förbättra ett RAG-system, börja inte med modellen. Börja med datan. Titta på dina dokument och fråga dig hur en människa skulle hitta svaret. Om en människa behöver läsa tre stycken i följd för att förstå svaret, behöver ditt system också göra det, och då måste din chunking-strategi stödja det. Om dina dokument är fulla av facktermer och förkortningar, testa att söka efter dem i ditt embeddingindex och se vad som kommer tillbaka. Du kommer förmodligen att bli förvånad.

Sedan: mät tidigt. Bygg ditt utvärderingsset innan du börjar optimera, inte efter. Det är frestande att skjuta upp det, men utan mätning vet du inte om dina ändringar hjälper eller stjälper. Lägg till reranking, det kostar lite latency men ger mycket tillbaka. Testa hybrid sök, särskilt om dina dokument innehåller identifierare, datum eller andra exakta termer. Och framför allt, acceptera att RAG inte är magi. Det är en ingenjörsdisciplin med kända fallgropar och beprövade lösningar. Skillnaden mellan ett system som fungerar i demo och ett som fungerar i produktion är att någon tog sig tiden att förstå var det kan gå sönder.

Vill ni prata om det här?

Ta en kaffe med oss

Om något här resonerade med er situation, hör av er. Vi sitter gärna ner och pratar om var ni är och vad nästa rimliga steg kunde vara. Inga säljpitchar, bara ett samtal.

Skriv till oss

Nyhetsbrev

EU AI Act, sandbox-status och svensk AI-infrastruktur.

En sammanfattning ungefär en gång i månaden. Vad som förändrats i regelverket, vilka pilot-cases vi sett och vilka vendor-shifts som påverkar svenska bolag. Skickas av oss, inte av en automation som låtsas vara oss.

Uppgifterna används endast för nyhetsbrevet. Inga utskick utöver det utan separat samtycke. Avregistrera när som helst via länk i mailet.