RAG-Konzepte

Retrieval Augmented Generation im Detail – Architektur, Strategien und Best Practices


Inhaltsverzeichnis

  1. Überblick: Was ist RAG?
  2. Die RAG-Architektur
    1. Indexierungsphase
    2. Abfragephase
  3. Chunking: Dokumente sinnvoll zerlegen
    1. Chunking-Strategien
    2. Der RecursiveCharacterTextSplitter
    3. Overlap: Kontext bewahren
    4. Empfehlungen nach Dokumenttyp
  4. Embeddings: Text als Vektor
    1. Konzept
    2. Verfügbare Embedding-Modelle
    3. Ähnlichkeitsmaße
    4. Beispiel: Embeddings erzeugen
  5. Retrieval: Die richtigen Dokumente finden
    1. Basis-Retrieval: Similarity Search
    2. Retrieval-Strategien im Vergleich
    3. Maximum Marginal Relevance (MMR)
    4. Score-basiertes Filtering
    5. Metadaten-Filter
  6. Reranking: Ergebnisse optimieren
    1. Warum Reranking?
    2. Reranking-Ansätze
    3. Beispiel: Cohere Reranker
  7. Advanced RAG-Techniken
    1. Query Transformation
    2. Self-Query
    3. Contextual Compression
    4. Parent Document Retriever
  8. RAG-Chain mit LangChain
    1. Minimales Beispiel
    2. RAG als Agent-Tool
  9. Evaluierung von RAG-Systemen
  10. Troubleshooting
    1. Problem: Keine relevanten Dokumente gefunden
    2. Problem: Falsche Antworten trotz korrektem Kontext
    3. Problem: Langsame Antwortzeiten
  11. Best Practices
    1. Indexierung
    2. Retrieval
    3. Prompt Design
    4. Evaluation
  12. Zusammenfassung
  13. Abgrenzung zu verwandten Dokumenten

Überblick: Was ist RAG?

Large Language Models besitzen beeindruckende Fähigkeiten, stoßen jedoch an klare Grenzen:

Limitation Beschreibung
Wissens-Cutoff Das Modell kennt nur Informationen bis zum Trainingszeitpunkt
Kein Domänenwissen Firmeninterne Dokumente, Fachrichtlinien oder aktuelle Daten fehlen
Halluzination Bei Wissenslücken werden plausible, aber falsche Antworten generiert
Kontextlimit Nicht alle relevanten Dokumente passen in einen einzelnen Prompt
Cross-Document-Reasoning RAG findet, was existiert — nicht, was fehlt. Lücken zwischen Dokumenten (z. B. “Welche Anforderungen wurden im Release weggelassen?”) sind nicht abrufbar, weil kein Chunk sie enthält

Retrieval Augmented Generation (RAG) löst diese Probleme durch einen eleganten Ansatz: Statt das LLM mit mehr Daten zu trainieren, werden relevante Informationen zur Laufzeit abgerufen und dem Prompt hinzugefügt.

Frage → Suche relevante Dokumente → Füge Kontext zum Prompt → LLM generiert Antwort

Kernidee: Das LLM erhält genau die Informationen, die es für die aktuelle Frage benötigt – nicht mehr und nicht weniger.

RAG ist nicht die einzige Augmentierungsstrategie. Eine Alternative ist CAG (Cache Augmented Generation): statt relevante Chunks abzurufen, wird die gesamte Wissensbasis vorab in das Kontextfenster geladen und als KV-Cache gespeichert. CAG hat niedrigere Latenz, ist aber durch die Kontextfenstergröße begrenzt und eignet sich nur für kleine, statische Wissensbasen. Für Vergleich, Entscheidungshilfe und Hybrid-Ansätze (RAG + CAG kombiniert) → RAG vs. CAG (geplant).


Die RAG-Architektur

Ein RAG-System besteht aus zwei Hauptphasen: Indexierung (einmalig) und Retrieval + Generation (bei jeder Anfrage).

Indexierungsphase

flowchart LR
    A[Dokumente] --> B[Laden]
    B --> C[Chunking]
    C --> D[Embedding]
    D --> E[Vektordatenbank]
Schritt Beschreibung Typische Tools
Laden Dokumente aus verschiedenen Quellen einlesen TextLoader, PyPDFLoader, WebBaseLoader
Chunking Große Dokumente in kleinere Teile zerlegen RecursiveCharacterTextSplitter
Embedding Textchunks in Vektoren umwandeln OpenAIEmbeddings, HuggingFaceEmbeddings
Speichern Vektoren in Datenbank ablegen ChromaDB, FAISS, Pinecone

