Danza entre incrustaciones densas y dispersas: habilitación de la búsqueda híbrida en LangChain-Milvus | Omri Levy y Ohad Eytan
Imagen del autor

Si intercambia las consultas entre los dos ejemplos anteriores y usa cada una con la incrustación de la otra, ambas producirán un resultado incorrecto. Esto demuestra que cada método tiene sus puntos fuertes pero también sus puntos débiles. La búsqueda híbrida combina los dos, con el objetivo de aprovechar lo mejor de ambos mundos. Al indexar datos con incrustaciones densas y escasas, podemos realizar búsquedas que consideren tanto la relevancia semántica como la concordancia de palabras clave, equilibrando los resultados en función de ponderaciones personalizadas. Nuevamente, la implementación interna es más complicada, pero langchain-milvus hace que su uso sea bastante sencillo. Veamos cómo funciona esto:

vector_store = Milvus(
embedding_function=[
sparse_embedding,
dense_embedding,
],
connection_args={"uri": "./milvus_hybrid.db"},
auto_id=True,
)
vector_store.add_texts(documents)

En esta configuración, se aplican incrustaciones tanto densas como escasas. Probemos la búsqueda híbrida con igual ponderación:

query = "Does Hot cover weather changes during weekends?"
hybrid_output = vector_store.similarity_search(
query=query,
k=1,
ranker_type="weighted",
ranker_params={"weights": [0.49, 0.51]}, # Combine both results!
)
print(f"Hybrid search results:\n{hybrid_output[0].page_content}")

# output: Hybrid search results:
# In Israel, Hot is a TV provider that broadcast 7 days a week

Esto busca resultados similares utilizando cada función de incrustación, asigna un peso a cada puntuación y devuelve el resultado con la mejor puntuación ponderada. Podemos ver que con un poco más de peso en las incrustaciones densas, obtenemos el resultado que deseamos. Esto también es válido para la segunda consulta.

Si damos más peso a las incrustaciones densas, volveremos a obtener resultados no relevantes, como ocurre con las incrustaciones densas solas:

query = "When and where is Hot active?"
hybrid_output = vector_store.similarity_search(
query=query,
k=1,
ranker_type="weighted",
ranker_params={"weights": [0.2, 0.8]}, # Note -> the weights changed
)
print(f"Hybrid search results:\n{hybrid_output[0].page_content}")

# output: Hybrid search results:
# Today was very warm during the day but cold at night

Encontrar el equilibrio adecuado entre denso y disperso no es una tarea trivial y puede verse como parte de un problema más amplio de optimización de hiperparámetros. Hay investigaciones y herramientas en curso que intentan resolver este tipo de problemas en esta área, por ejemplo AutoAI de IBM para RAG.

Hay muchas más formas de adaptar y utilizar el enfoque de búsqueda híbrida. Por ejemplo, si cada documento tiene un título asociado, podría utilizar dos funciones de incrustación densa (posiblemente con modelos diferentes), una para el título y otra para el contenido del documento, y realizar una búsqueda híbrida en ambos índices. Milvus actualmente admite hasta 10 campos vectoriales diferentes, lo que brinda flexibilidad para aplicaciones complejas. También hay configuraciones adicionales para los métodos de indexación y reclasificación. puedes ver documentación milvus sobre los parámetros y opciones disponibles.