7. OptimizationExperte

RAG-Systeme testen: Die 5-Schritte-Methodik die Google nutzt (Und Sie auch sollten)

28. August 2026
22 Min. Lesezeit
Ailog Team

Vollstaendige Methodik zum Testen von RAG-Systemen in 5 Schritten: Golden Dataset, Retrieval-Unit-Tests, Generierungstests, End-to-End-RAGAS-Bewertung, A/B-Tests in der Produktion.

TL;DR

Ein RAG-System zu testen bedeutet nicht nur "sieht die Antwort richtig aus". Google, Anthropic und die besten KI-Teams folgen einer 5-Schritte-Methodik: (1) Golden Dataset erstellen, (2) Retrieval einzeln testen, (3) Generierung einzeln testen, (4) End-to-End-Bewertung mit RAGAS, (5) A/B-Tests in der Produktion. Dieser Leitfaden beschreibt jeden Schritt mit Code, konkreten Metriken und zu vermeidenden Fallstricken.


Warum 90% der RAG-Systeme in der Produktion scheitern

Die meisten Teams testen ihr RAG, indem sie manuell ein paar Fragen stellen. Das ist, als wuerde man ein Auto testen, indem man schaut, ob es anspringt. Die echten Probleme erscheinen nach dem Deployment:

ProblemHaeufigkeitAuswirkung
Unerkannte Halluzinationen15-30% der AntwortenVertrauensverlust der Nutzer
Themenfremdes Retrieval20-40% der AbfragenIrrelevante Antworten
Regression nach UpdatesBei jedem DeploymentStille Verschlechterung
BestaetigungsfehlerPermanentFalsches Qualitaetsgefuehl

Die Loesung: eine systematische, automatisierte und reproduzierbare Testmethodik.


Schritt 1: Golden Dataset erstellen

Das Golden Dataset ist Ihre Quelle der Wahrheit. Es ist eine Sammlung von Frage-Antwort-Kontext-Paaren, die von menschlichen Experten validiert wurden.

Struktur des Golden Datasets

DEVELOPERjson
{ "id": "GD-001", "question": "Wie sind die Lieferzeiten in Deutschland?", "expected_answer": "Die Lieferzeiten in Deutschland betragen 2-5 Werktage fuer den Standardversand und 24 Stunden fuer den Expressversand.", "expected_contexts": [ "doc_versand_deutschland.md#lieferzeiten", "faq_versand.md#frage-12" ], "category": "logistics", "difficulty": "easy", "metadata": { "created_by": "support_team", "created_at": "2026-01-15", "last_validated": "2026-03-01" } }

Wie viele Paare brauchen Sie?

KorpusgroesseEmpfohlenes Golden DatasetAbdeckung
< 100 Dokumente50 Paare1 Paar / 2 Docs
100-1000 Docs100-200 PaareHauptkategorien
1000-10000 Docs200-500 PaareGeschichtete Stichprobe
> 10000 Docs500-1000 PaareKategorien + Randfaelle

Golden Dataset halbautomatisch generieren

DEVELOPERpython
from openai import OpenAI import json client = OpenAI() def generate_golden_pairs(documents: list[dict], n_pairs: int = 5) -> list[dict]: """Generiert Q&A-Paare aus echten Dokumenten.""" golden_pairs = [] for doc in documents: prompt = f"""Generiere aus dem folgenden Dokument {n_pairs} Frage-Antwort-Paare. Dokument: {doc['content'][:3000]} Regeln: - Vielfaeltige Fragen (faktisch, vergleichend, Ja/Nein) - Antworten basierend NUR auf dem Dokument - Genauen Quellabschnitt angeben JSON-Format: [{{"question": "...", "answer": "...", "source_section": "..."}}]""" response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": prompt}], response_format={"type": "json_object"} ) pairs = json.loads(response.choices[0].message.content) for pair in pairs.get("pairs", []): golden_pairs.append({ "question": pair["question"], "expected_answer": pair["answer"], "expected_contexts": [f"{doc['id']}#{pair['source_section']}"], "category": doc.get("category", "general"), "auto_generated": True, "validated": False # Muss von Mensch geprueft werden }) return golden_pairs # Verwendung documents = [ {"id": "doc_001", "content": "...", "category": "product"}, {"id": "doc_002", "content": "...", "category": "support"}, ] golden = generate_golden_pairs(documents, n_pairs=5) print(f"{len(golden)} Paare generiert - PRUEFUNG ERFORDERLICH")

