Aplicación Streamlit para búsqueda semántica multilingüe en más de 10 millones de documentos de Wikipedia vectorizados en incrustaciones por Weaviate. Esta implementación se basa en el blog de Cohere ´Using LLMs for Search´ y su cuaderno correspondiente. Permite comparar el rendimiento de la búsqueda de palabras clave , la recuperación densa y la búsqueda híbrida para consultar el conjunto de datos de Wikipedia. Además, demuestra el uso de Cohere Rerank para mejorar la precisión de los resultados y Cohere Generate para proporcionar una respuesta basada en dichos resultados clasificados.
La búsqueda semántica se refiere a algoritmos de búsqueda que consideran la intención y el significado contextual de las frases de búsqueda al generar resultados, en lugar de centrarse únicamente en la concordancia de palabras clave. Proporciona resultados más precisos y relevantes al comprender la semántica o significado detrás de la consulta.
Una incrustación es un vector (lista) de números de punto flotante que representan datos como palabras, oraciones, documentos, imágenes o audio. Dicha representación numérica captura el contexto, jerarquía y similitud de los datos. Se pueden utilizar para tareas posteriores como clasificación, agrupación, detección de valores atípicos y búsqueda semántica.
Las bases de datos vectoriales, como Weaviate, están diseñadas específicamente para optimizar las capacidades de almacenamiento y consulta para incrustaciones. En la práctica, una base de datos vectorial utiliza una combinación de diferentes algoritmos que participan en la búsqueda del vecino más cercano aproximado (ANN). Estos algoritmos optimizan la búsqueda mediante hash, cuantificación o búsqueda basada en gráficos.
Keyword Matching: busca objetos que contengan los términos de búsqueda en sus propiedades. Los resultados se puntúan según la función BM25F:
@ retry ( wait = wait_random_exponential ( min = 1 , max = 5 ), stop = stop_after_attempt ( 5 ))
def with_bm25 ( self , query , lang = 'en' , top_n = 10 ) -> list :
"""
Performs a keyword search (sparse retrieval) on Wikipedia Articles using embeddings stored in Weaviate.
Parameters:
- query (str): The search query.
- lang (str, optional): The language of the articles. Default is 'en'.
- top_n (int, optional): The number of top results to return. Default is 10.
Returns:
- list: List of top articles based on BM25F scoring.
"""
logging . info ( "with_bm25()" )
where_filter = {
"path" : [ "lang" ],
"operator" : "Equal" ,
"valueString" : lang
}
response = (
self . weaviate . query . get ( "Articles" , self . WIKIPEDIA_PROPERTIES )
. with_bm25 ( query = query )
. with_where ( where_filter )
. with_limit ( top_n )
. do ()
)
return response [ "data" ][ "Get" ][ "Articles" ]
Recuperación densa: busque objetos más similares a un texto sin formato (no vectorizado):
@ retry ( wait = wait_random_exponential ( min = 1 , max = 5 ), stop = stop_after_attempt ( 5 ))
def with_neartext ( self , query , lang = 'en' , top_n = 10 ) -> list :
"""
Performs a semantic search (dense retrieval) on Wikipedia Articles using embeddings stored in Weaviate.
Parameters:
- query (str): The search query.
- lang (str, optional): The language of the articles. Default is 'en'.
- top_n (int, optional): The number of top results to return. Default is 10.
Returns:
- list: List of top articles based on semantic similarity.
"""
logging . info ( "with_neartext()" )
nearText = {
"concepts" : [ query ]
}
where_filter = {
"path" : [ "lang" ],
"operator" : "Equal" ,
"valueString" : lang
}
response = (
self . weaviate . query . get ( "Articles" , self . WIKIPEDIA_PROPERTIES )
. with_near_text ( nearText )
. with_where ( where_filter )
. with_limit ( top_n )
. do ()
)
return response [ 'data' ][ 'Get' ][ 'Articles' ]
Búsqueda híbrida: produce resultados basados en una combinación ponderada de resultados de una búsqueda de palabra clave (bm25) y una búsqueda de vector.
@ retry ( wait = wait_random_exponential ( min = 1 , max = 5 ), stop = stop_after_attempt ( 5 ))
def with_hybrid ( self , query , lang = 'en' , top_n = 10 ) -> list :
"""
Performs a hybrid search on Wikipedia Articles using embeddings stored in Weaviate.
Parameters:
- query (str): The search query.
- lang (str, optional): The language of the articles. Default is 'en'.
- top_n (int, optional): The number of top results to return. Default is 10.
Returns:
- list: List of top articles based on hybrid scoring.
"""
logging . info ( "with_hybrid()" )
where_filter = {
"path" : [ "lang" ],
"operator" : "Equal" ,
"valueString" : lang
}
response = (
self . weaviate . query . get ( "Articles" , self . WIKIPEDIA_PROPERTIES )
. with_hybrid ( query = query )
. with_where ( where_filter )
. with_limit ( top_n )
. do ()
)
return response [ "data" ][ "Get" ][ "Articles" ]
@ retry ( wait = wait_random_exponential ( min = 1 , max = 5 ), stop = stop_after_attempt ( 5 ))
def rerank ( self , query , documents , top_n = 10 , model = 'rerank-english-v2.0' ) -> dict :
"""
Reranks a list of responses using Cohere's reranking API.
Parameters:
- query (str): The search query.
- documents (list): List of documents to be reranked.
- top_n (int, optional): The number of top reranked results to return. Default is 10.
- model: The model to use for reranking. Default is 'rerank-english-v2.0'.
Returns:
- dict: Reranked documents from Cohere's API.
"""
return self . cohere . rerank ( query = query , documents = documents , top_n = top_n , model = model )
Fuente: Coherir
@ retry ( wait = wait_random_exponential ( min = 1 , max = 5 ), stop = stop_after_attempt ( 5 ))
def with_llm ( self , context , query , temperature = 0.2 , model = "command" , lang = "english" ) -> list :
prompt = f"""
Use the information provided below to answer the questions at the end. /
Include some curious or relevant facts extracted from the context. /
Generate the answer in the language of the query. If you cannot determine the language of the query use { lang } . /
If the answer to the question is not contained in the provided information, generate "The answer is not in the context".
---
Context information:
{ context }
---
Question:
{ query }
"""
return self . cohere . generate (
prompt = prompt ,
num_generations = 1 ,
max_tokens = 1000 ,
temperature = temperature ,
model = model ,
)
[email protected]:dcarpintero/wikisearch.git
Windows:
py -m venv .venv
.venvscriptsactivate
macOS/Linux
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
streamlit run ./app.py
Aplicación web de demostración implementada en Streamlit Cloud y disponible en https://wikisearch.streamlit.app/