混合搜尋
LangChain 中的標準搜尋是透過向量相似度完成的。然而,許多 向量儲存庫 實作 (Astra DB、ElasticSearch、Neo4J、AzureSearch、Qdrant...) 也支援更進階的搜尋,結合了向量相似度搜尋和其他搜尋技術 (全文、BM25 等等)。這通常被稱為「混合」搜尋。
步驟 1:確認您使用的向量儲存庫支援混合搜尋
目前,LangChain 中沒有統一的方法來執行混合搜尋。每個向量儲存庫可能有自己的方法來執行。這通常作為關鍵字參數在 similarity_search
期間傳遞。
透過閱讀文件或原始碼,找出您使用的向量儲存庫是否支援混合搜尋,如果支援,如何使用它。
步驟 2:將該參數新增為鏈的可配置欄位
這將讓您輕鬆呼叫鏈並在執行時配置任何相關標誌。請參閱 此文件 以取得有關配置的更多資訊。
步驟 3:使用該可配置欄位呼叫鏈
現在,在執行時,您可以使用可配置欄位呼叫此鏈。
程式碼範例
讓我們看看這在程式碼中的具體範例。我們將使用 Astra DB 的 Cassandra/CQL 介面作為此範例。
安裝以下 Python 套件
!pip install "cassio>=0.1.7"
取得 連線密碼。
初始化 cassio
import cassio
cassio.init(
database_id="Your database ID",
token="Your application token",
keyspace="Your key space",
)
使用標準 索引分析器 建立 Cassandra VectorStore。需要索引分析器才能啟用詞彙比對。
from cassio.table.cql import STANDARD_ANALYZER
from langchain_community.vectorstores import Cassandra
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()
vectorstore = Cassandra(
embedding=embeddings,
table_name="test_hybrid",
body_index_options=[STANDARD_ANALYZER],
session=None,
keyspace=None,
)
vectorstore.add_texts(
[
"In 2023, I visited Paris",
"In 2022, I visited New York",
"In 2021, I visited New Orleans",
]
)
如果我們進行標準相似度搜尋,我們會取得所有文件
vectorstore.as_retriever().invoke("What city did I visit last?")
[Document(page_content='In 2022, I visited New York'),
Document(page_content='In 2023, I visited Paris'),
Document(page_content='In 2021, I visited New Orleans')]
Astra DB 向量儲存庫 body_search
參數可用於篩選詞彙 new
的搜尋。
vectorstore.as_retriever(search_kwargs={"body_search": "new"}).invoke(
"What city did I visit last?"
)
[Document(page_content='In 2022, I visited New York'),
Document(page_content='In 2021, I visited New Orleans')]
我們現在可以建立鏈,我們將使用它來進行問答
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import (
ConfigurableField,
RunnablePassthrough,
)
from langchain_openai import ChatOpenAI
這是基本問答鏈設定。
template = """Answer the question based only on the following context:
{context}
Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
model = ChatOpenAI()
retriever = vectorstore.as_retriever()
在這裡,我們將檢索器標記為具有可配置欄位。所有向量儲存庫檢索器都有 search_kwargs
作為欄位。這只是一個字典,包含向量儲存庫特定欄位
configurable_retriever = retriever.configurable_fields(
search_kwargs=ConfigurableField(
id="search_kwargs",
name="Search Kwargs",
description="The search kwargs to use",
)
)
我們現在可以使用我們的可配置檢索器建立鏈
chain = (
{"context": configurable_retriever, "question": RunnablePassthrough()}
| prompt
| model
| StrOutputParser()
)
chain.invoke("What city did I visit last?")
Paris
我們現在可以使用可配置選項調用鏈。search_kwargs
是可配置欄位的 ID。該值是要用於 Astra DB 的搜尋 kwargs。
chain.invoke(
"What city did I visit last?",
config={"configurable": {"search_kwargs": {"body_search": "new"}}},
)
New York