Abfragephase

flowchart LR
    A[Frage] --> B[Embedding]
    B --> C[Similarity Search]
    C --> D[Top-k Dokumente]
    D --> E[Prompt + Kontext]
    E --> F[LLM]
    F --> G[Antwort]
Schritt Beschreibung
Query-Embedding Die Frage wird in denselben Vektorraum transformiert
Similarity Search Die ähnlichsten Dokumentvektoren werden gefunden
Kontext-Erstellung Gefundene Chunks werden zum Prompt hinzugefügt
Generation Das LLM generiert eine Antwort basierend auf dem Kontext

[!WARNING] Retrieval verbessert Relevanz — garantiert aber keine Faktentreue.
RAG reduziert Halluzination, eliminiert sie nicht. Das LLM kann relevante Dokumente fehlinterpretieren, kombinieren oder ergänzen. Kritische Anwendungen brauchen zusätzliche Validierung der generierten Antworten.


Chunking: Dokumente sinnvoll zerlegen

Chunking ist eine der kritischsten Entscheidungen in einem RAG-System. Zu große Chunks verschwenden Kontext, zu kleine Chunks verlieren Zusammenhang.

[!TIP] Chunking-Strategie beeinflusst Retrieval-Qualität stark
Die Wahl von chunk_size und chunk_overlap ist dokumenttypabhängig. Falsch gewählte Parameter sind häufig die Ursache für schlechte RAG-Ergebnisse — noch bevor das LLM überhaupt zum Einsatz kommt.

Chunking-Strategien

Strategie Beschreibung Anwendungsfall
Fixed-Size Feste Zeichenanzahl pro Chunk Einfache Texte ohne Struktur
Recursive Hierarchische Trennung (Absatz → Satz → Wort) Allgemeine Dokumente
Semantic Trennung nach Bedeutungseinheiten Komplexe Fachtexte
Document-based Beibehaltung natürlicher Grenzen (Kapitel, Abschnitte) Strukturierte Dokumente

Der RecursiveCharacterTextSplitter

Der am häufigsten verwendete Splitter arbeitet mit einer Hierarchie von Trennzeichen:

from langchain_text_splitters import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,      # Maximale Chunk-Größe in Zeichen
    chunk_overlap=100,   # Überlappung zwischen Chunks
    separators=["\n\n", "\n", ". ", " ", ""]  # Trennzeichen-Hierarchie
)

Funktionsweise:

  1. Versuche zuerst, an Doppel-Zeilenumbrüchen zu trennen (Absätze)
  2. Falls Chunk zu groß: Trenne an einfachen Zeilenumbrüchen
  3. Falls immer noch zu groß: Trenne an Satzenden
  4. Letzte Option: Trenne an Leerzeichen oder einzelnen Zeichen

Overlap: Kontext bewahren

Dokument: [AAAA|BBBB|CCCC|DDDD]

Ohne Overlap:
  Chunk 1: [AAAA]
  Chunk 2: [BBBB]
  → Information an Grenzen geht verloren

Mit Overlap (25%):
  Chunk 1: [AAAA|BB]
  Chunk 2: [BB|CCCC]
  → Zusammenhänge bleiben erhalten

Empfehlungen nach Dokumenttyp

Dokumenttyp chunk_size chunk_overlap Begründung
FAQ / Kurztexte 200–300 50 Präzise, eigenständige Antworten
Handbücher 500–800 100–150 Kontext zwischen Abschnitten erhalten
Rechtsdokumente 800–1000 200 Vollständige Paragraphen wichtig
Code-Dokumentation 300–500 100 Funktionen zusammenhalten

Embeddings: Text als Vektor

Embeddings sind das Herzstück der semantischen Suche. Sie transformieren Text in numerische Vektoren, wobei ähnliche Bedeutungen zu ähnlichen Vektoren führen.

Konzept

"Der Hund spielt im Park"     → [0.12, -0.45, 0.78, ..., 0.33]  (1536 Dim.)
"Die Katze liegt im Garten"   → [0.15, -0.42, 0.71, ..., 0.29]  (ähnlich!)
"Quantenmechanik ist komplex" → [-0.89, 0.23, -0.11, ..., 0.67] (anders!)

Verfügbare Embedding-Modelle

