RAG-Systeme sind seit 2024 in der Production weit verbreitet. Unternehmen integrieren ihre eigenen Dokumentkorpora in LLMs über Embedding + Vector-DB-Stack. Aber die meisten Pilotprojekte stoßen auf dasselbe Problem: Retrieval-Qualität ist niedrig, Antworten sind inkonsistent, Kosten außer Kontrolle. Das liegt meist daran, dass die Embedding-Modell-Auswahl, Chunking-Strategie und das Eval-Setup zu schnell über den Tisch gegangen werden. Dieser Artikel zeigt, welche Entscheidungen nicht umkehrbar sind, bevor du die RAG-Pipeline in die Production verschiebst.

Embedding-Modell: Dimension ist nicht alles, Domain-Ausrichtung zählt

Die erste Reaktion bei der Embedding-Modell-Wahl ist "welcher hat den höchsten MTEB-Score?" Aber Benchmark-Rankings garantieren keine Production-Performance. Entscheidend ist, wie gut das Modell auf deine Dokumenttypen und Query-Patterns passt.

Als wir OpenAI text-embedding-3-large (3072 dim) mit Cohere embed-v3 (1024 dim) verglichen, lieferte Cohere bei Marketing-Dokumenten (Blogs, Case Studies, Landing Pages) besseren Recall@10 — das Training-Set enthielt mehr geschäftsinhalte. OpenAI's größere Dimension ist zwar in allgemeinen Benchmarks überlegen, aber die Query-Distribution unterscheidet sich im spezifischen Domain.

Ein weiteres Beispiel: bge-large-en-v1.5 (1024 dim, selbstgehostet) reicht für juristische Dokumente aus. Aber bei mehrsprachigem Corpus schlägt multilingual-e5-large (1024 dim) die Konkurrenz deutlich. Die Modellgröße ist nicht immer ein Qualitätssignal — die Übereinstimmung der Training-Daten mit deinem Domain ist kritischer.

Auswahlkriterien:

  1. MTEB-Score nicht — Recall@5 / MRR-Metrik auf eigenem Eval-Set
  2. Latenz (selbstgehostet vs API) — Batch-Embedding-Zeit für 512 Dokumente
  3. Kosten pro 1M Token — OpenAI 3-large $0,13, Cohere v3 $0,10, selbstgehostet $0 plus Infrastruktur

Wenn dein Dokumentset spezifische Domain-Begriffe enthält (Pharma, Finanzen, Legal), steigert Fine-Tuning eines Embedding-Modells oder ein selbsttrainierter Sentence Transformer die Retrieval-Qualität um 15-20%. Das fällt unter Datenanalyse & Insights-Engineering — du musst eine Training-Pipeline aufbauen und Datenqualität überwachen.

Chunking-Strategie: Feste Größe funktioniert nicht

Die meisten RAG-Implementierungen starten mit "512 Token mit Overlap-Fenster" als Standard. Bei Mixed-Format-Corpus (PDF, HTML, JSON) funktioniert das sofort nicht mehr.

Probleme mit fester Größe:

  • Überschriften werden zerrissen, semantische Integrität geht verloren
  • Tabellen, Code-Blöcke werden mitten durchgeteilt
  • Overlap-Strategie dupliziert überlappendes Context, Retrieval-Rauschen nimmt zu

Alternative: Semantic Chunking. Dokumentfragmente nach Satzbegrenzungen, Überschriften-Hierarchie aufteilen und semantische Integrität bewahren. Nutze langchain's MarkdownTextSplitter statt RecursiveCharacterTextSplitter. Bei PDFs pdfplumber nutzen für Tabel + Text-Trennung und unterschiedliche Chunk-Strategien pro Typ.

Bei einer E-Commerce-Firma haben wir die Produkt-Dokumentation in 3 Chunk-Typen aufgeteilt:

  • Titel + Kurzbeschreibung: 128 Token, leicht für Retrieval
  • Technische Spezifikationen + Tabelle: 256 Token, strukturierte Daten
  • Langform (Blog, Guides): 512 Token, semantische Aufteilung