Menschliche Validierung: Die Dreier-Regel

Jedes Golden-Dataset-Paar muss von mindestens 1 Person validiert werden. Fuer kritische Systeme (medizinisch, juristisch) verwenden Sie die Dreier-Regel: 3 unabhaengige Validatoren, Mehrheit erforderlich.


Schritt 2: Retrieval einzeln testen

Retrieval ist die kritischste Komponente. Wenn die falschen Dokumente abgerufen werden, kann kein LLM eine gute Antwort generieren.

Wichtige Metriken

MetrikFormelZielInterpretation
Recall@kRelevante Docs in Top-k / Gesamt relevant> 0,85"Wir finden die richtigen Docs"
Precision@kRelevante Docs in Top-k / k> 0,60"Gefundene Docs sind gut"
MRR1 / Rang des ersten relevanten Docs> 0,70"Richtiges Doc ist oben"
nDCG@kNormalisierter DCG-Score> 0,75"Ranking ist korrekt"
Hit RateAbfragen mit mind. 1 relevantem Doc / Gesamt> 0,90"Wir finden immer etwas"

Retrieval-Testcode

DEVELOPERpython
import numpy as np from dataclasses import dataclass @dataclass class RetrievalResult: query: str retrieved_docs: list[str] relevant_docs: list[str] def recall_at_k(result: RetrievalResult, k: int = 10) -> float: """Recall@k - Anteil der abgerufenen relevanten Dokumente.""" retrieved_set = set(result.retrieved_docs[:k]) relevant_set = set(result.relevant_docs) if not relevant_set: return 1.0 return len(retrieved_set & relevant_set) / len(relevant_set) def precision_at_k(result: RetrievalResult, k: int = 10) -> float: """Precision@k - Anteil der abgerufenen Dokumente, die relevant sind.""" retrieved = result.retrieved_docs[:k] relevant_set = set(result.relevant_docs) if not retrieved: return 0.0 return sum(1 for doc in retrieved if doc in relevant_set) / len(retrieved) def mrr(result: RetrievalResult) -> float: """Mean Reciprocal Rank - Kehrwert des Rangs des ersten relevanten Ergebnisses.""" relevant_set = set(result.relevant_docs) for i, doc in enumerate(result.retrieved_docs): if doc in relevant_set: return 1.0 / (i + 1) return 0.0 def evaluate_retrieval(golden_dataset: list[dict], retriever) -> dict: """Bewertet das Retrieval auf dem vollstaendigen Golden Dataset.""" metrics = {"recall@5": [], "recall@10": [], "precision@5": [], "mrr": [], "hit_rate": []} for item in golden_dataset: retrieved = retriever.search(item["question"], top_k=10) result = RetrievalResult( query=item["question"], retrieved_docs=[doc.id for doc in retrieved], relevant_docs=item["expected_contexts"] ) metrics["recall@5"].append(recall_at_k(result, 5)) metrics["recall@10"].append(recall_at_k(result, 10)) metrics["precision@5"].append(precision_at_k(result, 5)) metrics["mrr"].append(mrr(result)) metrics["hit_rate"].append(1.0 if recall_at_k(result, 10) > 0 else 0.0) return {k: np.mean(v) for k, v in metrics.items()}

Qualitaetsschwellenwerte