Modell Dimensionen Kosten Qualität
text-embedding-3-small (OpenAI) 1536 ~$0.02/1M Tokens ⭐⭐⭐⭐
text-embedding-3-large (OpenAI) 3072 ~$0.13/1M Tokens ⭐⭐⭐⭐⭐
all-MiniLM-L6-v2 (HuggingFace) 384 Kostenlos ⭐⭐⭐
multilingual-e5-large (HuggingFace) 1024 Kostenlos ⭐⭐⭐⭐

Ähnlichkeitsmaße

Die Ähnlichkeit zwischen Vektoren wird mathematisch berechnet:

Maß Beschreibung Wertebereich
Cosine Similarity Winkel zwischen Vektoren -1 bis 1
Euclidean Distance Geometrischer Abstand 0 bis ∞
Dot Product Skalarprodukt -∞ bis ∞

Cosine Similarity ist der Standard, da sie unabhängig von der Vektorlänge nur die “Richtung” (= Bedeutung) vergleicht.

Beispiel: Embeddings erzeugen

from langchain_openai import OpenAIEmbeddings

embedding_model = OpenAIEmbeddings(model="text-embedding-3-small")

# Einzelner Text (für Queries)
query_vector = embedding_model.embed_query("Was ist ein KI-Agent?")

# Mehrere Texte (für Dokumente)
doc_vectors = embedding_model.embed_documents([
    "Text 1", "Text 2", "Text 3"
])

Retrieval: Die richtigen Dokumente finden

Der Retriever ist die Brücke zwischen Frage und relevantem Wissen. Verschiedene Strategien optimieren die Trefferqualität.

from langchain_community.vectorstores import Chroma

vectorstore = Chroma.from_documents(chunks, embedding_model)
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})

# Suche
docs = retriever.invoke("Wie funktioniert RAG?")

Retrieval-Strategien im Vergleich

Strategie Beschreibung Vorteil Nachteil
Similarity Ähnlichste Vektoren Schnell, einfach Keine Qualitätsgarantie
MMR Maximum Marginal Relevance Diversität der Ergebnisse Etwas langsamer
Threshold Nur Ergebnisse über Schwellenwert Qualitätskontrolle Kann leer zurückkommen
Hybrid Keyword + Semantisch kombiniert Beste Abdeckung Komplexer aufzusetzen

Maximum Marginal Relevance (MMR)

MMR balanciert Relevanz und Diversität. Statt nur die ähnlichsten Dokumente zurückzugeben, werden auch unterschiedliche Perspektiven berücksichtigt.

retriever = vectorstore.as_retriever(
    search_type="mmr",
    search_kwargs={
        "k": 5,           # Finale Anzahl
        "fetch_k": 20,    # Kandidaten für MMR
        "lambda_mult": 0.7  # Balance (1.0 = nur Relevanz, 0.0 = nur Diversität)
    }
)

Score-basiertes Filtering

retriever = vectorstore.as_retriever(
    search_type="similarity_score_threshold",
    search_kwargs={
        "score_threshold": 0.5,  # Mindest-Ähnlichkeit
        "k": 10
    }
)

Metadaten-Filter

retriever = vectorstore.as_retriever(
    search_kwargs={
        "k": 5,
        "filter": {"source": "handbuch.pdf", "kapitel": "Sicherheit"}
    }
)

Reranking: Ergebnisse optimieren

Reranking verbessert die Qualität der gefundenen Dokumente durch einen zweiten Bewertungsschritt.

Warum Reranking?

Die initiale Vektorsuche ist schnell, aber nicht perfekt. Reranking verwendet ein präziseres (aber langsameres) Modell, um die Top-Ergebnisse neu zu ordnen.

Schritt 1: Similarity Search → 20 Kandidaten
Schritt 2: Reranker bewertet alle 20 → Sortiert nach Qualität
Schritt 3: Top 5 werden verwendet

Reranking-Ansätze

Ansatz Beschreibung Performance
Cross-Encoder Betrachtet Query + Dokument gemeinsam Höchste Qualität, langsam
LLM-based LLM bewertet Relevanz Flexibel, teuer
Lightweight Schnelle Heuristiken Schnell, moderate Qualität

Beispiel: Cohere Reranker

from langchain.retrievers import ContextualCompressionRetriever
from langchain_cohere import CohereRerank

base_retriever = vectorstore.as_retriever(search_kwargs={"k": 20})

reranker = CohereRerank(model="rerank-english-v3.0", top_n=5)