Wir markierten jeden Chunk mit Metadaten (chunk_type, source_page). Im Retrieval filterten wir nach Query-Typ. Z.B. "Produktvergleich"-Anfragen schauten nur auf technical_specs-Chunks. Das steigerte Precision@3 um 18%.

Overlap-Strategie: Wie viel ist genug?

Overlap wird typischerweise auf 10-20% empfohlen, aber das ist willkürlich. Unser Test: 50 Token Overlap bei 512 Token Chunk erhält semantische Kontinuität. 100 Token Overlap steigert Retrieval-Latenz um 12%, ohne Qualitätsgewinn. Der Sweet Spot hängt vom Domain ab — teste mit deinem Eval-Set.

Eval Setup: Muss vor Production aufgebaut werden

Die meisten RAG-Systeme gehen "sieht visuell gut aus" in Production. Ohne strukturiertes Eval-Setup für Retrieval-Qualität wirst du in den ersten 1000 Queries nicht zuverlässig sein.

Minimale Eval-Pipeline:

# eval_set.json — Golden Dataset
[
  {
    "query": "Wie kann man DSGVO-konform Benutzereinwilligung einholen?",
    "expected_docs": ["doc_42", "doc_89"],
    "expected_answer_contains": ["Cookie-Hinweis", "explizite Zustimmung"]
  },
  ...
]

# Eval-Metriken
def evaluate_retrieval(query, retrieved_docs, expected_docs):
    recall_at_k = len(set(retrieved_docs[:5]) & set(expected_docs)) / len(expected_docs)
    mrr = 1 / (retrieved_docs.index(expected_docs[0]) + 1) if expected_docs[0] in retrieved_docs else 0
    return {"recall@5": recall_at_k, "mrr": mrr}

def evaluate_generation(generated_answer, expected_contains):
    # LLM-as-judge: Frage Claude: "Enthält diese Antwort erwartete Inhalte?"
    prompt = f"Erwartet: {expected_contains}\nGeneriert: {generated_answer}\nScore 0-1:"
    score = claude_api(prompt)
    return float(score)

Eval-Häufigkeit: Nach jeder Embedding-Modell-Änderung, Chunking-Tweak. Im CI/CD automatisch ausführen. Falls Recall@5 < 0,7, Deployment blockieren.

Im realen Szenario: Für einen Kunden preparierte ich 200-er Eval-Set. Die Eval-Pipeline lief bei jedem Commit. Eine Chunking-Änderung steigerte Recall@5 von 0,68 auf 0,81, aber P95-Latenz sprang von 340ms auf 520ms. Mit dem Cost/Latenz-Tradeoff auf dem Dashboard sichtbar, rollten wir Chunking zurück und testeten einen anderen Ansatz. Ohne Eval wären wir blind auf diese Regression gewesen.

Hybrid Search: Sparse + Dense Retrieval kombinieren

Nur auf Vector-Ähnlichkeit zu setzen schlägt bei Edge Cases fehl. Exact-Keyword-Matches (Produktcode, API-Endpoint-Name) bekommen oft niedrige Vector-Scores. Hier kommt Hybrid Search ins Spiel: Kombiniere BM25 (Sparse) + Embedding (Dense) Scores.

# Hybrid-Retrieval-Beispiel
bm25_results = bm25_index.search(query, top_k=20)
vector_results = vector_db.search(query_embedding, top_k=20)

# RRF (Reciprocal Rank Fusion)
def rrf_score(rank, k=60):
    return 1 / (k + rank)

combined_scores = {}
for rank, doc in enumerate(bm25_results):
    combined_scores[doc.id] = combined_scores.get(doc.id, 0) + rrf_score(rank)
for rank, doc in enumerate(vector_results):
    combined_scores[doc.id] = combined_scores.get(doc.id, 0) + rrf_score(rank)

final_results = sorted(combined_scores.items(), key=lambda x: x[1], reverse=True)[:5]

Test-Ergebnis: Hybrid Search steigerte Recall@5 bei technischen Queries um 22%. Aber Latenz verdoppelte sich, weil zwei separate Indizes abgefragt werden. Falls dieser Tradeoff akzeptabel ist (z.B. internes Tool, <500ms ausreichend), funktioniert Hybrid Search in Production.