MetrikMindestens akzeptabelGutAusgezeichnet
Recall@100,750,850,95+
Precision@50,500,650,80+
MRR0,600,750,85+
Hit Rate0,800,900,95+

Schritt 3: Generierung einzeln testen

Selbst bei perfektem Retrieval kann das LLM halluzinieren, den Kontext ignorieren oder themenfremde Antworten generieren.

Generierungsmetriken

MetrikMisstMethode
FaithfulnessAntwort ist dem Kontext treuLLM-als-Richter
Answer RelevancyAntwort adressiert die FrageLLM-als-Richter
Answer CorrectnessAntwort entspricht dem GoldenCosinus-Aehnlichkeit + LLM
HarmfulnessIst die Antwort schaedlichKlassifikation

Treuetest mit LLM-als-Richter

DEVELOPERpython
from openai import OpenAI client = OpenAI() def evaluate_faithfulness(context: str, answer: str) -> dict: """Bewertet, ob die Antwort dem bereitgestellten Kontext treu ist.""" prompt = f"""Bewerte, ob die folgende Antwort dem bereitgestellten Kontext treu ist. KONTEXT: {context} ANTWORT: {answer} Analysiere jede Behauptung in der Antwort: 1. Wird die Behauptung durch den Kontext gestuetzt? (supported/unsupported) 2. Gibt es erfundene Informationen? (hallucination: yes/no) Treue-Score (0.0 bis 1.0) = gestuetzte Behauptungen / Gesamtbehauptungen Antworte als JSON: {{"claims": [{{"text": "...", "supported": true/false}}], "faithfulness_score": 0.X, "hallucinations": ["..."]}}""" response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": prompt}], response_format={"type": "json_object"} ) return json.loads(response.choices[0].message.content)

Schritt 4: End-to-End-Bewertung mit RAGAS

RAGAS (Retrieval Augmented Generation Assessment) ist das Referenz-Framework zur Bewertung einer vollstaendigen RAG-Pipeline.

Installation und Verwendung

DEVELOPERpython
from ragas import evaluate from ragas.metrics import ( faithfulness, answer_relevancy, context_precision, context_recall, answer_correctness ) from datasets import Dataset # Daten vorbereiten data = { "question": [], "answer": [], "contexts": [], "ground_truth": [] } for item in golden_dataset: # RAG-Pipeline ausfuehren rag_result = rag_pipeline.query(item["question"]) data["question"].append(item["question"]) data["answer"].append(rag_result.answer) data["contexts"].append(rag_result.contexts) data["ground_truth"].append(item["expected_answer"]) dataset = Dataset.from_dict(data) # RAGAS-Bewertung results = evaluate( dataset, metrics=[ faithfulness, answer_relevancy, context_precision, context_recall, answer_correctness ] ) print(results) # {'faithfulness': 0.87, 'answer_relevancy': 0.91, # 'context_precision': 0.78, 'context_recall': 0.85, # 'answer_correctness': 0.82}

Vergleich der Bewertungs-Frameworks

FrameworkMetrikenLLM-als-RichterOpen-SourceEinfachheitProduktionsreif
RAGAS8+JaJaEinfachJa
DeepEval14+JaJaMittelJa
TruLens6+JaJaEinfachJa
Phoenix (Arize)10+JaJaMittelJa
LangSmithCustomJaNeinEinfachJa
BraintrustCustomJaNeinEinfachJa

RAGAS vs DeepEval: Detaillierter Vergleich

KriteriumRAGASDeepEval
RAG-MetrikenAusgezeichnetAusgezeichnet
Benutzerdefinierte MetrikenBegrenztFlexibel
CI/CD-IntegrationUeber PythonNatives pytest-Plugin
DashboardNein (JSON-Export)Ja (Confident AI)
LLM-Kosten~$0,05/Bewertung~$0,08/Bewertung
CommunityGrossWachsend

Schritt 5: A/B-Tests in der Produktion

