ביצוע חיפוש של רלוונטיות שולית מקסימלית באמצעות LangChain ב-Bigtable
בדף הזה מוסבר איך לבצע חיפוש של רלוונטיות שולית מקסימלית (MMR) באמצעות השילוב של BigtableVectorStore עם LangChain ב-Bigtable ובפלטפורמת Gemini Enterprise Agent בתור שירות ההטמעה.
MMR היא טכניקת חיפוש שמשמשת באחזור מידע כדי להחזיר קבוצה של תוצאות שרלוונטיות לשאילתה ומגוונות, וכך למנוע כפילויות. חיפוש רגיל של דמיון וקטורי (לדוגמה, חיפוש שמשתמש בשיטת השכן הקרוב ביותר k) עשוי להחזיר הרבה פריטים דומים, אבל MMR מספק קבוצה מגוונת יותר של תוצאות מובילות. האפשרות הזו שימושית אם יש לכם נתונים שחופפים או כפולים במאגר הווקטורים.
לדוגמה, באפליקציית מסחר אלקטרוני, אם משתמש מחפש "עגבניות אדומות", חיפוש דמיון וקטורי עשוי להחזיר כמה רשימות של אותו סוג של עגבנייה אדומה טרייה. חיפוש MMR יציג מגוון רחב יותר של תוצאות, כמו 'עגבניות אדומות טריות', 'עגבניות אדומות חתוכות מקופסאות שימורים', 'עגבניות שרי אורגניות', ואולי אפילו 'מתכון לסלט עגבניות'.
לפני שקוראים את הדף הזה, חשוב להכיר את המושגים הבאים:
- רלוונטיות: מדד שמשקף את מידת ההתאמה של המסמך לשאילתה.
- מגוון: מדד שמראה עד כמה מסמך מסוים שונה מהמסמכים שכבר נבחרו בקבוצת התוצאות.
- Lambda Multiplier: גורם בין 0 ל-1 שמאזן בין הרלוונטיות לגיוון. ערך שקרוב יותר ל-1 נותן עדיפות לרלוונטיות, וערך שקרוב יותר ל-0 נותן עדיפות למגוון.
המחלקות BigtableVectorStore של LangChain מטמיעות את MMR כאלגוריתם לדירוג מחדש.
האלגוריתם הזה מאחזר קודם קבוצה גדולה יותר של מסמכים שרלוונטיים לשאילתה, ואז בוחר את המסמכים שתואמים לשאילתה באופן מאוזן מבחינת הרלוונטיות והמגוון.
לפני שמתחילים
במדריך הזה נעשה שימוש ב-Agent Platform כשירות ההטמעה. מוודאים ש-Agent Platform API מופעל בפרויקט.
התפקידים הנדרשים
כדי להשתמש ב-Bigtable עם LangChain, אתם צריכים את תפקידי ה-IAM הבאים:
- Bigtable User
(
roles/bigtable.user) on the Bigtable instance. - אם אתם מאתחלים את הטבלה, אתם צריכים גם את התפקיד Bigtable Administrator (
roles/bigtable.admin).
מגדירים את הסביבה
מתקינים את חבילות LangChain הנדרשות:
pip install --upgrade --quiet langchain-google-bigtable langchain-google-vertexaiמתבצע אימות ב- Google Cloud באמצעות חשבון המשתמש.
gcloud auth application-default loginמגדירים את מזהה הפרויקט, מזהה מופע Bigtable ומזהה הטבלה:
PROJECT_ID = "your-project-id" INSTANCE_ID = "your-instance-id" TABLE_ID = "your-table-id"
מפעילים את שירות ההטמעה ויוצרים טבלה
כדי להשתמש במאגר הווקטורים של Bigtable, צריך לספק הטמעות שנוצרו על ידי מודל AI. במדריך הזה נעשה שימוש במודל הטמעת הטקסט gemini-embedding-001 ב-Agent Platform.
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-001", 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
יצירת מופע של BigtableVectorStore
יוצרים את מופע המאגר על ידי העברת מזהי הטבלה של 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.")
איכלוס מאגר הווקטורים
במדריך הזה אנחנו משתמשים בתרחיש לדוגמה של שירות מסחר אלקטרוני פיקטיבי, שבו משתמשים רוצים לחפש פריטים שקשורים לעגבניות אדומות. קודם כל, צריך להוסיף לחנות הווקטורים כמה מוצרים שקשורים לעגבנייה ותיאורים שלהם.
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.")
ביצוע חיפוש MMR
בחנות יש הרבה מוצרים שקשורים לעגבניות, אבל המשתמשים רוצים לחפש רק מוצרים שקשורים ל'עגבניות אדומות'. כדי לקבל מגוון רחב של תוצאות, צריך להשתמש בטכניקת MMR לביצוע החיפוש.
השיטה העיקרית שבה משתמשים היא max_marginal_relevance_search, שמקבלת את הארגומנטים הבאים:
-
query(str): הטקסט לחיפוש. -
k(int): המספר הסופי של תוצאות החיפוש. -
fetch_k(int): מספר המוצרים הדומים הראשוני שצריך לאחזר לפני שמחילים את אלגוריתם ה-MMR. מומלץ שהמספר הזה יהיה גדול מהפרמטרk. -
lambda_mult(float): פרמטר הכוונון של הגיוון. משתמשים בערך0.0כדי למקסם את המגוון, ובערך1.0כדי למקסם את הרלוונטיות.
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}")
ערכים שונים של lambda_mult יניבו קבוצות שונות של תוצאות, ויאזנו בין הדמיון ל'עגבניות אדומות' לבין הייחודיות של המוצרים שמוצגים.
שימוש ב-MMR עם כלי לאחזור מידע
כדי להשתמש בחיפוש MMR, אפשר גם להגדיר LangChain retriever. רכיב המאחזר מספק ממשק אחיד שמאפשר לכם לשלב בצורה חלקה שיטות חיפוש מיוחדות, כמו MMR, ישירות ברשתות ובאפליקציות שלכם.
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}")
המאמרים הבאים
- אפשר לעיין בסוגי חיפוש נוספים ובאפשרויות סינון שזמינים ב-
BigtableVectorStore. - מידע נוסף על LangChain ב-Bigtable