← Portfolio AI Agent Flow →
Interaktiv guide

RAG
Chatbot

Retrieval-Augmented Generation — fra dokumenter til intelligente svar, trin for trin.

Start her ↓
// 01 — definition

Hvad er RAG?

En LLM ved kun det, den er trænet på. RAG løser dette ved at hente relevant information i realtid og give den til modellen som kontekst — ingen genoptræning nødvendig.

R
Retrieval
Find de mest relevante dokumenter fra din vidensbase baseret på brugerens spørgsmål.
A
Augmented
Berig sprogsmodellens prompt med den hentede information som ekstra kontekst.
G
Generation
LLM'en genererer et præcist svar baseret på spørgsmålet OG den hentede kontekst.
// 02 — pipeline

Byg en RAG — trin for trin

Klik på hvert trin for at udforske hvad der sker under motorhjelmen.

Chunking

Dine dokumenter er for store til at passe i én embedding. Vi opdeler dem i overlappende bidder (chunks) — typisk 256–1024 tokens med et overlap på 20–50 tokens.

Overlap sikrer at kontekst ikke mistes ved grænser mellem chunks.

chunk_size = 512 chunk_overlap = 50 splitter = RecursiveCharacterTextSplitter( chunk_size=chunk_size, chunk_overlap=chunk_overlap ) chunks = splitter.split_documents(docs)
Dokument → chunks

Embedding

Hvert chunk sendes igennem en embedding-model, der konverterer teksten til en numerisk vektor — en liste af decimaltal der repræsenterer tekstens semantiske mening.

Semantisk ens tekster får vektorer der ligger tæt på hinanden i det flerdimensionelle rum.

from sentence_transformers import SentenceTransformer model = SentenceTransformer('all-MiniLM-L6-v2') embedding = model.encode("Hvad er RAG?") # → [0.21, -0.83, 0.47, 0.09, ...] # Dimension: 384 tal
Klik for at embedding-e en tekst

Vektordatabase

Alle embeddings gemmes i en specialiseret vektordatabase optimeret til hurtig similarity search — selv over millioner af vektorer.

Populære valg: Pinecone, Chroma, Weaviate, Qdrant.

import chromadb client = chromadb.Client() collection = client.create_collection("docs") collection.add( embeddings=embeddings, documents=chunks, ids=[f"doc_{i}" for i in range(len(chunks))] )
Vektordatabase — lagrede docs

Retrieval

Brugerens spørgsmål embedding'es og vi søger efter de k nærmeste vektorer i databasen via cosine similarity.

De chunks med højest similarity score returneres som relevant kontekst.

query = "Hvad er neural netværk?" query_embedding = model.encode(query) results = collection.query( query_embeddings=[query_embedding], n_results=3 # top-3 chunks ) # Returnerer chunks med similarity scores
Similarity scores for: "neural netværk"

Re-Ranking

Retrieval returnerer f.eks. top-20 chunks via cosine similarity — hurtigt, men upræcist. En re-ranker (cross-encoder) scorer derefter disse 20 chunks igen ved at se spørgsmål og chunk sammen, og vælger de bedste 3–5 videre.

Cross-encodere er langsommere end bi-encodere, men langt mere præcise — derfor bruger man dem kun på den lille kandidatliste.

from sentence_transformers import CrossEncoder reranker = CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2') pairs = [[query, chunk] for chunk in candidate_chunks] scores = reranker.predict(pairs) # Sorter og behold top-3 ranked = sorted(zip(scores, candidate_chunks), reverse=True) top_chunks = [chunk for _, chunk in ranked[:3]]
Før og efter re-ranking
BI-ENCODER → CROSS-ENCODER
#1 Cosine similarity måler... 0.91 #3
#2 Vektordatabaser som Chroma... 0.87 #1
#3 RAG kombinerer informations... 0.83 #2
Cross-encoder ser spørgsmål + chunk samtidigt → mere præcis rangering

Augmentation

De hentede chunks kombineres med brugerens spørgsmål til én augmented prompt — en struktureret besked til LLM'en.

God prompt engineering her er afgørende for kvaliteten af det endelige svar.

prompt = f"""Besvar spørgsmålet baseret kun på den givne kontekst. KONTEKST: {retrieved_chunks} SPØRGSMÅL: {user_question} SVAR:"""
// system: svar kun baseret på kontekst KONTEKST: [ hentede chunks indsættes her... ] SPØRGSMÅL: [ brugerens spørgsmål ] SVAR:

Generation

LLM'en modtager den augmented prompt og genererer et svar. Fordi konteksten er inkluderet, kan modellen svare præcist baseret på din data.

Modellen "hallucinerer" langt sjældnere, når svaret er forankret i konkrete dokumenter.

from openai import OpenAI client = OpenAI() response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": prompt}] ) answer = response.choices[0].message.content # → Præcist svar baseret på dine docs!
RAG vs. ingen RAG
❌ UDEN RAG
"Jeg er ikke sikker... det kunne måske være X, men jeg er ikke opdateret efter min træningsdato."
✓ MED RAG
"Ifølge dokumentet fra 2024 er svaret præcis: [konkret, faktuel information fra din vidensbase]."
// 03 — matematik

Cosine Similarity

Træk i sliders for at justere to vektorer og se hvordan similarity-scoren ændrer sig. Formlen: cos(θ) = (A·B) / (|A|·|B|)

Vektor A
Vektor B
Cosine Similarity
0.86
Meget ens — god match
// 04 — prøv det selv

Mini RAG Demo

En simuleret vidensbase om AI. Stil et spørgsmål og se hvilke dokumenter der matches (highlighted), og hvordan svaret bygges op.

rag-demo.local
📚 Vidensbase (6 docs)
RAG kombinerer informationsgenfinding med tekstgenerering for mere præcise LLM-svar.
Embeddings konverterer tekst til vektorer hvor semantisk ens tekster ligger tæt.
Cosine similarity måler vinklen mellem to vektorer — nærmere 1 = mere ens.
Transformere bruger attention-mekanisme til at forstå kontekst i lange tekster.
Chunking opdeler dokumenter i overlappende bidder på 256-1024 tokens.
Vektordatabaser som Chroma og Pinecone er optimeret til hurtig similarity search.
Hej! Spørg mig om RAG, embeddings, eller AI. Jeg finder svar fra vidensbasen til venstre →
Prøv: "hvad er rag?", "forklar embeddings", "cosine similarity", "hvad er chunking?"