Hybride Suche: BM25 + vectoriel
Die hybride Suche führt parallel eine Stichwortsuche (BM25) und eine Vektorsuche für dieselbe Frage aus und führt anschließend die beiden Ranglisten zusammen, meist mittels Reciprocal Rank Fusion (RRF). Sie gleicht Fälle aus, in denen das Embedding versagt (Kennungen, Eigennamen, seltene Begriffe), ohne das Verständnis von Paraphrasen einzubüßen. Qdrant, Weaviate und Elasticsearch unterstützen sie nativ; mit ChromaDB lässt sie sich in dreißig Zeilen Python implementieren.
Eine Vektordatenbank findet Bedeutungen, keine exakten Zeichenfolgen: Eine Referenz wie „RG/2024-117“ oder eine Ticketnummer entgeht ihr. Umgekehrt versteht die Stichwortsuche nicht, dass „automobile“ und „voiture“ dasselbe bezeichnen. Dieser Leitfaden zeigt, wie sich beide Ansätze kombinieren lassen, welche Fusionsmethode zu wählen ist, was Qdrant und Weaviate tun und welche Falle bei der Tokenisierung französischer Texte den BM25-Teil unbemerkt ruiniert.
#Warum rein vektorbasierte Suche bei manchen Fragen scheitert
Die Vektorsuche wandelt jede Textpassage in einen Vektor um, der ihren allgemeinen Sinn zusammenfasst, und gibt dann die Passagen zurück, deren Vektoren dem Vektor der Frage am nächsten liegen. Diese Kompression funktioniert sehr gut bei Paraphrasen, aber schlecht bei allem, was wortgetreu gefunden werden muss: einer Kennung, einem Fehlercode, einem Personennamen, einem internen Kürzel. Beim Embedding ähneln sich „PROD-4817“ und „PROD-4871“, sodass ein unpassendes Ticket vor dem richtigen erscheinen kann. Die hybride Suche begegnet diesem Problem: Sie ergänzt eine zweite Rangfolge, die auf dem exakten Vorkommen der Wörter beruht, und führt beide zusammen, sodass jede Methode die blinden Flecken der anderen ausgleicht.
- Identifikatoren und Referenzen
- Ticketnummern, Aktennummern, Vertragsnummern, SKU, Fehlercodes: Sie sind Zeichenketten, die ein Embedding nicht zuverlässig speichert und die BM25 sofort wiederfindet, sobald sie im Abschnitt vorkommen.
- Seltene Fachbegriffe
- Seltene medizinische, juristische oder technische Begriffe: Ein seltenes Wort hat in BM25 ein hohes Gewicht, während sein Embedding unscharf sein kann.
- Sehr kurze Anfragen
- Zwei Wörter wie „Rechnung 2024“ liefern wenig Material für ein Embedding; Schlüsselwörter hingegen werden unverändert miteinander verglichen.
- Paraphrasen und Umformulierungen
- Der umgekehrte Fall: „befristeter Arbeitsvertrag“ und „CDD“ oder „Auto“ und „Automobil“ haben kein Wort gemeinsam; nur die Vektorsuche stellt eine Verbindung zwischen ihnen her.
#BM25: Was die Stichwortsuche leistet
Ihre Dokumente, Ihre KI: ein zuverlässiges lokales RAG für Ihre PDFs, Notizen und E-Mails – ohne Daten in die Cloud zu senden.
- Lebenslanger Online-Zugang
- PDF + Dateien
- Erstattung binnen 30 Tagen
BM25 ist die lexikalische Rankingfunktion, die Lucene, Elasticsearch und OpenSearch verwenden und die SQLite in seinem FTS5-Modul anbietet (die Dokumentation beschreibt die Funktion bm25() als eine Funktion, die einen Wert zurückgibt, der angibt, wie gut die Zeile zur Suchanfrage passt). Sie beruht auf drei Ideen: Ein seltenes Wort hat mehr Gewicht als ein häufiges, ein wiederholtes Wort zählt ab einer bestimmten Anzahl von Vorkommen immer weniger, und eine lange Passage wird gegenüber einer kurzen leicht benachteiligt. Der Parameter k1 steuert diese Sättigung: Laut der Beschreibung von Elastic begrenzt er den Einfluss, den ein einzelner Begriff der Suchanfrage auf den Score eines Dokuments haben kann.
- Stärken
- Seltene Begriffe, Kennungen, kurze Suchanfragen, Fachvokabular, kein Modell, das geladen oder trainiert werden muss, kompakter Index, nachvollziehbares Ergebnis (man weiß, welches Wort den betreffenden Abschnitt in den Suchergebnissen nach oben gebracht hat).
- Schwächen
- Synonyme, Umformulierungen, Paraphrasen, Tippfehler; ohne Lemmatisierung sind „signé“ und „signature“ zwei verschiedene Wörter.
- Voraussetzungen
- Eine sorgfältige Tokenisierung: Umwandlung in Kleinbuchstaben, Entfernung von Akzenten, gegebenenfalls Stammformreduktion (Stemming). Genau hier machen die meisten selbst entwickelten Implementierungen Fehler, siehe unten.
#Hybride Suche: das Prinzip
Beide Suchen werden für dieselbe Frage ausgeführt. Jede liefert ihre Liste von Kandidaten (20 bis 50 Passagen), anschließend werden die beiden Listen zu einer einzigen Rangliste zusammengeführt. Der Vorteil ergibt sich aus einer einfachen Beobachtung: Passagen, die in beiden Listen erscheinen, sind fast immer relevant, und jede Methode liefert zusätzlich Passagen, die die andere übersehen hat. Weaviate definiert die hybride Suche so: Sie kombiniert die Ergebnisse einer Vektorsuche und einer Stichwortsuche, indem sie die beiden Ergebnismengen zusammenführt, wobei sich die Fusionsmethode und die relativen Gewichtungen konfigurieren lassen. Der messbare Vorteil hängt vom Korpus und den Fragen ab: Keine allgemeine Zahl ist verlässlich, und Sie müssen den Vorteil anhand Ihrer eigenen Dokumente messen (siehe unten).
#Ohne Normalisierung fusionieren: Reciprocal Rank Fusion
Der klassische Fehler besteht darin, die Rohwerte der Scores zu addieren. Ein BM25-Score ist eine positive Zahl ohne obere Grenze; ein Score für Vektorähnlichkeit ist eine Distanz oder ein Kosinuswert in einem begrenzten Wertebereich: Die beiden Skalen sind nicht vergleichbar, und schon die kleinste Änderung am Korpus verschiebt sie. Reciprocal Rank Fusion umgeht das Problem, indem sie ausschließlich die Rangpositionen verwendet. Die Elasticsearch-Dokumentation beschreibt sie als eine Methode, die keinerlei Abstimmung erfordert und deren Relevanzmaße nicht miteinander in Beziehung stehen müssen.
Eine Textpassage, die bei BM25 auf Platz eins und bei der Vektorsuche auf Platz fünf steht, erhält 1/61 + 1/65, also etwa 0,0318; eine Textpassage auf Platz fünfzehn in beiden Listen erhält 2/75, also etwa 0,0267. Die Konstante k schwächt den Vorteil des allerersten Rangs ab: Je größer sie ist, desto stärker zählen weiter hinten liegende Ränge. Elasticsearch dokumentiert diese Konstante unter dem Namen rank_constant mit einem Standardwert von 60 sowie eine Fenstergröße (rank_window_size), die die Länge jeder Liste vor der Zusammenführung festlegt. Ein größeres Fenster verbessert die Relevanz auf Kosten der Performance, erläutert die Dokumentation.
#Und die Score-Fusion?
Einige Suchsysteme bieten eine Alternative: die Scores jeder Liste normalisieren und anschließend gewichtet zusammenführen. Weaviate dokumentiert beide Methoden, eine rangbasierte Zusammenführung und eine Zusammenführung anhand relativer Scores. Letztere ist seit Version 1.24 die Standardmethode; sie ist erforderlich, um autocut mit dem Hybridoperator zu verwenden. Qdrant bietet RRF und DBSF an. Letztere behält die Rohscores bei, normalisiert jedoch vor der Zusammenführung deren Verteilung (Mittelwert und Standardabweichung). Die rangbasierte Zusammenführung ist robuster, wenn die Verteilung der Scores unbekannt ist; die Zusammenführung anhand von Scores ermöglicht eine feinere Abstimmung, wenn Messungen möglich sind.
#Welches Tool: Suchmaschinen mit nativer Unterstützung für hybride Suche
| Tool | Native hybride Suche | Fusion | Einstellung der Gewichtung |
|---|---|---|---|
| Qdrant | Ja, über die Query-API (seit Version 1.10 verfügbar) | RRF oder DBSF | Gewichtung pro Abfrage und Konstante k in neueren Versionen einstellbar |
| Weaviate | Ja, mit dem Operator hybrid | Relative Ränge oder Scores (Standard ab Version 1.24) | Parameter alpha: 1 = rein vektorbasiert, 0 = rein schlüsselwortbasiert |
| Elasticsearch | Ja, rrf-Retriever | RRF | rank_constant (Standardwert: 60) und rank_window_size |
| SQLite FTS5 + Vektorerweiterung | Muss zusammengesetzt werden | Noch zu schreiben | Liegt bei Ihnen |
| ChromaDB + rank_bm25 | In Python zusammenzustellen | Zu schreiben (RRF in 6 Zeilen) | Liegt bei Ihnen |
Der grundlegende Unterschied liegt nicht in der Zusammenführung selbst, die sich mit wenigen Codezeilen umsetzen lässt, sondern im Index: Eine Suchengine mit nativer Unterstützung hält beide Indizes gemeinsam aktuell, während eine selbst gebaute Lösung den BM25-Index im Arbeitsspeicher hält und ihn bei jedem neu hinzugefügten Dokument neu aufbauen muss. Für ein Korpus mit einigen Tausend Textabschnitten, das sich selten ändert, reicht die selbst gebaute Lösung völlig aus. Bei größeren Korpora oder sobald sich die Dokumente täglich ändern, vermeidet eine Suchengine mit nativer Unterstützung Inkonsistenzen zwischen den beiden Indizes. Die Anleitung zu Weaviate stellt dieses Tool ausführlich vor.
#Eigenentwicklung: ChromaDB, rank_bm25 und RRF
Der folgende Code kombiniert die drei Bausteine. Er behebt einen häufigen Fehler in Beispielen: Die Normalisierungsfunktion muss vor dem Filtern die diakritischen Zeichen entfernen, sonst teilt jeder akzentuierte Buchstabe ein Wort in zwei Teile.
Zwei praktische Vorsichtsmaßnahmen. Erstens müssen die Kennungen in beiden Indizes identisch sein: Hier dient der Listenindex, in eine Zeichenkette umgewandelt, als Chroma-Kennung. Zweitens geht der BM25-Index im Arbeitsspeicher beim Beenden des Programms verloren: Bauen Sie ihn beim Start neu auf, was bei Zehntausenden von Textpassagen einige Sekunden dauert, oder speichern Sie die Dokumentenliste neben der Datenbank.
#Das Verhältnis zwischen BM25 und Vektorsuche einstellen
Standardmäßig gewichtet RRF beide Listen gleich. Wenn Ihr Korpus viele Referenzen enthält (Rechtsprechung, Tickets, Kataloge), geben Sie BM25 mehr Gewicht; wenn die Fragen dialogorientiert sind, behalten Sie die gleiche Gewichtung bei oder bevorzugen Sie die Vektorsuche. In der vorherigen Funktion genügt es, weights=[0.6, 0.4] zu übergeben, um BM25 mit 60 % zu gewichten. Qdrant ermöglicht dieselbe Einstellung: Laut Dokumentation beträgt das Gewicht jeder Abfrage standardmäßig 1, wodurch sich wieder die ursprüngliche RRF-Formel ergibt, und die Konstante k lässt sich in neueren Versionen einstellen. In Weaviate stellt man alpha ein: 1 entspricht einer reinen Vektorsuche, 0 einer reinen Schlüsselwortsuche.
| Korpus und Fragen | Anfangsgewichtung BM25 / Vektorsuche | Was Sie beobachten |
|---|---|---|
| Referenzen, Nummern, Eigennamen (Recht, Tickets, Kataloge) | 60 / 40 | Werden Fragen nach Identifikator zuerst zurückgegeben? |
| Ausformulierte Dokumentation, Fragen in natürlicher Sprache | 40 / 60 | Wird bei paraphrasierten Anfragen der richtige Abschnitt gefunden? |
| Gemischtes oder unbekanntes Korpus | 50 / 50 | Recall@5 bei 30 bis 50 echten Fragen |
| Abkürzungen und Fachbegriffe | 55 / 45, mit einem Synonymwörterbuch für BM25 | Finden die Abkürzung und die ausgeschriebene Form dieselbe Passage? |
#Nach der Fusion: Reranker hinzufügen
Die Fusion liefert eine vielfältigere Kandidatenmenge als jede Methode allein. Ein Reranker kann diese Menge anschließend sortieren, indem er jeden Abschnitt zusammen mit der Frage liest: Die beiden Techniken lassen sich kombinieren. Der übliche Ablauf ist die hybride Suche, dann die Fusion, dann ein Reranker für die ersten 20 bis 50 Ergebnisse und schließlich die Aufnahme der 3 bis 5 besten Abschnitte in den Prompt. Der Leitfaden zum Reranker erläutert diesen letzten Schritt im Detail, und der Leitfaden zum Chunking erklärt, warum die Länge der Abschnitte sowohl BM25 als auch die Embeddings so stark beeinflusst.
#Häufige Fragen zu hybrider Suche
Was ist die hybride Suche in einem RAG?+
Sollten BM25- und Vektor-Scores vor der Addition normalisiert werden?+
Welchen Wert für k sollte man bei RRF wählen?+
Kann man mit ChromaDB eine hybride Suche durchführen?+
Verlangsamt die hybride Suche die Abfragen erheblich?+
Wie kann man entscheiden, ob der hybride Ansatz für meine Dokumente sinnvoll ist?+
- Einen Reranker in die Pipeline integrieren
- Chunking-Strategien
- Weaviate: hybride Suche und Mandantenfähigkeit
- Lokales RAG mit ChromaDB und Ollama
- Die besten Embedding-Modelle für Französisch
- Quelle: Qdrant, hybride Abfragen
- Quelle: Weaviate, hybride Suche
- Quelle: Elasticsearch, Reciprocal Rank Fusion
- Quelle: SQLite FTS5, Funktion bm25()
Haben Sie Feedback, einen Fehler entdeckt oder möchten Sie etwas präzisieren? Geben Sie uns Bescheid – so wird der Guide für alle besser.