探索LangChain中的混合搜索:结合向量相似性与文本搜索

53 阅读3分钟

引言

在现代信息检索中,简单的向量相似性搜索已不能满足所有需求。不同应用场景中我们可能需要同时结合文本匹配和向量相似性,以便提高搜索的准确性和相关性。本文将介绍如何在LangChain中实现这种混合搜索,并通过Astra DB的例子进行详细的代码演示。

Step 1: 检查向量存储库是否支持混合搜索

在开始之前,我们需要确认所使用的向量存储库是否支持混合搜索功能。在这篇文章中,我们将使用Astra DB的Cassandra/CQL接口来演示。

Step 2: 为链路添加可配置字段

为了在运行时方便调用链路,并配置相关标志,可以将混合搜索参数添加为链路中的可配置字段。

代码示例

以下是使用Astra DB进行混合搜索的具体代码示例。首先,确保安装相应的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')]

使用body_search参数过滤搜索结果:

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')]

Step 3: 使用可配置字段调用链路

我们将创建一个链路以便在上下文中进行问答。

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()

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参数以使用混合搜索功能:

chain.invoke(
    "What city did I visit last?",
    config={"configurable": {"search_kwargs": {"body_search": "new"}}},
)

结果:

New York

结论

通过本文,我们了解了如何在LangChain中使用Astra DB实现混合搜索功能。结合向量相似性和文本搜索,可以有效提升文档检索的准确性和相关性。此方法为复杂信息检索需求提供了一种灵活且强大的解决方案。通过在链路中添加可配置字段,用户可以动态地调整搜索参数,满足不同应用场景的需求。

继续探索LangChain,你将发现更多的可能性和应用场景,为数据检索提供更智能化的解决方案。### 参考

通过这一代码示例和步骤,你将能够在LangChain中实现混合搜索,提高信息检索的精准度,充分利用Astra DB和其他支持混合搜索的向量存储库的功能。### 小结

本文结合实际示例,详细介绍了如何在LangChain中实现结合向量相似性与文本匹配的混合搜索。通过使用Astra DB的向量存储库和LangChain提供的可配置链路,您可以灵活地根据具体需求进行搜索配置。这种方法在提高文档检索的准确性方面具有重要的应用价值。### 参考文献