Reranking: Zweite Filterbühne

Die erste Retrieval-Phase (BM25 + Vector) holt 20-50 Dokumente. Aber nicht alle passen in den LLM-Context (Cost + Token-Limit). Ein Reranker-Modell kommt ins Spiel: Es bewertet die Relevanz jedes Dokuments zur Query neu und wählt Top-5.

Modelle wie Cohere rerank-english-v2.0 oder bge-reranker-large werden genutzt. Reranker nutzen Cross-Encoder-Architektur — sie encodieren Query + Dokument zusammen, deshalb sind sie teurer als Embeddings, aber genauer.

Benchmark: Beim Reranking über 50 Dokumente:

  • Recall@5: 0,73 → 0,89
  • Latenz: +180ms (akzeptabel)
  • Kosten: +$0,002 pro Retrieval (Cohere API)

Wenn Budget eng ist, nutze selbstgehostete Reranker, benötigst aber GPU-Inference. Hier rechnest du Infrastructure-Kosten vs API-Kosten.

Context-Fenster optimieren: Weniger Dokumente, bessere Antworten

20 Dokumente an LLM zu geben erzeugt nicht immer bessere Antworten. Großer Context führt zu "Lost in the Middle" — das Modell ignoriert mittlere Informationen. Test-Ergebnis: GPT-4 Turbo mit 5 Dokumenten produziert bessere Antworten als mit 15 (BLEU-Score 11% Unterschied).

Optimierungs-Strategie:

  1. Mit Reranker Top-5 wählen
  2. Dokumente mit Relevance-Score < 0,6 ausfiltern
  3. Verbleibende 3-5 Dokumente ins LLM-Context schicken

Dieser Ansatz senkt Token-Kosten (Input-Tokens um 70% weniger) und steigert Antwortqualität. In Production musst du den Sweet Spot im Cost/Latenz/Quality-Dreieck finden — Eval-Pipeline macht das sichtbar.

Production-Monitoring: Retrieval-Drift

Retrieval-Qualität kann mit der Zeit sinken — neue Dokumente, sich ändernde Query-Verteilung. Retrieval-Drift muss mit einem Dashboard überwacht werden:

MetrikZielAlarm-Schwelle
Recall@5 (wöchentlich Eval)> 0,75< 0,70
P95 Latenz< 400ms> 600ms
Null-Result-Queries (%)< 5%> 10%
Durchschn. Relevance-Score> 0,65< 0,55

Falls Recall-Drift auftritt:

  1. Eval-Set aktualisieren (neue Query-Patterns hinzufügen)
  2. Embedding-Modell fine-tunen oder ersetzen
  3. Chunking-Strategie überprüfen

Dieses Monitoring fällt unter First-Party-Daten & Measurement-Architektur — RAG ist auch eine Data-Pipeline und muss observable sein.

Cost vs Quality Tradeoff: Pragmatische Entscheidungen

Jede Production-RAG-Entscheidung enthält einen Cost/Quality/Latenz-Tradeoff. Einige pragmatische Wähle:

  • Embedding-Modell: OpenAI 3-large durch Cohere v3 ersetzen → 30% Kostenersparnis, 2% Quality-Verlust (akzeptabel)
  • Reranking: Nicht jeden Query reranken, nur ambige → Latenz 40% weniger
  • Hybrid Search: Nur Vector statt BM25 + Vector (wenn Exact-Match unwichtig) → Latenz 50% weniger
  • Context-Fenster: 10 statt 5 Dokumente → 60% Token-Kosten weniger, 8% Quality-Gewinn

Ohne Eval-Pipeline siehst du diese Tradeoffs nicht. Sonst sagst du "Embedding-Modell geändert, ist billiger" und merkst nicht, dass Retrieval-Qualität um 15% sank.

Bevor du dein RAG-System in Production verschiebst: Nimm Embedding-Modell, Chunking-Strategie und Eval-Setup ernst. Cost-Optimierung kommt später — erst Retrieval-Qualität stabilisieren, dann Kosten senken. Sonst wird die Unzuverlässigkeit sichtbar und Adoption sinkt.