Verwendung der Volltextsuche mit LlamaIndex und Milvus
DieVolltextsuche verwendet exakte Schlüsselwortabgleiche und nutzt oft Algorithmen wie BM25, um Dokumente nach Relevanz zu ordnen. In Retrieval-Augmented Generation (RAG) -Systemen wird mit dieser Methode relevanter Text abgerufen, um die von der KI generierten Antworten zu verbessern.
In der Zwischenzeit interpretiert die semantische Suche die kontextuelle Bedeutung, um umfassendere Ergebnisse zu liefern. Durch die Kombination beider Ansätze entsteht eine hybride Suche, die das Abrufen von Informationen verbessert - insbesondere in Fällen, in denen eine einzelne Methode nicht ausreicht.
Mit dem Sparse-BM25-Ansatz von Milvus 2.5 wird der Rohtext automatisch in Sparse-Vektoren umgewandelt. Dies macht die manuelle Erzeugung von Sparse Embedding überflüssig und ermöglicht eine hybride Suchstrategie, die ein Gleichgewicht zwischen semantischem Verständnis und Schlüsselwortrelevanz schafft.
In diesem Tutorial lernen Sie, wie Sie mit LlamaIndex und Milvus ein RAG-System mit Volltextsuche und hybrider Suche aufbauen können. Wir beginnen mit der Implementierung einer reinen Volltextsuche und erweitern diese dann durch die Integration einer semantischen Suche für umfassendere Ergebnisse.
Bevor Sie mit diesem Tutorial fortfahren, stellen Sie sicher, dass Sie mit der Volltextsuche und den Grundlagen der Verwendung von Milvus in LlamaIndex vertraut sind.
Voraussetzungen
Abhängigkeiten installieren
Bevor Sie beginnen, sollten Sie sicherstellen, dass Sie die folgenden Abhängigkeiten installiert haben:
$ $pip install llama-index-vector-stores-milvus
$ $pip install llama-index-embeddings-openai
$ $pip install llama-index-llms-openai
Wenn Sie Google Colab verwenden, müssen Sie möglicherweise die Runtime neu starten (navigieren Sie zum Menü "Runtime" am oberen Rand der Benutzeroberfläche und wählen Sie "Restart session" aus dem Dropdown-Menü).
Konten einrichten
Dieses Tutorial verwendet OpenAI für Texteinbettungen und die Generierung von Antworten. Sie müssen den OpenAI-API-Schlüssel vorbereiten.
import openai
openai.api_key = "sk-"
Um den Milvus-Vektorspeicher zu verwenden, geben Sie Ihren Milvus-Server URI (und optional mit der TOKEN) an. Um einen Milvus-Server zu starten, können Sie einen Milvus-Server einrichten, indem Sie der Milvus-Installationsanleitung folgen oder einfach Zilliz Cloud kostenlos ausprobieren.
Die Volltextsuche wird derzeit in Milvus Standalone, Milvus Distributed und Zilliz Cloud unterstützt, aber noch nicht in Milvus Lite (für eine zukünftige Implementierung geplant). Wenden Sie sich an support@zilliz.com für weitere Informationen.
URI = "http://localhost:19530"
# TOKEN = ""
Download von Beispieldaten
Führen Sie die folgenden Befehle aus, um Beispieldokumente in das Verzeichnis "data/paul_graham" herunterzuladen:
$ mkdir -p 'data/paul_graham/'
$ $wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/docs/examples/data/paul_graham/paul_graham_essay.txt' -O 'data/paul_graham/paul_graham_essay.txt'
--2025-03-27 07:49:01-- https://raw.githubusercontent.com/run-llama/llama_index/main/docs/docs/examples/data/paul_graham/paul_graham_essay.txt
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 75042 (73K) [text/plain]
Saving to: ‘data/paul_graham/paul_graham_essay.txt’
data/paul_graham/pa 100%[===================>] 73.28K --.-KB/s in 0.07s
2025-03-27 07:49:01 (1.01 MB/s) - ‘data/paul_graham/paul_graham_essay.txt’ saved [75042/75042]
RAG mit Volltextsuche
Die Integration der Volltextsuche in ein RAG-System schafft ein Gleichgewicht zwischen semantischer Suche und präzisem und vorhersehbarem stichwortbasiertem Retrieval. Sie können sich auch dafür entscheiden, nur die Volltextsuche zu verwenden, es wird jedoch empfohlen, die Volltextsuche mit der semantischen Suche zu kombinieren, um bessere Suchergebnisse zu erzielen. Zu Demonstrationszwecken zeigen wir hier die Volltextsuche allein und die hybride Suche.
Um zu beginnen, laden Sie mit SimpleDirectoryReaderLoad den Aufsatz "What I Worked On" von Paul Graham:
from llama_index.core import SimpleDirectoryReader
documents = SimpleDirectoryReader("./data/paul_graham/").load_data()
# Let's take a look at the first document
print("Example document:\n", documents[0])
Example document:
Doc ID: 16b7942f-bf1a-4197-85e1-f31d51ea25a9
Text: What I Worked On February 2021 Before college the two main
things I worked on, outside of school, were writing and programming. I
didn't write essays. I wrote what beginning writers were supposed to
write then, and probably still are: short stories. My stories were
awful. They had hardly any plot, just characters with strong feelings,
which I ...
Volltextsuche mit BM25
LlamaIndex's MilvusVectorStore unterstützt die Volltextsuche und ermöglicht eine effiziente stichwortbasierte Suche. Unter Verwendung einer eingebauten Funktion wie sparse_embedding_function wird das BM25-Scoring angewendet, um die Suchergebnisse zu bewerten.
In diesem Abschnitt wird demonstriert, wie ein RAG-System mit BM25 für die Volltextsuche implementiert werden kann.
from llama_index.core import VectorStoreIndex, StorageContext
from llama_index.vector_stores.milvus import MilvusVectorStore
from llama_index.vector_stores.milvus.utils import BM25BuiltInFunction
from llama_index.core import Settings
# Skip dense embedding model
Settings.embed_model = None
# Build Milvus vector store creating a new collection
vector_store = MilvusVectorStore(
uri=URI,
# token=TOKEN,
enable_dense=False,
enable_sparse=True, # Only enable sparse to demo full text search
sparse_embedding_function=BM25BuiltInFunction(),
overwrite=True,
)
# Store documents in Milvus
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(documents, storage_context=storage_context)
Embeddings have been explicitly disabled. Using MockEmbedding.
Der obige Code fügt Beispieldokumente in Milvus ein und baut einen Index auf, um BM25-Ranking für die Volltextsuche zu ermöglichen. Er deaktiviert die dichte Einbettung und verwendet BM25BuiltInFunction mit Standardparametern.
Sie können die Eingabe- und Ausgabefelder in den BM25BuiltInFunction Parametern angeben:
input_field_names (str): Das Eingabetextfeld (Standard: "text"). Es gibt an, auf welches Textfeld der BM25-Algorithmus angewendet wird. Ändern Sie dies, wenn Sie eine eigene Sammlung mit einem anderen Textfeldnamen verwenden.output_field_names (str): Das Feld, in dem die Ausgaben dieser BM25-Funktion gespeichert werden (Standardwert: "sparse_embedding").
Sobald der Vektorspeicher eingerichtet ist, können Sie mit Milvus Volltextsuchanfragen mit dem Abfragemodus "sparse" oder "text_search" durchführen:
import textwrap
query_engine = index.as_query_engine(
vector_store_query_mode="sparse", similarity_top_k=5
)
answer = query_engine.query("What did the author learn at Viaweb?")
print(textwrap.fill(str(answer), 100))
The author learned several important lessons at Viaweb. They learned about the importance of growth
rate as the ultimate test of a startup, the value of building stores for users to understand retail
and software usability, and the significance of being the "entry level" option in a market.
Additionally, they discovered the accidental success of making Viaweb inexpensive, the challenges of
hiring too many people, and the relief felt when the company was acquired by Yahoo.
Anpassen des Textanalysators
Analyzer spielen eine wichtige Rolle bei der Volltextsuche, indem sie Sätze in Token zerlegen und lexikalische Verarbeitungen durchführen, z. B. Stemming und Stoppwortentfernung. Sie sind in der Regel sprachspezifisch. Weitere Einzelheiten finden Sie im Milvus Analyzer Guide.
Milvus unterstützt zwei Arten von Analyzern: Eingebaute Analyzer und benutzerdefinierte Analyzer. Standardmäßig verwendet BM25BuiltInFunction den standardmäßig eingebauten Analyzer, der Text auf der Grundlage von Interpunktion tokenisiert.
Um einen anderen Analyzer zu verwenden oder den vorhandenen anzupassen, können Sie dem Argument analyzer_params einen Wert übergeben:
bm25_function = BM25BuiltInFunction(
analyzer_params={
"tokenizer": "standard",
"filter": [
"lowercase", # Built-in filter
{"type": "length", "max": 40}, # Custom cap size of a single token
{"type": "stop", "stop_words": ["of", "to"]}, # Custom stopwords
],
},
enable_match=True,
)
Hybride Suche mit Reranker
Ein hybrides Suchsystem kombiniert semantische Suche und Volltextsuche und optimiert die Suchleistung in einem RAG-System.
Das folgende Beispiel verwendet OpenAI Embedding für die semantische Suche und BM25 für die Volltextsuche:
# Create index over the documnts
vector_store = MilvusVectorStore(
uri=URI,
# token=TOKEN,
# enable_dense=True, # enable_dense defaults to True
dim=1536,
enable_sparse=True,
sparse_embedding_function=BM25BuiltInFunction(),
overwrite=True,
# hybrid_ranker="RRFRanker", # hybrid_ranker defaults to "RRFRanker"
# hybrid_ranker_params={}, # hybrid_ranker_params defaults to {}
)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(
documents,
storage_context=storage_context,
embed_model="default", # "default" will use OpenAI embedding
)
So funktioniert es
Bei diesem Ansatz werden Dokumente in einer Milvus-Sammlung mit beiden Vektorfeldern gespeichert:
embedding: Dichte Einbettungen, die durch das OpenAI-Einbettungsmodell für die semantische Suche erzeugt werden.sparse_embedding: Sparse Embeddings, die mit BM25BuiltInFunction für die Volltextsuche berechnet werden.
Darüber hinaus haben wir eine Reranking-Strategie mit "RRFRanker" mit seinen Standardparametern angewendet. Um den Reranker anzupassen, können Sie hybrid_ranker und hybrid_ranker_params gemäß dem Milvus Reranking Guide konfigurieren.
Nun wollen wir das RAG-System mit einer Beispielabfrage testen:
# Query
query_engine = index.as_query_engine(
vector_store_query_mode="hybrid", similarity_top_k=5
)
answer = query_engine.query("What did the author learn at Viaweb?")
print(textwrap.fill(str(answer), 100))
The author learned several important lessons at Viaweb. These included the importance of
understanding growth rate as the ultimate test of a startup, the impact of hiring too many people,
the challenges of being at the mercy of investors, and the relief experienced when Yahoo bought the
company. Additionally, the author learned about the significance of user feedback, the value of
building stores for users, and the realization that growth rate is crucial for the long-term success
of a startup.
Dieser hybride Ansatz gewährleistet genauere, kontextbezogene Antworten in einem RAG-System, indem er sowohl die semantische als auch die schlagwortbasierte Suche nutzt.