Warum deine RAG-Pipeline selbstbewussten Unsinn zurueckgibt: Chunk-Groesse, Reranking und das Eval-Framework, das du vor dem Launch brauchst
Retrieval-Augmented Generation hat ein schmutziges Geheimnis: Die Demo funktioniert immer. Du fuegest ein paar Dokumente in ein Notebook ein, schickst eine Anfrage an den Vektorspeicher, und das LLM antwortet fluessig und korrekt. Du zeigst es dem Stakeholder. Alle sind beeindruckt. Du bringst es live.
Drei Wochen spaeter halluziniert das RAG-System in der Produktion Richtliniennummern, zitiert selbstbewusst die falsche Version eines Dokuments, und dein Support-Team hat eine Warteschlange voller verwirrter Folgeanfragen.
Das ist kein Modellproblem. Das Modell tut genau das, worum du es gebeten hast: eine Antwort aus den abgerufenen Chunks synthetisieren. Das Problem ist, dass die falschen Chunks zurueckgegeben wurden - oder die richtigen Chunks auf eine Art zurueckkamen, die den Kontext zerstoert hat, den das Modell benoetigt haette. RAG-Produktionsfehler sind fast immer Retrieval-Fehler, die als Generierungsfehler verkleidet sind.
In diesem Post moechte ich die drei Schichten durchgehen, die die meisten RAG-Systeme in der Praxis kaputt machen - Chunking, Reranking und Evaluation - anhand von Fehlermustern, die mir wiederholt bei Code-Audits und KI-Integrationsprojekten begegnen. Am Ende solltest du ein konkretes Eval-Framework haben, das du offline vor jeder wesentlichen Aenderung an deiner Pipeline ausfuehren kannst.
Das Chunking-Problem, ueber das niemand ehrlich spricht
Wenn Entwickler zum ersten Mal eine RAG-Pipeline aufbauen, kopieren sie in der Regel die Chunk-Groesse aus dem Tutorial, das sie gefunden haben. 512 Token sind haeufig. Manchmal 256. Gelegentlich 1.000. Es gibt selten einen prinzipiengeleiteten Grund hinter der Wahl, und das macht einen groesseren Unterschied, als die meisten erwarten.
Chunk-Groesse ist kein Hyperparameter, den man einmal einstellt und vergisst. Sie ist eine Funktion von drei interagierenden Dingen: der Struktur deiner Quelldokumente, dem Kontextfenster deines Embedding-Modells und der Art der Anfragen, die Nutzer tatsaechlich stellen.
Kurze Chunks (128-256 Token) bewahren die lexikalische Praezision - eine bestimmte Klausel in einem Vertrag, ein einzelner Schritt in einem Verfahren. Sie zerstoeren aber auch den semantischen Kontext. Wenn ein Nutzer fragt "Wie lange ist das Rueckgabefenster fuer Enterprise-Kunden?" und die Antwort einen Absatz umfasst, der lautet "Enterprise-Konten haben Anspruch auf Erstattungen innerhalb von 90 Tagen, sofern der Antrag ueber das Abrechnungsportal gestellt und vom Account-Management genehmigt wird" - ein 128-Token-Chunk koennte dem LLM das 90-Tage-Fenster ohne die Bedingungen liefern, oder die Bedingungen ohne das Fenster. Das Modell synthetisiert dann eine selbstbewusste, aber unvollstaendige Antwort.
Lange Chunks (1.024-2.048 Token) bewahren den Kontext, verduennen aber das Embedding. Ein 1.500-Token-Chunk ueber deine Preisseite, deine Erstattungsrichtlinie und dein Enterprise-SLA zusammen ergibt ein Embedding, das in einem vagen Bereich des Vektorraums liegt. Er wird fuer Fragen abgerufen, fuer die er nicht die beste Antwort ist, und bei Fragen, fuer die er die beste Antwort waere, wird er uebergangen.
Die ehrliche Antwort ist, dass es keine universell korrekte Chunk-Groesse gibt - aber es gibt prinzipiengeleitete Wege, eine zu waehlen. Beginne mit der typischen Laenge der bedeutungsvollen Einheit in deinem Quellkorpus. Rechtsdokumente haben Klauseln. Support-Dokumentation hat Verfahren. Produkt-Changelogs haben Releases. Identifiziere die semantische Einheit und setze deine Ziel-Chunk-Groesse so, dass sie ungefaehr eine davon enthaelt, mit einer Ueberlappung von 10-20% der Chunk-Groesse, um Kontexttrennung an Grenzen zu verhindern.
Ueberlappung ist bei sequenziellen Dokumenten nicht optional. Wenn du ein zehnstuftiges Verfahren hast und Chunks zufaellig zwischen Schritt 3 und 4 abschneiden, koennte eine Anfrage zu Schritt 4 einen Chunk zurueckgeben, der mitten im Satz beginnt. Das Embedding wird verwirrt sein, und das Modell auch. Eine Ueberlappung von 50-100 Token bei einem 512-Token-Chunk ist kostenguenstig und verhindert die meisten dieser Fehler.
Ein Muster, das die Retrieval-Qualitaet bei Audits konsistent verbessert, ist hierarchisches Chunking: Speichere sowohl einen kleinen Chunk (fuer praezises Retrieval) als auch einen groesseren Eltern-Chunk (fuer die Kontextlieferung). Du erstellst Embeddings und suchst in den kleinen Chunks, aber wenn ein kleiner Chunk ausgewaehlt wird, fuegest du den vollstaendigen Eltern-Chunk in den Prompt ein. Das gibt dir sowohl Retrieval-Praezision als auch Generierungskontext gleichzeitig. Bibliotheken wie LlamaIndex nennen das "Small-to-Big Retrieval", aber das Muster ist direkt gegen pgvector implementierbar, wenn du einen Symfony-Stack betreibst - die Schema-Details findest du in unserem pgvector-Architektur-Blueprint-Post.
Warum ein Reranker das Ergebnis mehr veraendert als ein besseres Embedding-Modell
Die meisten Teams, die ihre RAG-Pipeline optimieren, konzentrieren sich auf den Wechsel von Embedding-Modellen. Sie wechseln von text-embedding-ada-002 zu einem neueren Modell, fuehren ein paar manuelle Tests durch und sind mit der Aenderung zufrieden. Die Qualitaet des Embedding-Modells spielt eine Rolle - aber sie ist nicht der wirkungsvollste Hebel fuer die meisten produktiven Pipelines.
Der wirkungsvollste Hebel ist das Hinzufuegen eines Cross-Encoder-Rerankers zwischen Vektor-Retrieval und Prompt-Zusammenstellung.
Hier ist der Unterschied: Ein Bi-Encoder (die Art von Modell, die zur Erstellung von Embeddings verwendet wird) kodiert Anfrage und jedes Dokument unabhaengig und berechnet dann die Aehnlichkeit im Vektorraum. Das ist schnell und skalierbar, weshalb es fuer das Retrieval ueber Millionen von Dokumenten funktioniert. Bi-Encoder verlieren jedoch die feinkoernige Token-Level-Interaktion zwischen Anfrage und Dokument - zwei Texte koennen semantisch nah im Embedding-Raum sein, waehrend einer von ihnen tatsaechlich eine viel bessere Antwort auf die spezifische Frage ist.
Ein Cross-Encoder nimmt die Anfrage und einen Kandidaten-Chunk zusammen als einzelne Eingabe und erzeugt einen Relevanzscore. Er beachtet jedes Token der Anfrage in Bezug auf jedes Token des Dokuments. Das ist viel genauer - und viel langsamer, weshalb du ihn nicht fuer den initialen Retrieval-Durchlauf verwendest.
Das Standardmuster ist: 20-50 Kandidaten aus dem Vektorspeicher abrufen (guenstig), mit einem Cross-Encoder neu ordnen (maessige Kosten, begrenzt durch die Anzahl der Kandidaten), die Top 3-5 fuer den Prompt nehmen. Bei den meisten RAG-Pipelines, die ich auditiert habe, hat das Hinzufuegen eines Cross-Encoder-Rerankers die Faithfulness-Scores um 15-30 Prozentpunkte verbessert, ohne das Embedding-Modell oder die Prompt-Vorlage zu beruehren. Das ist eine erhebliche Verbesserung fuer die Kosten eines zusaetzlichen Modellaufrufs pro Anfrage.
Fuer selbst gehostete Stacks ist cross-encoder/ms-marco-MiniLM-L-6-v2 von HuggingFace ein praktischer Ausgangspunkt - klein genug, um auf einer einzelnen GPU oder sogar einem leistungsstarken CPU-Server fuer maessige Query-Volumen zu laufen. Fuer verwaltete Optionen ist Cohere Rerank einfach zu integrieren und funktioniert gut, wenn du bereits ihr Embedding-Modell verwendest. Das Latenzbudget fuer ein Cross-Encoder-Reranking ueber 20 Kandidaten betraegt typischerweise 50-150ms, was innerhalb eines nutzerseitigen Chat-Interface akzeptabel ist.
Die Entscheidungsmatrix fuer "Lohnt sich ein Reranker?" ist ungefaehr folgende: Wenn dein Retrieval-Recall (erscheint das richtige Dokument irgendwo in den Top-20-Ergebnissen?) bereits ueber 80% liegt, deine Praezision (ist das richtige Dokument unter den Top-3, die in den Prompt eingehen?) aber unter 60% liegt, fuge einen Reranker hinzu. Wenn dein Recall unter 80% liegt, behebe zuerst dein Chunking und dein Embedding - ein Reranker kann keine Dokumente wiederherstellen, die nie abgerufen wurden.
Das Vier-Fragen-Eval-Framework
Das mit Abstand haeufigste Versagen, das ich in der KI-Produktentwicklung sehe, ist das Ausliefern ohne ein Offline-Evaluierungs-Framework. Teams testen nach Gefuehl - sie fuehren ein paar Anfragen aus, die Antworten sehen vernuenftig aus, und sie deployen. Das funktioniert, bis es katastrophal nicht mehr funktioniert.
Ein gutes RAG-Eval-Framework beantwortet vier Fragen zu jeder Anfrage in einem repraesentativen Testset:
1. Faithfulness - ist jede Behauptung in der generierten Antwort im abgerufenen Kontext enthalten? Ein Faithfulness-Score von 1,0 bedeutet, dass das Modell keine Behauptungen aufgestellt hat, die nicht in den abgerufenen Chunks begruendet waren. Halluzinationen zeigen sich als Faithfulness unter 1,0. Du misst das, indem du die atomaren Behauptungen in der Antwort extrahierst und jede gegen den abgerufenen Kontext pruefst - das kann mit einem kleinen LLM-Judge-Prompt automatisiert werden. RAGAS ist die am weitesten verbreitete Open-Source-Bibliothek dafuer.
2. Antwortrelevanz - beantwortet die Antwort tatsaechlich das, was der Nutzer gefragt hat? Ein Modell kann perfekt treu (jede Behauptung ist begruendet) sein und trotzdem die Frage umgehen oder eine leicht andere Frage als die gestellte beantworten. Messe das mit einem semantischen Aehnlichkeitsscore zwischen Frage und Antwort, oder mit einem Judge-Prompt, der bewertet, ob die Antwort die Nutzerabsicht aufloest.
3. Kontext-Relevanz - sind die abgerufenen Chunks tatsaechlich relevant fuer die Frage? Das ist eine Retrieval-Qualitaetsmetrik, keine Generierungsqualitaetsmetrik. Wenn deine Kontext-Relevanz niedrig ist, ist deine Retrieval-Schicht unabhaengig davon, was das Modell mit dem schlechten Kontext macht, defekt. Verfolge das getrennt von der Antwortqualitaet, damit du weisst, ob du Retrieval oder Generierung optimieren musst.
4. End-to-End-Latenz - P50, P95, P99. RAG-Pipelines unter produktiver Last verhalten sich anders als beim Testen, weil Vektorspeicher kalte Caches haben, Reranker Aufwaermkosten haben und LLM-Anbieter Rate-Limits haben. Nimm die Latenz in dein Eval auf, damit du eine Regressions-Basislinie hast, nicht nur Qualitaets-Basislinien.
Das Aufbauen eines Testsets erfordert Disziplin. Du benotigst mindestens 50-100 Frage-Antwort-Paare, die aus realistischen Nutzeranfragen stammen, nicht aus Anfragen, die du dir beim Aufbau des Features ausgedacht hast. Der schnellste Weg, ein realistisches Testset aufzubauen, ist, die ersten zwei Wochen der Produktionsanfragen zu sammeln, eine repraesentative Auswahl zu treffen und die korrekten Antworten manuell zu annotieren. Ja, manuell. Synthetische Testsets, die von demselben LLM generiert wurden, das du evaluierst, sind zirkulaer und unzuverlaessig - das Modell wird bei seinen eigenen Fehlermustern gut abschneiden.
Fuehre dieses Framework bei jeder Aenderung an deiner Pipeline aus: bei jeder Prompt-Bearbeitung, jedem Chunk-Groessen-Experiment, jedem Embedding-Modellwechsel, jeder Reranker-Schwellwertanpassung. Eine Aenderung, die die Faithfulness verbessert, aber die Kontext-Relevanz verschlechtert, hat das Problem verlagert, nicht geloest.
Die Fehlermuster, die wir bei Audits tatsaechlich sehen
Wenn wir KI-Integrations-Audits an RAG-gestuetzten Produkten durchfuehren, haeufen sich die Probleme in einigen wiederkehrenden Mustern, die es wert sind, sie im Voraus zu kennen.
Versions-Verwirrung ist eines der schaedlichsten. Wenn dein Dokument-Korpus mehrere Versionen derselben Richtlinie, desselben Verfahrens oder derselben Spezifikation enthaelt, ruft deine RAG-Pipeline die Version ab, die die hoechste Embedding-Aehnlichkeit zur Anfrage aufweist - was moeglicherweise nicht die aktuelle Version ist. Das LLM antwortet selbstbewusst aus einer veralteten Quelle. Die Loesung besteht darin, Versions- oder Wirksamkeitsdatum-Metadaten in deinen Chunks zu platzieren und beim Retrieval zu filtern: Nur Chunks abrufen, bei denen effective_date = latest. Metadaten-Filterung in pgvector ist kostenguenstig, und diese einzelne Aenderung eliminiert eine grosse Klasse von selbstbewussten-aber-falschen Antworten.
Das verlorene Nadelproblem tritt auf, wenn eine kleine kritische Information - eine bestimmte Zahl, ein Schwellenwert, ein Name - in einem langen Chunk voll von umgebendem Kontext eingebettet ist. Das Embedding fuer den vollstaendigen Chunk signalisiert das spezifische Faktum nicht stark, sodass Anfragen, die auf dieses Faktum abzielen, ihn verfehlen werden. Hierarchisches Chunking loest das, aber auch das explizite Extrahieren hochwertiger strukturierter Daten (Zahlen, Daten, benannte Entitaeten) in einen separaten Retrieval-Pfad - manchmal ist die richtige Antwort eine SQL-Abfrage, keine Vektorsuche.
Prompt-Bleeding tritt auf, wenn du mehrere Chunks abrufst und diese widerspruechliche Informationen enthalten. Das Modell synthetisiert typischerweise ueber sie hinweg und erzeugt eine Antwort, die beide Quellen vermischt. Ohne Faithfulness-Evaluation wirst du das nie erkennen. Die Retrieval-Schicht sollte nahezu-doppelte Chunks deduplizieren, und deine Prompt-Vorlage sollte das Modell anweisen, Widerspruche zu melden, anstatt sie stillschweigend aufzuloesen.
Token-Budget-Kollaps ist ein stiller Killer im grossen Massstab. Deine Retrieval-Logik ruft 5 Chunks ab. Jeder Chunk ist 512 Token. Du hast einen System-Prompt, eine Nutzernachricht und Konversationsverlauf. Ploetzlich naherst du dich deinem Modell-Kontextlimit, und das Framework kuerzt stillschweigend die letzten beiden abgerufenen Chunks ab, bevor der Prompt gesendet wird. Das Modell sieht nie den relevantesten Kontext, und dein Eval-Framework (das mit kurzen Konversationen getestet hat) hat das nie bemerkt. Instrumentiere immer deine tatsaechliche Token-Nutzung in der Produktion und setze harte Limits fuer die abgerufene Kontextlaenge, bevor der Konversationsverlauf ihn wegkomprimiert.
Bevor du das naechste RAG-Feature auslieferst
Keines dieser Probleme ist exotisch. Chunking-Strategie, Reranking und Eval-Frameworks sind alle gut verstanden - die Luecke liegt meist darin, dass Teams nicht wissen, dass sie sie benoetigen, bis sie bereits ohne sie ausgeliefert haben.
Wenn du ein RAG-gestuetztes Produkt aufbaust oder wartest und eine unabhaengige Bewertung deiner Retrieval-Qualitaet vor dem naechsten Release moechtest, melde dich bei hello@wolf-tech.io oder starte eine Konversation unter wolf-tech.io. Wir koennen in der Regel die wirkungsvollsten Korrekturen innerhalb einer einzelnen Audit-Sitzung identifizieren und dir eine konkrete Vorher-Nachher-Basislinie aus dem Eval-Framework liefern.
Ein produktives KI-Feature, das halluziniert, ist kein KI-Problem - es ist ein Engineering-Problem. Und Engineering-Probleme haben Engineering-Loesungen.

