Integrar Milvus con WhyHow
Esta guía muestra cómo utilizar whyhow.ai y Milvus Lite para llevar a cabo una recuperación basada en reglas.
Descripción general
WhyHow es una plataforma que proporciona a los desarrolladores los bloques de construcción que necesitan para organizar, contextualizar y recuperar de forma fiable datos no estructurados para realizar RAG complejas. El paquete Rule-based Retrieval es un paquete Python desarrollado por WhyHow que permite crear y gestionar aplicaciones de Generación Aumentada de Recuperación (RAG) con capacidades avanzadas de filtrado.
Instalación
Antes de empezar, instale todos los paquetes python necesarios para su uso posterior.
pip install --upgrade pymilvus, whyhow_rbr
A continuación, necesitamos inicializar el cliente Milvus para implementar la Recuperación Basada en Reglas utilizando 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)
También puede inicializar el cliente Milvus a través de 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,
)
Crear colección
Definir las variables necesarias
# 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
Añadir esquema
Antes de insertar cualquier dato en la base de datos de Milvus Lite, necesitamos definir primero el campo de datos, que aquí se llama esquema. A través de crear objeto CollectionSchema
y añadir campo de datos a través de add_field()
, podemos controlar nuestro tipo de datos y sus características. Este paso es obligatorio antes de insertar cualquier dato en 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)
Crear índice
Para cada esquema, es mejor tener un índice para que la consulta sea mucho más eficiente. Para crear un índice, primero necesitamos un index_params
y más tarde añadir más datos de índice en este objeto 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
)
Este método es una fina envoltura alrededor de la implementación oficial de Milvus(docs oficiales).
Crear colección
Después de definir todos los campos de datos e indexarlos, ahora necesitamos crear nuestra colección de base de datos para que podamos acceder a nuestros datos de forma rápida y precisa. Lo que hay que mencionar es que inicializamos el enable_dynamic_field
para que sea true y así poder cargar cualquier dato libremente. El coste es que la consulta de datos puede ser ineficiente.
# Create Collection
milvus_client.create_collection(
collection_name=COLLECTION_NAME,
schema=schema,
index_params=index_params
)
Cargar documentos
Después de crear una colección, estamos listos para llenarla de documentos. En whyhow_rbr
esto se hace usando el método upload_documents
de MilvusClient
. Realiza los siguientes pasos bajo el capó:
- Preprocesamiento: Lectura y división en trozos de los archivos PDF proporcionados.
- Incrustación: Incrustar todos los trozos utilizando un modelo OpenAI.
- Inserción: Carga de las incrustaciones y los metadatos en 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
)
Respuesta a preguntas
Ahora por fin podemos pasar a la generación aumentada de recuperación.
# 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'])
Reglas
En el ejemplo anterior, se han tenido en cuenta todos y cada uno de los documentos de nuestro índice. Sin embargo, a veces puede ser beneficioso recuperar sólo los documentos que satisfacen algunas condiciones predefinidas (por ejemplo, filename=harry-potter.pdf
). En whyhow_rbr
a través de Milvus Lite, esto puede hacerse ajustando los parámetros de búsqueda.
Una regla puede controlar los siguientes atributos de metadatos
filename
nombre del archivopage_numbers
lista de números enteros correspondientes a los números de página (indexación 0)id
identificador único de un chunk (este es el filtro más "extremo")- Otras reglas basadas en expresiones booleanas
# 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'])
En este ejemplo, primero creamos una partición que almacena los pdf relacionados con harry-potter, y mediante la búsqueda dentro de esta partición, podemos obtener la información más directa. Además, aplicamos números de página como filtro para especificar la página exacta en la que deseamos buscar. Recuerda que el parámetro filer debe seguir la regla booleana.
Limpieza
Por último, después de implementar todas las instrucciones, puedes limpiar la base de datos llamando a drop_collection()
.
# Clean up
milvus_client.drop_collection(
collection_name=COLLECTION_NAME
)