Open In Colab GitHub Repository

Usare la ricerca full-text con LlamaIndex e Milvus

Laricerca full-text utilizza la corrispondenza esatta delle parole chiave, spesso sfruttando algoritmi come BM25 per classificare i documenti in base alla rilevanza. Nei sistemi RAG (Retrieval-Augmented Generation), questo metodo recupera il testo pertinente per migliorare le risposte generate dall'intelligenza artificiale.

Nel frattempo, la ricerca semantica interpreta il significato contestuale per fornire risultati più ampi. La combinazione di entrambi gli approcci crea una ricerca ibrida che migliora il reperimento delle informazioni, soprattutto nei casi in cui un singolo metodo è insufficiente.

Con l'approccio Sparse-BM25 di Milvus 2.5, il testo grezzo viene convertito automaticamente in vettori sparsi. Questo elimina la necessità di generare manualmente l'embedding sparse e consente una strategia di ricerca ibrida che bilancia la comprensione semantica con la pertinenza delle parole chiave.

In questo tutorial imparerete a usare LlamaIndex e Milvus per costruire un sistema RAG usando la ricerca full-text e la ricerca ibrida. Inizieremo con l'implementazione della sola ricerca full-text e poi la miglioreremo integrando la ricerca semantica per ottenere risultati più completi.

Prima di procedere con questa esercitazione, assicuratevi di conoscere la ricerca full-text e le basi dell'uso di Milvus in LlamaIndex.

Prerequisiti

Installare le dipendenze

Prima di iniziare, assicuratevi di aver installato le seguenti dipendenze:

$ $pip install llama-index-vector-stores-milvus
$ $pip install llama-index-embeddings-openai
$ $pip install llama-index-llms-openai

Se si utilizza Google Colab, potrebbe essere necessario riavviare il runtime (andare al menu "Runtime" nella parte superiore dell'interfaccia e selezionare "Riavvia sessione" dal menu a discesa).

Impostazione degli account

Questa esercitazione utilizza OpenAI per l'incorporazione del testo e la generazione delle risposte. È necessario preparare la chiave API di OpenAI.

import openai

openai.api_key = "sk-"

Per utilizzare l'archivio vettoriale Milvus, specificare il server Milvus URI (e facoltativamente TOKEN). Per avviare un server Milvus, è possibile configurarlo seguendo la guida all'installazione di Milvus o semplicemente provando gratuitamente Zilliz Cloud.

La ricerca full-text è attualmente supportata in Milvus Standalone, Milvus Distributed e Zilliz Cloud, ma non ancora in Milvus Lite (prevista in futuro). Per ulteriori informazioni, contattare support@zilliz.com.

URI = "http://localhost:19530"
# TOKEN = ""

Scaricare dati di esempio

Eseguire i seguenti comandi per scaricare documenti di esempio nella directory "data/paul_graham":

$ 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]

L'integrazione della ricerca full-text in un sistema RAG bilancia la ricerca semantica con un recupero preciso e prevedibile basato su parole chiave. Si può anche scegliere di utilizzare solo la ricerca full text, anche se si consiglia di combinare la ricerca full text con la ricerca semantica per ottenere risultati migliori. Qui, a scopo dimostrativo, mostreremo la sola ricerca full text e la ricerca ibrida.

Per iniziare, utilizzare SimpleDirectoryReaderLoad per caricare il saggio "What I Worked On" di 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 ...

Ricerca a tutto testo con BM25

MilvusVectorStore di LlamaIndex supporta la ricerca full-text, consentendo un efficiente recupero basato su parole chiave. Utilizzando una funzione integrata come sparse_embedding_function, applica il punteggio BM25 per classificare i risultati della ricerca.

In questa sezione, dimostreremo come implementare un sistema RAG utilizzando BM25 per la ricerca full-text.

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.

Il codice sopra riportato inserisce documenti di esempio in Milvus e costruisce un indice per abilitare il ranking BM25 per la ricerca full-text. Disabilita il dense embedding e utilizza BM25BuiltInFunction con parametri predefiniti.

È possibile specificare i campi di input e di output nei parametri di BM25BuiltInFunction:

  • input_field_names (str): Il campo di testo di input (predefinito: "text"). Indica il campo di testo a cui si applica l'algoritmo BM25. Modificare questo parametro se si utilizza una raccolta propria con un nome di campo di testo diverso.
  • output_field_names (str): Il campo in cui vengono memorizzati gli output di questa funzione BM25 (default: "sparse_embedding").

Una volta impostato l'archivio vettoriale, è possibile eseguire query di ricerca full-text utilizzando Milvus con la modalità di interrogazione "sparse" o "text_search":

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.

Personalizzare l'analizzatore di testo

Gli analizzatori svolgono un ruolo fondamentale nella ricerca full-text, suddividendo le frasi in token ed eseguendo l'elaborazione lessicale, come l'eliminazione di stemming e stop-word. In genere sono specifici per la lingua. Per maggiori dettagli, consultare la Guida agli analizzatori di Milvus.

Milvus supporta due tipi di analizzatori: Analizzatori integrati e Analizzatori personalizzati. Per impostazione predefinita, BM25BuiltInFunction utilizza l'analizzatore standard incorporato, che tokenizza il testo in base alla punteggiatura.

Per utilizzare un analizzatore diverso o personalizzare quello esistente, è possibile passare un valore all'argomento analyzer_params:

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,
)

Ricerca ibrida con Reranker

Un sistema di ricerca ibrido combina la ricerca semantica e la ricerca full-text, ottimizzando le prestazioni di recupero in un sistema RAG.

L'esempio seguente utilizza l'embedding OpenAI per la ricerca semantica e BM25 per la ricerca full-text:

# 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
)

Come funziona

Questo approccio memorizza i documenti in una collezione Milvus con entrambi i campi vettoriali:

  • embedding: Dense embeddings generate dal modello di embedding OpenAI per la ricerca semantica.
  • sparse_embedding: embeddings sparsi calcolati con BM25BuiltInFunction per la ricerca full-text.

Inoltre, abbiamo applicato una strategia di reranking utilizzando "RRFRanker" con i suoi parametri predefiniti. Per personalizzare il reranker, è possibile configurare hybrid_ranker e hybrid_ranker_params seguendo la Guida al reranking di Milvus.

Ora testiamo il sistema RAG con una query di esempio:

# 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.

Questo approccio ibrido garantisce risposte più accurate e consapevoli del contesto in un sistema RAG, sfruttando sia il reperimento semantico che quello basato sulle parole chiave.

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
Feedback

Questa pagina è stata utile?