Loading...
Loading...
Loading...
Begriffe und Konzepte, die in den Experiment-Dokumenten verwendet werden.
# Glossar
Begriffe und Konzepte, die in den Experiment-Dokumenten verwendet werden.
Wachst mit den Phasen mit.
---
## Evaluation Dataset (Golden Dataset)
Das Evaluation Dataset (auch "Golden Dataset" oder "Ground Truth") ist die Grundlage
aller Retrieval-Metriken. Es definiert, welche Dokumente fuer eine gegebene Query
als "relevant" gelten. Alle Precision-, Recall-, MRR- und nDCG-Werte sind nur so
aussagekraeftig wie das Dataset, gegen das sie gemessen werden.
### Aufbau
Ein Evaluation Dataset besteht aus Query-Dokument-Paaren:
- **Query:** Eine natuerlichsprachige Frage oder Suchanfrage
- **Expected Sources:** Liste der Dokumente, die als relevant gelten
- **Must-Contain Keywords:** Schluesselwoerter, die in den Ergebnissen vorkommen muessen
- **Reference Chunk Text:** Referenztext fuer semantischen Abgleich
### Qualitaetskriterien
| Kriterium | Beschreibung | Risiko bei Verletzung |
|-----------|-------------|----------------------|
| Abdeckung | Queries decken verschiedene Themen und Schwierigkeitsgrade ab | Blind Spots bei bestimmten Dokumenttypen |
| Vollstaendigkeit | Alle relevanten Dokumente pro Query sind annotiert | Recall wird zu hoch gemessen — nicht-annotierte relevante Docs werden ignoriert |
| Korrektheit | Nur tatsaechlich relevante Dokumente sind markiert | Kuenstlich niedrige Precision (False Positives) |
| Umfang | Genuegend Queries fuer statistisch belastbare Ergebnisse | Zufallsschwankungen dominieren die Metriken |
| Negative Tests | Queries, fuer die keine relevanten Dokumente existieren | System-Robustheit wird nicht geprueft |
### Unser Dataset
`data/evaluation/aws_cert_eval_v1.json`: 53 Queries (50 positive, 3 negative)
ueber AWS Certification Docs. Validierung erfolgt ueber drei Ebenen:
Source Matching (OR) Keyword Matching (OR) Semantic Similarity.
**Einschraenkung:** 53 Queries sind ausreichend fuer relative Vergleiche zwischen
Konfigurationen, aber zu wenig fuer statistisch signifikante Aussagen ueber absolute
Qualitaet. Kleine Aenderungen an wenigen Queries koennen die Metriken um 1-2pp verschieben.
---
## Retrieval-Metriken
### Precision@k
Anteil der relevanten Dokumente unter den Top-k Ergebnissen.
**Formel:** `Precision@k = |relevante Dokumente in Top-k| / k`
**Beispiel:** Bei k=10 werden 10 Dokumente zurueckgegeben. 8 davon sind relevant.
Precision@10 = 8/10 = 0.80
**Interpretation:** Hohe Precision = wenig Rauschen in den Ergebnissen. Wichtig, wenn
jedes zurueckgegebene Dokument dem LLM als Kontext dient und irrelevante Dokumente
die Antwortqualitaet verschlechtern koennen.
### Recall@k
Anteil der gefundenen relevanten Dokumente an allen relevanten Dokumenten im Index.
**Formel:** `Recall@k = |relevante Dokumente in Top-k| / |alle relevanten Dokumente|`
**Beispiel:** Es gibt 12 relevante Dokumente im Index. Bei k=10 werden 9 davon gefunden.
Recall@10 = 9/12 = 0.75
**Interpretation:** Hoher Recall = wenige relevante Dokumente werden verpasst. In RAG-Systemen
besonders kritisch: Was nicht gefunden wird, kann downstream nicht kompensiert werden.
Precision laesst sich durch Reranking verbessern, Recall nicht.
### MRR (Mean Reciprocal Rank)
Durchschnitt des reziproken Rangs des ersten relevanten Ergebnisses ueber alle Queries.
**Formel:** `MRR = (1/N) * sum(1/rank_i)` wobei `rank_i` der Rang des ersten relevanten
Ergebnisses fuer Query i ist.
**Beispiel:**
- Query 1: Erstes relevantes Ergebnis auf Rang 1 -> 1/1 = 1.0
- Query 2: Erstes relevantes Ergebnis auf Rang 3 -> 1/3 = 0.33
- Query 3: Erstes relevantes Ergebnis auf Rang 1 -> 1/1 = 1.0
- MRR = (1.0 + 0.33 + 1.0) / 3 = 0.78
**Interpretation:** MRR nahe 1.0 bedeutet, dass das erste relevante Ergebnis fast immer
auf Rang 1 steht. Besonders wichtig fuer User-facing Systeme, wo der Nutzer das erste
Ergebnis erwartet.
### nDCG@k (Normalized Discounted Cumulative Gain)
Misst die Ranking-Qualitaet: Sind relevante Dokumente hoeher gerankt als irrelevante?
**Idee:** Ein relevantes Dokument auf Rang 1 ist wertvoller als auf Rang 10.
Der "Gain" wird mit zunehmender Position logarithmisch abgewertet ("discounted").
Normalisiert auf [0, 1] durch Division mit dem idealen Ranking.
**Formel:**
```
DCG@k = sum(rel_i / log2(i + 1)) fuer i = 1..k
nDCG@k = DCG@k / IDCG@k (IDCG = DCG des perfekten Rankings)
```
**Beispiel:** Bei k=5 mit Relevanz-Labels [1, 0, 1, 1, 0]:
- DCG = 1/log2(2) + 0/log2(3) + 1/log2(4) + 1/log2(5) + 0/log2(6) = 1.0 + 0 + 0.5 + 0.43 + 0 = 1.93
- Ideales Ranking [1, 1, 1, 0, 0]: IDCG = 1.0 + 0.63 + 0.5 + 0 + 0 = 2.13
- nDCG = 1.93 / 2.13 = 0.91
**Interpretation:** nDCG@k nahe 1.0 bedeutet, dass die relevanten Dokumente optimal
platziert sind. Kombiniert Precision (wie viele sind relevant?) mit Ranking-Qualitaet
(wo stehen sie?). Gilt als beste einzelne Metrik fuer Retrieval-Qualitaet.
### Metriken im Vergleich
| Metrik | Misst | Staerke | Schwaeche |
|--------|-------|---------|-----------|
| Precision@k | Anteil relevanter Ergebnisse | Einfach, intuitiv | Ignoriert Ranking-Reihenfolge |
| Recall@k | Abdeckung aller relevanten Docs | Wichtig fuer RAG-Vollstaendigkeit | Ignoriert Rauschen |
| MRR | Position des ersten Treffers | Gut fuer "brauche nur 1 Ergebnis" | Ignoriert alle weiteren Treffer |
| nDCG@k | Ranking-Qualitaet insgesamt | Beste Gesamtmetrik | Komplexer zu interpretieren |
---
## Chunking
### Recursive Chunking
Teilt Text entlang natuerlicher Grenzen: zuerst Absaetze, dann Saetze, dann Woerter.
Versucht semantisch zusammenhaengende Einheiten zu erhalten.
**Vorteile:** Respektiert Dokumentstruktur, weniger Kontext-Brueche.
**Nachteile:** Ungleichmaessige Chunk-Groessen.
### Fixed Chunking
Teilt Text in Stuecke fester Laenge (in Tokens), unabhaengig von der Textstruktur.
**Vorteile:** Gleichmaessige Chunk-Groessen, konsistentere Embeddings.
**Nachteile:** Kann mitten im Satz oder Absatz trennen.
### Overlap
Anzahl Tokens, die sich zwischen aufeinanderfolgenden Chunks ueberlappen.
Verhindert, dass relevante Informationen an Chunk-Grenzen verloren gehen.
**Typische Werte:** 10-20% der Chunk-Groesse (z.B. 50 bei Chunk Size 512).
---
## Embeddings
### Embedding-Dimension
Laenge des Vektors, den das Embedding-Modell pro Text-Chunk erzeugt.
- **768d** (z.B. BGE-base): Standard-BERT-Groesse. Gut fuer kuerzere Texte.
- **1024d** (z.B. BGE-large, E5-large): Mehr Kapazitaet fuer semantische Nuancen.
Profitiert besonders bei laengeren Chunks (1024+ Tokens), da mehr Kontext
kodiert werden muss.
**Trade-offs:** Hoehere Dimensionen verbessern die Retrieval-Qualitaet, erhoehen aber
auch Embedding-Latenz (groesseres Modell), Speicherverbrauch im Vector Index
(jeder Vektor belegt mehr Bytes) und Search-Latenz (mehr Dimensionen pro
Distanzberechnung). Bei 100k Chunks: 768d ~ 300 MB, 1024d ~ 400 MB (float32).
### BGE (BAAI General Embedding)
Embedding-Modelle von BAAI (Beijing Academy of Artificial Intelligence).
Varianten: bge-base (768d), bge-large (1024d). Typ-Praefix: "bge".
### E5 (EmbEddings from bidirEctional Encoder rEpresentations)
Embedding-Modelle von Microsoft Research. E5-large-v2 hat 1024 Dimensionen.
Typ-Praefix: "e5". Verwendet "[query]"/"[passage]" Praefixe fuer asymmetrische Suche.
---
## Vector Search
### HNSW (Hierarchical Navigable Small World)
Graph-basierter Algorithmus fuer Approximate Nearest Neighbor (ANN) Suche.
Standard-Index in ChromaDB, Qdrant, Weaviate.
**Wichtige Parameter:**
- **ef_construction:** Genauigkeit beim Index-Aufbau (hoeher = genauer, langsamer)
- **M:** Anzahl der Verbindungen pro Knoten (hoeher = genauer, mehr Speicher)
### Cosine Similarity
Aehnlichkeitsmass zwischen zwei Vektoren. Misst den Winkel, nicht die Laenge.
Werte von -1 (entgegengesetzt) bis 1 (identisch). Standard-Metrik fuer Embedding-Suche.
### Dot Product (Skalarprodukt)
Mathematische Operation zwischen zwei Vektoren: `a . b = sum(a_i * b_i)`.
Bei Sparse Vectors werden nur die gemeinsamen Non-Zero-Positionen multipliziert und
aufsummiert. Im Kontext von BM25: Das Dot Product zwischen Query-Sparse-Vector und
Document-Sparse-Vector ergibt den BM25-Score.
**Unterschied zu Cosine Similarity:** Cosine normalisiert auf Vektorlaenge (misst
Richtung), Dot Product beruecksichtigt auch die Laenge (misst Richtung + Magnitude).
---
## Search-Strategien
### Dense Vector Search
Semantische Suche ueber Embedding-Vektoren. Jeder Text wird von einem Embedding-Modell
in einen Dense Vector (vollbesetzter Vektor, alle Dimensionen haben Werte) umgewandelt.
Aehnliche Texte haben aehnliche Vektoren (gemessen via Cosine Similarity).
**Staerken:** Erfasst semantische Aehnlichkeit ("Auto" findet auch "Fahrzeug").
**Schwaechen:** Kann exakte Keyword-Matches verpassen, besonders bei Fachbegriffen
oder Eigennamen die im Training nicht vorkamen.
### Dense Vector
Vollbesetzter Vektor fester Laenge (z.B. 1024 Dimensionen), bei dem jede Position
einen Float-Wert hat. Erzeugt von Embedding-Modellen wie E5-large-v2 oder BGE.
Kodiert die semantische Bedeutung des gesamten Textes.
**Speicher:** 1024d * 4 Bytes (float32) = 4 KB pro Vektor. Bei 150k Chunks: ~600 MB.
### Sparse Vector
Duennbesetzter Vektor mit hoher Dimensionalitaet (Groesse des Vocabulars, z.B. 50.000+),
aber nur wenigen Non-Zero-Eintraegen (typisch 20-100 pro Dokument). Gespeichert als
Paar von `indices` (welche Positionen) und `values` (welche Gewichte).
**Beispiel:** Ein Dokument mit den Termen "Lambda", "serverless", "function" hat einen
Sparse Vector mit 3 Non-Zero-Eintraegen an den Positionen dieser Terme im Vocabulary.
**Speicher:** Nur die Non-Zero-Eintraege werden gespeichert. Bei 50 Termen pro Chunk:
50 * (4 + 4) Bytes = 400 Bytes pro Vektor. Bei 150k Chunks: ~60 MB.
### BM25 (Best Match 25)
Klassischer Keyword-Ranking-Algorithmus (Robertson et al., 1994). Bewertet Dokumente
basierend auf der Uebereinstimmung mit Query-Termen unter Beruecksichtigung von:
1. **Term Frequency (TF):** Wie oft ein Query-Term im Dokument vorkommt.
BM25 verwendet saturierte TF — der Nutzen jedes weiteren Vorkommens nimmt ab:
```
tf_component = tf * (k1 + 1) / (tf + k1 * (1 - b + b * dl / avgdl))
```
- `k1` (default 1.5): Steuert die TF-Saettigung. Hoeher = mehr Gewicht fuer
haeufige Terme. k1=0 ignoriert TF komplett.
- `b` (default 0.75): Steuert die Laengen-Normalisierung. b=1 normalisiert voll,
b=0 ignoriert die Dokumentlaenge.
- `dl`: Dokumentlaenge (Anzahl Tokens)
- `avgdl`: Durchschnittliche Dokumentlaenge im Corpus
2. **Inverse Document Frequency (IDF):** Gewichtung seltener Terme. Je seltener
ein Term im gesamten Corpus vorkommt, desto informativer ist er:
```
IDF(t) = log((N - df(t) + 0.5) / (df(t) + 0.5) + 1)
```
- `N`: Gesamtzahl der Dokumente im Corpus
- `df(t)`: Anzahl der Dokumente, die Term t enthalten
3. **BM25-Score** fuer ein Dokument d und Query q:
```
BM25(d, q) = sum(IDF(t) * tf_component(t, d)) fuer alle t in q
```
**Staerken:** Exzellent bei exakten Keyword-Matches, Fachbegriffen, Eigennamen.
**Schwaechen:** Kein semantisches Verstaendnis ("Auto" findet nicht "Fahrzeug").
**In unserem System:** BM25-Gewichte werden als Sparse Vectors in Qdrant gespeichert.
Document-Vectors enthalten die TF-Komponente (ohne IDF), Query-Vectors enthalten
die IDF-Werte. Das Dot Product ergibt den BM25-Score.
### Named Vectors (Qdrant)
Qdrant-Feature (seit v1.7), das mehrere Vektor-Raeume pro Collection erlaubt.
Jeder Vektor-Raum hat einen Namen und eigene Parameter (Dimension, Distanz-Metrik).
**Beispiel unserer Hybrid-Collection:**
```
Collection: "recursive_1024_100__e5-large-v2__hybrid"
├── "dense": 1024-dim, Cosine Similarity (E5-large-v2 Embeddings)
└── "bm25": Sparse Vector (BM25 TF-Gewichte)
```
Jedes Dokument hat beide Vektoren. Queries koennen gezielt einen Vektor-Raum
ansprechen (`using="dense"` oder `using="bm25"`) oder beide kombinieren.
### Hybrid Search
Kombination aus Dense (semantischer) und Sparse (keyword-basierter) Suche.
Ziel: Die Staerken beider Verfahren vereinen — semantisches Verstaendnis (Dense)
plus exakte Keyword-Matches (Sparse).
**Ablauf in unserem System:**
1. Query an Dense-Index senden → Top-2k Ergebnisse mit Scores
2. Query an Sparse-Index senden → Top-2k Ergebnisse mit Scores
3. Scores normalisieren (Min-Max auf [0,1])
4. Gewichtet kombinieren: `combined = α * dense + (1-α) * sparse`
5. Nach Combined Score sortieren, Top-k zurueckgeben
### Alpha (Hybrid Weight)
Gewichtungsparameter fuer Hybrid Search. Bestimmt das Verhaeltnis zwischen
Dense (semantischer) und Sparse (keyword) Komponente.
| Alpha | Dense-Anteil | Sparse-Anteil | Beschreibung |
|-------|-------------|---------------|-------------|
| 1.0 | 100% | 0% | Pure Dense (= reine semantische Suche) |
| 0.7 | 70% | 30% | Semantik-dominant |
| 0.5 | 50% | 50% | Ausgeglichen |
| 0.3 | 30% | 70% | Keyword-dominant |
| 0.0 | 0% | 100% | Pure Sparse (= reines BM25) |
**Intuition:** Fuer Fachdomaenen mit spezifischen Begriffen (wie AWS-Zertifizierungen)
kann ein Keyword-Anteil helfen, exakte Service-Namen und Fachbegriffe zuverlaessiger
zu finden, waehrend die semantische Komponente konzeptuelle Aehnlichkeiten abdeckt.
### Score Fusion
Zusammenfuehrung der Ergebnisse aus zwei (oder mehr) Suchverfahren zu einer
einheitlichen Ranking-Liste.
**Alpha-Blending (score-basiert):** Normalisiert die Scores beider Verfahren auf
[0,1] und gewichtet sie: `α * score_A + (1-α) * score_B`. Erfordert Score-Normalisierung,
da Dense (0-1) und Sparse (0-30+) unterschiedliche Skalen haben.
**RRF (Reciprocal Rank Fusion):** Rang-basierte Alternative: `score = sum(1 / (k + rank_i))`.
Kein Alpha-Parameter, behandelt alle Quellen gleich. Unabhaengig von Score-Skalen,
aber keine Gewichtung moeglich.
**Unsere Wahl:** Alpha-Blending, weil wir den Einfluss von Dense vs. Sparse
experimentell steuern und vergleichen wollen.
### Min-Max Normalisierung
Skalierung von Werten auf den Bereich [0, 1]:
```
normalized = (x - min) / (max - min)
```
Noetig fuer Score Fusion, da die Rohscores aus verschiedenen Suchverfahren
unterschiedliche Skalen haben:
- Dense (Cosine Similarity): typisch 0.3 - 0.95
- Sparse (BM25 Dot Product): typisch 0 - 30+
Nach Normalisierung sind beide auf [0, 1] und koennen gewichtet kombiniert werden.
**Edge Case:** Wenn alle Scores gleich sind (`max = min`), werden alle auf 1.0 gesetzt.
---
## Reranking
### Reranking (Second-Stage Scoring)
Nachbearbeitung der initialen Retrieval-Ergebnisse durch ein praeziseres Modell.
Das Retrieval (Stage 1) liefert schnell eine Kandidatenliste (z.B. Top-100 aus 150k),
der Reranker (Stage 2) bewertet diese Kandidaten genauer und sortiert sie neu.
**Auswirkung auf Metriken:**
- Verbessert **Precision** (irrelevante Ergebnisse werden nach unten sortiert)
- Verbessert **nDCG und MRR** (besseres Ranking relevanter Ergebnisse)
- Verbessert **nicht den Recall** — was im Retrieval nicht gefunden wurde, kann der
Reranker nicht hinzufuegen. Deshalb ist Over-Retrieval (mehr Kandidaten holen als
final benoetigt) entscheidend.
### Bi-Encoder
Modell, das Query und Dokument **unabhaengig** kodiert — je ein separates Embedding.
Die Aehnlichkeit wird ueber Vektoroperationen berechnet (z.B. Cosine Similarity).
**Vorteile:** Dokument-Embeddings koennen vorberechnet und in einem Vector Index
gespeichert werden. Suche ueber 150k Chunks in Millisekunden (ANN-Algorithmen).
**Nachteile:** Die unabhaengige Kodierung kann feine Interaktionen zwischen Query-
und Dokument-Termen nicht erfassen.
**In unserem System:** E5-large-v2 (Phase 2) ist ein Bi-Encoder fuer Retrieval.
### Cross-Encoder
Modell, das Query und Dokument **gemeinsam** kodiert — beide werden als Paar
konkateniert und durch einen Transformer geschickt. Das Modell kann Interaktionen
zwischen Query- und Dokument-Termen direkt modellieren.
**Vorteile:** Deutlich genauer als Bi-Encoder, da das Modell sehen kann, welche
Query-Terme im Dokument vorkommen und in welchem Kontext.
**Nachteile:** O(n) teuer — jedes (Query, Dokument)-Paar braucht einen separaten
Forward Pass. Bei 100 Kandidaten = 100 Inference Calls pro Query. Deshalb nur als
Reranker fuer vorselektierte Kandidaten einsetzbar, nicht fuer Full-Index-Suche.
**Typische Architektur:** `AutoModelForSequenceClassification` (z.B. BGE-reranker-v2-m3).
Input: `[CLS] query [SEP] document [SEP]` → Output: Relevanz-Score.
### Bi-Encoder vs. Cross-Encoder
Das Standard-Pattern in modernen RAG-Systemen:
```
Full Index (150k Chunks)
|
v Bi-Encoder (schnell, O(1) via ANN)
Top-100 Kandidaten
|
v Cross-Encoder (genau, O(n))
Top-5 Ergebnisse
|
v LLM (Synthesis)
Antwort
```
Der Bi-Encoder filtert schnell den Grossteil irrelevanter Dokumente weg.
Der Cross-Encoder optimiert das Ranking der verbleibenden Kandidaten.
Dieses zweistufige Verfahren kombiniert die Geschwindigkeit des Bi-Encoders
mit der Genauigkeit des Cross-Encoders.
### Generativer Reranker
Reranker auf Basis eines Language Models (z.B. Qwen2, Qwen3). Bewertet Relevanz
durch Token-Generierung statt Sequence Classification.
**Typischer Ansatz:** Das Modell erhaelt Query + Dokument als Chat-Prompt und
entscheidet, ob das Dokument relevant ist. Der Score ist die Wahrscheinlichkeit
des "yes"-Tokens relativ zum "no"-Token.
**Unterschied zum Cross-Encoder:** Cross-Encoder haben einen dedizierten
Classification-Head (lineare Schicht). Generative Reranker nutzen den
Language-Modeling-Head und extrahieren Scores aus Token-Wahrscheinlichkeiten.
**Beispiele:** Mixedbread mxbai-rerank-v2 (Qwen2-basiert), Qwen3-Reranker.
### Over-Retrieval (retrieve_k)
Strategie, bei der mehr Kandidaten aus dem Index geholt werden als final benoetigt,
um dem Reranker eine breitere Auswahl zu geben.
**Beispiel:** Fuer k=5 finale Ergebnisse werden retrieve_k=100 Kandidaten geholt.
Der Reranker bewertet alle 100 und gibt die 5 besten zurueck.
**Typische Verhaeltnisse:** 3-20x des finalen k. Zu wenige Kandidaten limitieren
den Reranker, zu viele erhoehen die Latenz (besonders bei LLM-basierten Rerankern).
**In unserem System:** `--retrieve-k 100` (CLI-Parameter in `run_eval.py`).
---
## Response Synthesis
### Response Synthesis
LLM generiert aus Retrieved Chunks eine natuerlichsprachige Antwort. Verschiedene
Modi bestimmen, wie die Chunks dem LLM praesentiert werden. Der Modus beeinflusst
Qualitaet, Latenz und Token-Verbrauch.
### Response Mode: tree_summarize
Hierarchische Zusammenfassung: Chunks werden paarweise zusammengefasst, die
Zusammenfassungen wieder zusammengefasst → finale Antwort. Benoetigt mehrere
LLM-Calls (O(log n)), liefert aber die beste Qualitaet bei vielen Chunks, da
jeder Chunk beruecksichtigt wird.
### Response Mode: refine
Iteratives Verfeinern: Erster Chunk → erste Antwort. Jeder weitere Chunk
verfeinert die Antwort. N LLM-Calls (N = Anzahl Chunks). Gut wenn die
Reihenfolge der Chunks eine Rolle spielt.
### Response Mode: compact
Fuegt moeglichst viele Chunks in einen Prompt (bis Context-Window-Grenze).
Typisch 1-2 LLM-Calls. Schneller und guenstiger, aber weniger gruendlich bei
vielen Chunks.
### Temperature
Sampling-Parameter des LLMs. Steuert, wie deterministisch oder kreativ die
Antworten sind.
| Wert | Effekt | Empfehlung |
|------|--------|-----------|
| 0.0 | Deterministisch (immer der wahrscheinlichste Token) | Faktische Antworten |
| 0.3 | Leichte Variation | Guter Kompromiss |
| 0.7+ | Kreativ/zufaellig | Nicht fuer RAG empfohlen |
Fuer RAG-Systeme mit faktischen Antworten: 0.0-0.3 empfohlen.
---
## Synthesis-Metriken
### Faithfulness (LLM-as-Judge)
Misst, ob die Antwort ausschliesslich auf den Source-Chunks basiert (keine
Erfindungen). LLM-as-Judge: Ein Evaluator-LLM prueft jeden Claim in der
Antwort gegen die Quellentexte.
**Werte:** 0.0 (alle Claims frei erfunden) bis 1.0 (alle Claims belegbar).
**Status:** Implementiert in `LLMMetrics.faithfulness()`. In Phase 6 nicht
aufgerufen (Embedding-basierte Metriken stattdessen). Ab Phase 7 aktivierbar
via `--enable-faithfulness` Flag. Verwendet Claude Haiku 4.5 als Evaluator.
### LLM-as-Judge
Evaluationsansatz, bei dem ein LLM die Qualitaet eines anderen LLM-Outputs
bewertet. Skalierbar und automatisierbar — keine manuellen Annotationen noetig.
**Risiko:** Self-Evaluation Bias — ein Modell bewertet sich selbst wohlwollender.
Deshalb: Anderes Modell als Evaluator verwenden (z.B. Claude Haiku 4.5 evaluiert
GPT-4o-mini Outputs).
**In Phase 6:** LLM-as-Judge (Faithfulness) war geplant, wurde aber zugunsten
deterministischer Embedding-basierter Metriken zurueckgestellt.
### Answer Relevance (Embedding-basiert)
Semantische Aehnlichkeit zwischen Query und Antwort, gemessen als Embedding
Cosine Similarity. Ein hoher Wert bedeutet, dass die Antwort die Frage tatsaechlich
adressiert, nicht nur verwandtes Material enthaelt.
**Methode:** Query-Embedding vs. Response-Embedding via E5-large-v2.
**Typ:** Deterministisch, kein LLM-Call.
### Hallucination Score (Embedding-basiert)
Per-Sentence Embedding-Vergleich der Antwort gegen alle Source-Chunks. Jeder Satz
der Antwort wird als Embedding kodiert und gegen die Source-Chunk-Embeddings
verglichen. Saetze mit niedriger Aehnlichkeit zu allen Quellen sind potentiell
halluziniert.
**Werte:** 0.0 (starke Halluzination) bis 1.0 (keine Halluzination erkannt).
**Typ:** Deterministisch, kein LLM-Call. Komplementaer zu Faithfulness — misst
denselben Aspekt (Quellentreue), aber Embedding-basiert statt LLM-basiert.
### Keyword Coverage (Rule-based, Custom)
Anteil der erwarteten Schluesselwoerter (`must_contain_keywords` aus dem
Eval-Dataset) in der generierten Antwort. Custom-Metrik fuer dieses Projekt,
da das Eval-Dataset keine Reference Answers hat, aber Keywords pro Query definiert.
**Formel:** `keyword_coverage = |gefundene Keywords| / |erwartete Keywords|`
**Methode:** Case-insensitive Substring-Match.
**Beispiel:** Keywords = ["SageMaker", "machine learning", "managed service"].
Antwort enthaelt "SageMaker" und "machine learning" → Coverage = 2/3 = 0.67.
**Einordnung:** Praxisnaeher als rein semantische Metriken, weil konkrete Fakten
geprueft werden. Gleichzeitig limitiert: Synonyme und Umschreibungen werden nicht
erkannt ("fully managed" matcht nicht auf "managed service").
### Source Attribution (Embedding-basiert)
Misst, welche Source-Chunks tatsaechlich in die Antwort eingeflossen sind.
Embedding-Similarity zwischen Antwort und jedem Source-Chunk.
**Werte:** `attribution_rate` von 0.0 (keine Quellen genutzt) bis 1.0 (alle
Quellen beigetragen). Ein hoher Wert bedeutet, dass das LLM die bereitgestellten
Quellen effektiv nutzt statt eigenes Wissen einzusetzen.
**Typ:** Deterministisch, kein LLM-Call.
### Latenz-Percentile (p50, p95, p99)
Statistische Verteilungsmasse fuer Antwortzeiten ueber alle Queries:
| Percentil | Bedeutung |
|-----------|-----------|
| p50 (Median) | 50% der Queries sind schneller |
| p95 | 95% der Queries sind schneller (Tail Latency) |
| p99 | 99% der Queries sind schneller (Worst Case) |
**Warum nicht nur avg?** Der Durchschnitt verschleiert Ausreisser. p95/p99 zeigen,
wie das System unter Last performt. Fuer User-facing Systeme ist p95 oft die
relevantere Metrik als avg.
### Quality Composite Score
Gewichteter Score aus allen Synthesis-Metriken. Normalisiert auf [0, 1].
**Gewichte (mit Faithfulness):**
- Answer Relevance: 35%
- Keyword Coverage: 25%
- Source Attribution: 20%
- Hallucination Penalty (1 - halluc_score): 10%
- Faithfulness: 10%
**Ohne Faithfulness:** Relevance 40%, Keywords 25%, Attribution 20%, Halluc 15%.
### Cost Efficiency
Verhaeltnis von Qualitaet zu Kosten: `quality_score / total_cost_usd`.
Hoeher = besseres Preis-Leistungs-Verhaeltnis.
---
## LLM Hosting
### vLLM
Open-Source LLM Inference Engine. Hostet Open-Source Modelle auf eigener GPU-
Infrastruktur mit OpenAI-kompatibler API. Statt Token-basierter Abrechnung
zahlt man nur die GPU-Compute-Zeit.
**Key Features:**
- PagedAttention fuer effiziente KV-Cache-Verwaltung
- Continuous Batching fuer hohen Durchsatz
- Tensor Parallelism fuer grosse Modelle ueber mehrere GPUs
- OpenAI-kompatible API (`/v1/chat/completions`)
**In unserem System:** vLLM wird als Kubernetes Deployment auf GPU-Nodes
betrieben. Das Modell wird via `--served-model-name` konfiguriert und ueber
einen internen Service (`vllm-svc.ml-models.svc.cluster.local:8000`) erreichbar.
**Wichtig:** Der Service heisst `vllm-svc` (nicht `vllm`), weil Kubernetes bei
einem Service namens `vllm` automatisch `VLLM_PORT=tcp://...` injiziert, was mit
vLLMs eigenem `VLLM_PORT` Env-Var kollidiert.
### GPU-Time Pricing
Kostenmodell fuer self-hosted LLMs. Statt Token-basierter Abrechnung (wie bei
OpenAI) wird die GPU-Nutzungsdauer berechnet:
```
cost = latency_ms / 1000 / 3600 * gpu_hourly_rate
```
**Beispiel:** 500ms Inferenz auf g6.xlarge ($0.98/h):
`0.5 / 3600 * 0.98 = $0.000136` pro Query
**Vorteil:** Kosten skalieren mit Inferenz-Zeit, nicht mit Token-Anzahl.
Grosse Prompts sind nicht teurer als kleine (bei gleicher Inferenz-Zeit).
### Tensor Parallelism (TP)
Verteilung eines Modells auf mehrere GPUs, indem die Gewichtsmatrizen entlang
der Spalten/Zeilen aufgeteilt werden. Jede GPU haelt nur einen Teil des Modells.
**Wann noetig:** Wenn das Modell nicht auf eine einzelne GPU passt.
- 70B-Q4 (~35GB) passt nicht auf 1x A10G (24GB), aber auf 4x A10G (96GB) mit TP=4
- 27B/32B BF16 passen auf 1x L40S (48GB) ohne TP
**Overhead:** TP erfordert inter-GPU-Kommunikation bei jedem Transformer-Layer.
1x L40S ohne TP ist deshalb oft schneller als 4x A10G mit TP=4 fuer Modelle
die auf eine GPU passen.
### Quantisierung (AWQ, GPTQ)
Reduktion der Gewichtspräzision von BF16/FP16 (16 Bit) auf INT4 (4 Bit).
Halbiert den VRAM-Bedarf bei minimalem Qualitaetsverlust.
**AWQ (Activation-aware Weight Quantization):**
Quantisiert Gewichte asymmetrisch, behaelt wichtige Gewichte (basierend auf
Aktivierungsverteilung) in hoeherer Praezision. Nativ von vLLM unterstuetzt.
**GPTQ (GPT Quantization):**
Aeltere Methode, quantisiert Gewichte per Layer mit Fehlerkorrektur.
Ebenfalls nativ von vLLM unterstuetzt.
**TorchAO:**
PyTorch-natives Quantisierungsformat. Benoetigt `torchao>=0.10.0` — in vLLM
v0.14 nicht vorinstalliert. Modelle mit TorchAO-Quantisierung (z.B.
`pytorch/gemma-3-27b-it-AWQ-INT4`) funktionieren nicht out-of-the-box.
**Praxiserfahrung aus Phase 7:**
| Modell | BF16 VRAM | Quantisiert | VRAM (est.) | GPU |
|--------|-----------|-------------|-------------|-----|
| Phi-4 (14B) | ~28GB | AWQ-INT4 | ~8GB | L4 (24GB) |
| Gemma-3-27B | ~54GB | GPTQ-INT4 | ~14GB | L40S (48GB) |
| Qwen3-32B | ~64GB | AWQ | ~16GB | L40S (48GB) |
Ohne Quantisierung passen Mid-Tier Modelle (27B, 32B) nicht auf einzelne GPUs.
Quantisierung ist in der Praxis nicht optional, sondern Voraussetzung.
### Thinking Mode (Qwen3)
Qwen3-Modelle generieren standardmaessig `<think>...</think>` Reasoning-Tokens
vor der eigentlichen Antwort. Dies fuehrt zu massiv erhoehter Latenz
(~21s/Query fuer 8B auf L4 statt erwarteter ~2-3s).
**Auswirkung auf Qualitaet:** Trotz hoher Latenz liefert Qwen3 die beste
Keyword Coverage (0.929 bei 32B-AWQ) — die Thinking-Tokens scheinen die
Antwortqualitaet tatsaechlich zu verbessern.
**`--override-generation-config '{"enable_thinking": false}'` hat das Problem
in unseren Tests NICHT behoben.** Die Latenz blieb unveraendert.
---
## End-to-End Evaluation (Phase 8)
### Naive Baseline
Die absichtlich unoptimierte Referenz-Pipeline, die als Ausgangspunkt dient.
Alle Komponenten auf Default-/Einsteiger-Einstellungen:
- Chunking: `fixed_256_25` (feste 256-Token-Chunks, 25 Token Overlap)
- Embedding: `bge-base-en-v1.5` (768 Dimensionen)
- VectorDB: ChromaDB (In-Process)
- Search: Dense
- Reranking: None
### Per-Layer Impact Ranking
Methode zur Quantifizierung des Beitrags jeder Optimierungsschicht.
Vergleicht die Retrieval-Metriken (MRR, nDCG, Precision, Recall) vor und
nach jeder Phase-Optimierung. Sortiert nach absolutem Delta der
primaeren Metrik (z.B. MRR).
### Cost-at-Volume Modelling
Kostenprojektion fuer verschiedene Query-Volumina (100/1k/10k/100k pro Monat):
- **API-Kosten:** `cost_per_query * volume` (aus Phase 7 Eval-Ergebnissen)
- **GPU-Kosten:** `(avg_ms / 3_600_000) * gpu_hourly_rate * volume`
Erkenntnis aus Phase 8: GPT-4o-mini ($0.00025/Query) ist pro Query guenstiger
als Self-Hosted Qwen3-8B auf L4 ($0.006/Query bei 21s Latenz durch Thinking-Mode).
Der GPU-Vorteil liegt bei Datenschutz und Qualitaet, nicht bei Kosten.
This roadmap outlines planned enhancements to transform cheap-RAG from a functional document retrieval system into a production-ready, state-of-the-art RAG framework. Priorities are based on impact vs. effort analysis and alignment with mainstream RAG best practices.
See `specs/Semblance-MVP-Plan-v2.md` for full technical specification.
All notable changes to AvocadoDB will be documented in this file.
**Goal:** Stand up Toasty as a reliable service wired to BLT/GitHub events; deliver safe, useful summaries early.