Esegui la ricerca di massima pertinenza marginale con LangChain su Bigtable
Questa pagina descrive come eseguire una ricerca di massima pertinenza marginale (MMR) utilizzando l'integrazione BigtableVectorStore per LangChain in Bigtable e Vertex AI come servizio di incorporamento.
MMR è una tecnica di ricerca utilizzata nel recupero di informazioni per restituire un insieme di risultati pertinenti alla query e diversi, evitando la ridondanza. Mentre la ricerca standard di similarità vettoriale (ad esempio, una ricerca che utilizza il metodo k-nearest neighbor) potrebbe restituire molti elementi simili, MMR fornisce un insieme più vario di risultati principali. Questa funzionalità è utile quando hai dati potenzialmente sovrapposti o duplicati nel tuo archivio vettoriale.
Ad esempio, in un'applicazione di e-commerce, se un utente cerca "pomodori rossi", una ricerca di similarità vettoriale potrebbe restituire più schede dello stesso tipo di pomodoro rosso fresco. Una ricerca MMR mirerebbe a restituire un insieme più diversificato, ad esempio "pomodori rossi freschi", "pomodori rossi a cubetti in scatola", "pomodorini biologici" e magari anche "ricetta insalata di pomodori".
Prima di leggere questa pagina, è importante che tu conosca i seguenti concetti:
- Pertinenza: una misura del grado di corrispondenza tra il documento e la query.
- Diversità: una misura di quanto un documento sia diverso dai documenti già selezionati nel set di risultati.
- Moltiplicatore lambda: un fattore compreso tra 0 e 1 che bilancia pertinenza e diversità. Un valore più vicino a 1 dà la priorità alla pertinenza, mentre un valore più vicino a 0 dà la priorità alla diversità.
La classe BigtableVectorStore per LangChain
implementa MMR come algoritmo di riordinamento.
Questo algoritmo recupera innanzitutto un insieme più ampio di documenti pertinenti alla query
e seleziona i documenti che corrispondono alla query in modo equilibrato per
pertinenza e diversità.
Prima di iniziare
Questa guida utilizza Vertex AI come servizio di incorporamento. Assicurati di aver abilitato l'API Vertex AI nel tuo progetto.
Ruoli obbligatori
Per utilizzare Bigtable con LangChain, devi disporre dei seguenti ruoli IAM:
- Utente Bigtable
(
roles/bigtable.user) sull'istanza Bigtable. - Se inizializzi la tabella, devi disporre anche del ruolo Bigtable
Administrator
(
roles/bigtable.admin).
Configura l'ambiente
Installa i pacchetti LangChain richiesti:
pip install --upgrade --quiet langchain-google-bigtable langchain-google-vertexaiEsegui l'autenticazione per Google Cloud con il tuo account utente.
gcloud auth application-default loginImposta l'ID progetto, l'ID istanza Bigtable e l'ID tabella:
PROJECT_ID = "your-project-id" INSTANCE_ID = "your-instance-id" TABLE_ID = "your-table-id"
Inizializza il servizio di incorporamento e crea una tabella
Per utilizzare l'archivio vettoriale Bigtable, devi fornire gli embedding
generati da un modello di AI. In questa guida utilizzerai il modello di text embedding
gemini-embedding-004 su
Vertex AI.
from langchain_google_vertexai import VertexAIEmbeddings
from langchain_google_bigtable.vector_store import init_vector_store_table, BigtableVectorStore, ColumnConfig
# Initialize an embedding service
embedding_service = VertexAIEmbeddings(model_name="text-embedding-004", project=PROJECT_ID)
# Define column families
DATA_COLUMN_FAMILY = "product_data"
# Initialize the table (if it doesn't exist)
try:
init_vector_store_table(
project_id=PROJECT_ID,
instance_id=INSTANCE_ID,
table_id=TABLE_ID,
content_column_family=DATA_COLUMN_FAMILY,
embedding_column_family=DATA_COLUMN_FAMILY,
)
print(f"Table {TABLE_ID} created successfully.")
except ValueError as e:
print(e) # Table likely already exists
Instanzia BigtableVectorStore
Crea l'istanza del negozio passando il servizio di incorporamento e gli identificatori della tabella Bigtable.
# Configure columns
content_column = ColumnConfig(
column_family=DATA_COLUMN_FAMILY, column_qualifier="product_description"
)
embedding_column = ColumnConfig(
column_family=DATA_COLUMN_FAMILY, column_qualifier="embedding"
)
# Create the vector store instance
vector_store = BigtableVectorStore.create_sync(
project_id=PROJECT_ID,
instance_id=INSTANCE_ID,
table_id=TABLE_ID,
embedding_service=embedding_service,
collection="ecommerce_products",
content_column=content_column,
embedding_column=embedding_column,
)
print("BigtableVectorStore instantiated.")
Compila il datastore vettoriale
In questa guida utilizziamo uno scenario di esempio di un servizio di e-commerce fittizio in cui gli utenti vogliono cercare articoli correlati ai pomodori rossi. Innanzitutto, dobbiamo aggiungere alcuni prodotti e descrizioni correlati al pomodoro al vector store.
from langchain_core.documents import Document
products = [
Document(page_content="Fresh organic red tomatoes, great for salads.", metadata={"type": "fresh produce", "color": "red", "name": "Organic Vine Tomatoes"}),
Document(page_content="Ripe red tomatoes on the vine.", metadata={"type": "fresh", "color": "red", "name": "Tomatoes on Vine"}),
Document(page_content="Sweet cherry tomatoes, red and juicy.", metadata={"type": "fresh", "color": "red", "name": "Cherry Tomatoes"}),
Document(page_content="Canned diced red tomatoes in juice.", metadata={"type": "canned", "color": "red", "name": "Diced Tomatoes"}),
Document(page_content="Sun-dried tomatoes in oil.", metadata={"type": "preserved", "color": "red", "name": "Sun-Dried Tomatoes"}),
Document(page_content="Green tomatoes, perfect for frying.", metadata={"type": "fresh", "color": "green", "name": "Green Tomatoes"}),
Document(page_content="Tomato paste, concentrated flavor.", metadata={"type": "canned", "color": "red", "name": "Tomato Paste"}),
Document(page_content="Mixed salad greens with cherry tomatoes.", metadata={"type": "prepared", "color": "mixed", "name": "Salad Mix with Tomatoes"}),
Document(page_content="Yellow pear tomatoes, mild flavor.", metadata={"type": "fresh", "color": "yellow", "name": "Yellow Pear Tomatoes"}),
Document(page_content="Heirloom tomatoes, various colors.", metadata={"type": "fresh", "color": "various", "name": "Heirloom Tomatoes"}),
]
vector_store.add_documents(products)
print(f"Added {len(products)} products to the vector store.")
Eseguire la ricerca MMR
Il negozio contiene molti prodotti correlati ai pomodori, ma gli utenti vogliono cercare solo le offerte associate ai "pomodori rossi". Per ottenere un insieme diversificato di risultati, utilizza la tecnica MMR per eseguire la ricerca.
Il metodo chiave da utilizzare è
max_marginal_relevance_search
che accetta i seguenti argomenti:
query(str): il testo di ricerca.k(int): il numero finale di risultati di ricerca.fetch_k(int): il numero iniziale di prodotti simili da recuperare prima di applicare l'algoritmo MMR. Ti consigliamo che questo numero sia maggiore del parametrok.lambda_mult(float): il parametro di ottimizzazione della diversità. Utilizza0.0per la massima diversità e1.0per la massima pertinenza.
user_query = "red tomatoes"
k_results = 4
fetch_k_candidates = 10
print(f"Performing MMR search for: '{user_query}'")
# Example 1: Balanced relevance and diversity
mmr_results_balanced = vector_store.max_marginal_relevance_search(
user_query, k=k_results, fetch_k=fetch_k_candidates, lambda_mult=0.5
)
print(f"MMR Results (lambda=0.5, k={k_results}, fetch_k={fetch_k_candidates}):")
for doc in mmr_results_balanced:
print(f" - {doc.metadata['name']}: {doc.page_content}")
print("\n")
# Example 2: Prioritizing Diversity
mmr_results_diverse = vector_store.max_marginal_relevance_search(
user_query, k=k_results, fetch_k=fetch_k_candidates, lambda_mult=0.1
)
print(f"MMR Results (lambda=0.1, k={k_results}, fetch_k={fetch_k_candidates}):")
for doc in mmr_results_diverse:
print(f" - {doc.metadata['name']}: {doc.page_content}")
print("\n")
# Example 3: Prioritizing Relevance
mmr_results_relevant = vector_store.max_marginal_relevance_search(
user_query, k=k_results, fetch_k=fetch_k_candidates, lambda_mult=0.9
)
print(f"MMR Results (lambda=0.9, k={k_results}, fetch_k={fetch_k_candidates}):")
for doc in mmr_results_relevant:
print(f" - {doc.metadata['name']}: {doc.page_content}")
Valori di lambda_mult diversi producono insiemi di risultati diversi, bilanciando la
somiglianza con "pomodori rossi" con l'unicità dei prodotti mostrati.
Utilizzo di MMR con un retriever
Per utilizzare la ricerca MMR, puoi anche configurare un recuperatore LangChain. Il recuperatore fornisce un'interfaccia uniforme che ti consente di integrare facilmente metodi di ricerca specializzati, come MMR, direttamente nelle tue catene e applicazioni.
retriever = vector_store.as_retriever(
search_type="mmr",
search_kwargs={
"k": 3,
"fetch_k": 10,
"lambda_mult": 0.3,
}
)
retrieved_docs = retriever.invoke(user_query)
print(f"\nRetriever MMR Results for '{user_query}':")
for doc in retrieved_docs:
print(f" - {doc.metadata['name']}: {doc.page_content}")
Passaggi successivi
- Esplora altri tipi di ricerca e opzioni di filtro disponibili in
BigtableVectorStore. - Scopri di più su LangChain in Bigtable.