compression_retriever = ContextualCompressionRetriever(
    base_compressor=reranker,
    base_retriever=base_retriever
)

docs = compression_retriever.invoke("Meine Frage")

Advanced RAG-Techniken

Über die Grundlagen hinaus existieren fortgeschrittene Techniken zur Qualitätsverbesserung.

Query Transformation

Die ursprüngliche Frage wird umformuliert oder erweitert, um bessere Treffer zu erzielen.

Multi-Query: Eine Frage wird in mehrere Varianten umgewandelt:

Original: "Wie funktioniert RAG?"
→ "Was ist Retrieval Augmented Generation?"
→ "Erkläre die RAG-Architektur"
→ "RAG-System Komponenten"

HyDE (Hypothetical Document Embedding): Das LLM generiert eine hypothetische Antwort, die dann für die Suche verwendet wird:

Frage: "Wie funktioniert RAG?"
→ LLM generiert: "RAG kombiniert Retrieval und Generation..."
→ Suche nach Dokumenten ähnlich zur hypothetischen Antwort

Self-Query

Das LLM extrahiert strukturierte Filter aus natürlichsprachlichen Fragen:

Frage: "Zeige mir Sicherheitsrichtlinien aus 2024"
→ Extrahiert: {"kategorie": "sicherheit", "jahr": 2024}
→ Kombiniert semantische Suche mit Metadaten-Filter

Contextual Compression

Gefundene Dokumente werden auf das Wesentliche komprimiert:

Gefundener Chunk (500 Zeichen):
"Die Firma wurde 1995 gegründet. Der Hauptsitz befindet sich in Berlin.
 Die Sicherheitsrichtlinien wurden 2023 aktualisiert und umfassen..."

Nach Compression (relevanter Teil für Frage "Sicherheitsrichtlinien"):
"Die Sicherheitsrichtlinien wurden 2023 aktualisiert und umfassen..."

Parent Document Retriever

Kleine Chunks für präzises Retrieval, aber größere Kontextfenster für die Generierung:

Indexierung: Kleine Chunks (200 Zeichen) → Vektordatenbank
Retrieval: Finde relevante kleine Chunks
Rückgabe: Hole zugehörige Parent-Dokumente (2000 Zeichen)

RAG-Chain mit LangChain

Die Kombination aller Komponenten zu einer funktionierenden Pipeline.

Minimales Beispiel

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain.chat_models import init_chat_model
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings

# Komponenten
llm = init_chat_model("openai:gpt-4o-mini", temperature=0.0)
embedding_model = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_documents(chunks, embedding_model)
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})

# Hilfsfunktion
def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)

# RAG-Prompt
rag_prompt = ChatPromptTemplate.from_template(
    """Beantworte die Frage basierend auf dem folgenden Kontext.
Wenn die Antwort nicht im Kontext steht, sage ehrlich, dass keine Information vorliegt.

Kontext:
{context}

Frage: {question}

Antwort:"""
)

# LCEL Chain
rag_chain = (
    {
        "context": retriever | format_docs,
        "question": RunnablePassthrough()
    }
    | rag_prompt
    | llm
    | StrOutputParser()
)

# Aufruf
antwort = rag_chain.invoke("Wie funktioniert das System?")

RAG als Agent-Tool

from langchain_core.tools import tool

@tool
def firmenwissen_suchen(frage: str) -> str:
    """🔍 FIRMENWISSEN – Durchsucht interne Dokumente.
    
    Verwenden für Fragen zu:
    - Unternehmensrichtlinien
    - Internen Prozessen
    - Produktinformationen
    
    Args:
        frage: Die Suchanfrage in natürlicher Sprache
    
    Returns:
        Relevante Informationen aus den Firmendokumenten
    """
    try:
        return rag_chain.invoke(frage)
    except Exception as e:
        return f"Fehler bei der Suche: {str(e)}"

Evaluierung von RAG-Systemen

Die Qualität eines RAG-Systems wird auf zwei Ebenen gemessen:

Ebene Metrik Misst
Retrieval Precision@k Anteil relevanter Dokumente unter den Gefundenen
Retrieval Recall@k Anteil gefundener relevanter Dokumente
Generation Faithfulness Basiert die Antwort ausschließlich auf dem Kontext?
Generation Answer Relevance Beantwortet die Antwort die gestellte Frage?
Generation Context Relevance Ist der abgerufene Kontext tatsächlich relevant?