Offline-Metriken reichen nicht aus. Der echte Test ist die Produktion.

Produktionsmetriken

MetrikQuelleZiel
Quellen-KlickrateFrontend> 30%
Daumen hoch/runter VerhaeltnisFrontend> 80% hoch
Menschliche EskalationsrateBackend< 20%
Durchschnittliche SitzungsdauerAnalyticsStabil oder wachsend
RueckkehrrateAnalytics> 40%
Abfragen ohne AntwortBackend< 5%

A/B-Test-Implementierung

DEVELOPERpython
import hashlib from datetime import datetime class RAGABTest: def __init__(self, variant_a, variant_b, traffic_split: float = 0.5): self.variant_a = variant_a # RAG-Pipeline v1 self.variant_b = variant_b # RAG-Pipeline v2 self.traffic_split = traffic_split self.results = {"a": [], "b": []} def get_variant(self, user_id: str) -> str: """Deterministische Zuweisung basierend auf user_id.""" hash_val = int(hashlib.md5(user_id.encode()).hexdigest(), 16) return "a" if (hash_val % 100) < (self.traffic_split * 100) else "b" async def query(self, question: str, user_id: str) -> dict: variant = self.get_variant(user_id) pipeline = self.variant_a if variant == "a" else self.variant_b start_time = datetime.now() result = await pipeline.query(question) latency = (datetime.now() - start_time).total_seconds() self.results[variant].append({ "question": question, "answer": result.answer, "latency": latency, "variant": variant, "timestamp": datetime.now().isoformat() }) return { "answer": result.answer, "sources": result.sources, "variant": variant }

Minimale A/B-Testdauer

Taegliches AbfragevolumenMindestdauerErforderliche Stichprobe
< 1004 Wochen~2.800 Abfragen
100-1.0002 Wochen~7.000 Abfragen
1.000-10.0001 Woche~7.000 Abfragen
> 10.0003-5 Tage~15.000 Abfragen

CI/CD-Integration

GitHub Actions fuer RAG-Tests

DEVELOPERyaml
# .github/workflows/rag-tests.yml name: RAG Quality Tests on: push: branches: [develop, main] paths: - 'backend/rag/**' - 'backend/prompts/**' - 'tests/golden_dataset.json' jobs: rag-evaluation: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install dependencies run: pip install ragas deepeval openai - name: Run retrieval tests run: python tests/test_retrieval.py env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} QDRANT_URL: ${{ secrets.QDRANT_TEST_URL }} - name: Run RAGAS evaluation run: python tests/test_ragas.py --threshold 0.80 - name: Check thresholds run: | python -c " import json with open('tests/results/ragas_scores.json') as f: scores = json.load(f) assert scores['faithfulness'] >= 0.80 assert scores['answer_relevancy'] >= 0.75 assert scores['context_recall'] >= 0.80 print('Alle RAG-Qualitaetsschwellenwerte bestanden') "

Die 7 haeufigsten Fallstricke

FallstrickAuswirkungLoesung
Golden Dataset zu kleinFalsches QualitaetsgefuehlMindestens 100 Paare, ausgewogene Kategorien
Keine RegressionstestsStille VerschlechterungCI/CD mit automatischen Schwellenwerten
Nur Generierung bewertenFehlschlagendes Retrieval wird uebersehenRetrieval UND Generierung testen
Gleiches LLM zur BewertungBestaetigungsfehlerAnderes LLM als Richter verwenden
Randfaelle ignorierenProduktionsausfaelle20% Randfaelle im Golden einbeziehen
Metriken ohne GeschaeftskontextFalsches Ziel optimierenAn Geschaefts-KPIs anknuepfen
Einmaliger TestVariabilitaet ignoriert3x ausfuehren, Median nehmen

Unser Ansatz bei Ailog

