Integrare Milvus con WhyHow
Questa guida illustra come utilizzare whyhow.ai e Milvus Lite per effettuare il recupero basato su regole.
Panoramica
WhyHow è una piattaforma che fornisce agli sviluppatori gli elementi necessari per organizzare, contestualizzare e recuperare in modo affidabile i dati non strutturati per eseguire RAG complessi. Il pacchetto Rule-based Retrieval è un pacchetto Python sviluppato da WhyHow che consente di creare e gestire applicazioni di RAG (Retrieval Augmented Generation) con funzionalità di filtraggio avanzate.
Installazione
Prima di iniziare, installare tutti i pacchetti Python necessari per l'utilizzo successivo.
pip install --upgrade pymilvus, whyhow_rbr
Successivamente, è necessario inizializzare il client Milvus per implementare il Retrieval basato su regole utilizzando Milvus Lite.
from pymilvus import MilvusClient
# Milvus Lite local path
path="./milvus_demo.db" # random name for local milvus lite db path
# Initialize the ClientMilvus
milvus_client = ClientMilvus(path)
È possibile inizializzare il client Milvus anche attraverso Milvus Cloud.
from pymilvus import MilvusClient
# Milvus Cloud credentials
YOUR_MILVUS_CLOUD_END_POINT = "YOUR_MILVUS_CLOUD_END_POINT"
YOUR_MILVUS_CLOUD_TOKEN = "YOUR_MILVUS_CLOUD_TOKEN"
# Initialize the ClientMilvus
milvus_client = ClientMilvus(
milvus_uri=YOUR_MILVUS_CLOUD_END_POINT,
milvus_token=YOUR_MILVUS_CLOUD_TOKEN,
)
Creare la raccolta
Definire le variabili necessarie
# Define collection name
COLLECTION_NAME="YOUR_COLLECTION_NAME" # take your own collection name
# Define vector dimension size
DIMENSION=1536 # decide by the model you use
Aggiungere lo schema
Prima di inserire i dati nel database di Milvus Lite, è necessario definire il campo dati, che qui viene chiamato schema. Attraverso la creazione di un oggetto CollectionSchema
e l'aggiunta di un campo dati attraverso add_field()
, possiamo controllare il tipo di dati e le loro caratteristiche. Questo passo è obbligatorio prima di inserire qualsiasi dato in Milvus.
schema = milvus_client.create_schema(auto_id=True) # Enable id matching
schema = milvus_client.add_field(schema=schema, field_name="id", datatype=DataType.INT64, is_primary=True)
schema = milvus_client.add_field(schema=schema, field_name="embedding", datatype=DataType.FLOAT_VECTOR, dim=DIMENSION)
Creare un indice
Per ogni schema è meglio avere un indice, in modo che l'interrogazione sia molto più efficiente. Per creare un indice, occorre innanzitutto un oggetto index_params
e successivamente aggiungere altri dati dell'indice a questo oggetto IndexParams
.
# Start to indexing data field
index_params = milvus_client.prepare_index_params()
index_params = milvus_client.add_index(
index_params=index_params, # pass in index_params object
field_name="embedding",
index_type="AUTOINDEX", # use autoindex instead of other complex indexing method
metric_type="COSINE", # L2, COSINE, or IP
)
Questo metodo è un sottile wrapper attorno all'implementazione ufficiale di Milvus(documentazione ufficiale).
Creare la collezione
Dopo aver definito tutti i campi dati e averli indicizzati, dobbiamo creare la nostra collezione di database, in modo da poter accedere ai dati in modo rapido e preciso. Va detto che abbiamo inizializzato enable_dynamic_field
come true, in modo da poter caricare liberamente qualsiasi dato. Il costo è che l'interrogazione dei dati potrebbe essere inefficiente.
# Create Collection
milvus_client.create_collection(
collection_name=COLLECTION_NAME,
schema=schema,
index_params=index_params
)
Caricare i documenti
Dopo aver creato una raccolta, siamo pronti a popolarla con i documenti. In whyhow_rbr
questo viene fatto usando il metodo upload_documents
di MilvusClient
. Esso esegue i seguenti passaggi:
- Preelaborazione: Lettura e suddivisione in pezzi dei file PDF forniti.
- Incorporamento: Incorporazione di tutti i pezzi utilizzando un modello OpenAI.
- Inserimento: Caricamento delle incorporazioni e dei metadati su Milvus Lite.
# get pdfs
pdfs = ["harry-potter.pdf", "game-of-thrones.pdf"] # replace to your pdfs path
# Uploading the PDF document
milvus_client.upload_documents(
collection_name=COLLECTION_NAME,
documents=pdfs
)
Risposta alle domande
Ora possiamo finalmente passare alla generazione aumentata del reperimento.
# Search data and implement RAG!
res = milvus_client.search(
question='What food does Harry Potter like to eat?',
collection_name=COLLECTION_NAME,
anns_field='embedding',
output_fields='text'
)
print(res['answer'])
print(res['matches'])
Regole
Nell'esempio precedente, è stato considerato ogni singolo documento del nostro indice. Tuttavia, a volte potrebbe essere utile recuperare solo i documenti che soddisfano alcune condizioni predefinite (ad esempio, filename=harry-potter.pdf
). In whyhow_rbr
attraverso Milvus Lite, questo può essere fatto regolando i parametri di ricerca.
Una regola può controllare i seguenti attributi dei metadati
filename
nome del filepage_numbers
elenco di numeri interi corrispondenti ai numeri di pagina (indicizzazione 0)id
identificatore univoco di un chunk (questo è il filtro più "estremo")- Altre regole basate su espressioni booleane
# RULES(search on book harry-potter on page 8):
PARTITION_NAME='harry-potter' # search on books
page_number='page_number == 8'
# first create a partitions to store the book and later search on this specific partition:
milvus_client.crate_partition(
collection_name=COLLECTION_NAME,
partition_name=PARTITION_NAME # separate base on your pdfs type
)
# search with rules
res = milvus_client.search(
question='Tell me about the greedy method',
collection_name=COLLECTION_NAME,
partition_names=PARTITION_NAME,
filter=page_number, # append any rules follow the Boolean Expression Rule
anns_field='embedding',
output_fields='text'
)
print(res['answer'])
print(res['matches'])
In questo esempio, per prima cosa creiamo una partizione che memorizza i pdf relativi a Harry Potter e, attraverso la ricerca all'interno di questa partizione, possiamo ottenere le informazioni più dirette. Inoltre, applichiamo i numeri di pagina come filtro per specificare la pagina esatta su cui vogliamo effettuare la ricerca. Ricordare che il parametro filer deve seguire la regola booleana.
Pulire
Infine, dopo aver implementato tutte le istruzioni, è possibile ripulire il database chiamando drop_collection()
.
# Clean up
milvus_client.drop_collection(
collection_name=COLLECTION_NAME
)