Faithfulness ist die wichtigste RAG-Metrik: Sie prüft, ob das Modell halluziniert oder sich strikt auf die abgerufenen Dokumente stützt.

Für Implementierungsdetails zu Evaluatoren, LangSmith-Integration, RAGAS-Framework, LLM-as-Judge und Regression-Tests siehe → Evaluation & Testing.


Troubleshooting

Häufige Probleme und deren Lösungen.

Problem: Keine relevanten Dokumente gefunden

Wenn der Retriever die richtigen Chunks nicht zurückliefert, beantwortet das LLM die Frage trotzdem — aber ohne die benötigte Information. Dieses Muster wird Silent Failure genannt: Die Antwort existierte in der Wissensbasis, das LLM hat sie nie gesehen.

Ursache Diagnose Lösung
Collection leer vectorstore._collection.count() Dokumente indexieren
Falsches Embedding-Modell Dimensionen vergleichen Gleiches Modell für Index und Query
Query zu spezifisch Mit breiterem Begriff testen Query umformulieren
k zu klein k erhöhen search_kwargs={"k": 10}

Problem: Falsche Antworten trotz korrektem Kontext

Ursache Lösung
Prompt unklar Anweisungen präzisieren
Zu viel Kontext Weniger Chunks, Compression nutzen
Widersprüchliche Dokumente Metadaten-Filter für Aktualität
Halluzination Explizite Anweisung: “Nur basierend auf Kontext”

Problem: Langsame Antwortzeiten

Komponente Optimierung
Embedding Batch-Verarbeitung, Caching
Retrieval Index optimieren, k reduzieren
Reranking Weniger Kandidaten, leichteres Modell
LLM Streaming aktivieren, schnelleres Modell

Best Practices

Indexierung

  • Konsistentes Embedding-Modell: Dasselbe Modell für Indexierung und Queries verwenden
  • Sinnvolles Chunking: Dokumenttyp-spezifische Parameter wählen
  • Metadaten anreichern: Quelle, Datum, Kategorie für späteres Filtern
  • Inkrementelle Updates: Nur geänderte Dokumente neu indexieren

Retrieval

  • k sinnvoll wählen: Zu wenig = fehlender Kontext, zu viel = Rauschen
  • MMR für Diversität: Bei breiten Themen verschiedene Perspektiven einbeziehen
  • Threshold für Qualität: Lieber keine Antwort als eine falsche

Prompt Design

  • Klare Anweisungen: “Antworte NUR basierend auf dem Kontext”
  • Fallback definieren: Was tun bei fehlendem Wissen?
  • Quellenangaben: Antwort mit Dokumentreferenzen anreichern

Evaluation

  • Test-Dataset erstellen: Repräsentative Fragen mit erwarteten Antworten
  • Regelmäßig evaluieren: Nach jedem Update der Wissensbasis
  • Feedback sammeln: Nutzer-Bewertungen für kontinuierliche Verbesserung

Zusammenfassung

RAG kombiniert die Stärken von Retrieval-Systemen mit generativen LLMs:

Komponente Funktion Typisches Tool
Document Loader Daten einlesen TextLoader, PyPDFLoader
Text Splitter Chunking RecursiveCharacterTextSplitter
Embedding Model Text → Vektor OpenAIEmbeddings
Vector Store Speicherung & Suche ChromaDB, FAISS
Retriever Relevante Chunks finden as_retriever()
LLM Antwort generieren GPT-4o-mini

Der typische Workflow:

1. Dokumente laden und chunken
       ↓
2. Embeddings erzeugen und speichern
       ↓
3. Retriever konfigurieren
       ↓
4. RAG-Prompt erstellen
       ↓
5. LCEL-Chain bauen
       ↓
6. Evaluieren und optimieren

RAG ermöglicht es, LLMs mit aktuellem, domänenspezifischem Wissen auszustatten – ohne teures Fine-Tuning und mit voller Kontrolle über die Wissensbasis.

Abgrenzung zu verwandten Dokumenten

Dokument Inhalt
Lohnt es sich überhaupt? Wann RAG die richtige Wahl ist — und wann nicht
Evaluation & Testing Wie Retrieval-Qualität, Faithfulness und Groundedness gemessen werden
State Management Wie Retrieval-Ergebnisse im Graph-State weitergegeben werden

Version: 1.0
Stand: November 2025
Kurs: KI-Agenten. Verstehen. Anwenden. Gestalten.