Bei Ailog wird jede Kunden-RAG-Pipeline automatisch getestet:

  1. Golden Dataset: Halbautomatisch aus Kundendokumenten generiert, von unserem Team validiert
  2. Retrieval-Tests: Recall@10 > 0,85 vor dem Deployment erforderlich
  3. RAGAS-Tests: Faithfulness > 0,80, Relevancy > 0,75
  4. Produktions-Monitoring: Automatische Alarme bei Daumen-runter > 20%

Entdecken Sie, wie wir unsere RAG-Systeme bewerten und wie wir in der Produktion monitoren.

FAQ

Die Bewertung mit LLM-als-Richter (RAGAS oder DeepEval) kostet etwa $0,05-0,10 pro Testpaar mit GPT-4o. Fuer ein Golden Dataset von 200 Paaren rechnen Sie mit $10-20 pro Durchlauf. Bei CI/CD mit 3 Durchlaeufen pro Woche betragen die monatlichen Kosten etwa $120-240. Das ist vernachlaessigbar im Vergleich zu den Kosten eines fehlerhaften RAG in der Produktion.
Ja, aber mit Vorsicht. Open-Source-Modelle wie Qwen 3 235B oder DeepSeek-R1 koennen als Richter dienen, sind aber generell weniger zuverlaessig als GPT-4o bei der Erkennung subtiler Halluzinationen. Unsere Empfehlung: GPT-4o fuer kritische Bewertungen verwenden und ein Open-Source-Modell fuer schnelle Regressionstests.
Das Golden Dataset sollte bei jeder grossen Aenderung des Dokumentenkorpus aktualisiert werden. In der Praxis: monatlich fuer dynamische Korpora (FAQ, Support) und vierteljaehrlich fuer stabile Korpora (technische Dokumentation). Fuegen Sie systematisch Abfragen hinzu, die in der Produktion gescheitert sind.
Zum Einstieg ist **RAGAS** einfacher und schneller einzurichten. Fuer reife CI/CD-Integration mit pytest ist **DeepEval** dank seines nativen Plugins ueberlegen. Beide sind Open-Source und von vergleichbarer Qualitaet. Bei Ailog verwenden wir RAGAS fuer Ad-hoc-Bewertungen und DeepEval fuer CI/CD.
Halluzinationen werden mit der Treue-Metrik getestet: Jede Behauptung in der Antwort wird gegen den bereitgestellten Kontext verifiziert. Fuer weitergehende Tests fuegen Sie "Fallenfragen" zu Ihrem Golden Dataset hinzu: Fragen, die die Dokumente NICHT beantworten koennen. Das System sollte "Ich weiss es nicht" antworten, anstatt Antworten zu erfinden. Lesen Sie unseren Leitfaden zur [Halluzinationserkennung](/blog/guides/hallucination-detection). ---

Fazit

Ein RAG-System zu testen ist nicht optional - es ist das, was einen Prototypen von einem Produkt trennt. Die 5-Schritte-Methodik funktioniert bei jeder Groesse:

  1. Golden Dataset: Ihre Quelle der Wahrheit
  2. Retrieval-Tests: Die kritischste Komponente
  3. Generierungstests: Treue und Relevanz
  4. End-to-End RAGAS: Die vollstaendige Bewertung
  5. A/B-Tests: Die abschliessende Validierung

Fangen Sie klein an (50 Paare, einfaches RAGAS), dann automatisieren Sie. Die Investition rechnet sich mit dem ersten Bug, der vor der Produktion erkannt wird.

Moechten Sie ein RAG-System, das automatisch getestet und ueberwacht wird? Testen Sie Ailog - unsere Pipelines beinhalten automatische Bewertung und Echtzeit-Monitoring.

Tags

RAGTestingEvaluationRAGASQualitaetCI/CDGolden Dataset

Verwandte Artikel

Ailog Assistant

Ici pour vous aider

Salut ! Pose-moi des questions sur Ailog et comment intégrer votre RAG dans vos projets !