跳到主要內容
Open In ColabOpen on GitHub

混合搜尋

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

此頁面是否對您有幫助?