引言
在现代信息检索中,简单的向量相似性搜索已不能满足所有需求。不同应用场景中我们可能需要同时结合文本匹配和向量相似性,以便提高搜索的准确性和相关性。本文将介绍如何在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,你将发现更多的可能性和应用场景,为数据检索提供更智能化的解决方案。### 参考
- Cassandra
- LangChain Community VectorStores
- OpenAI Embeddings
- StrOutputParser
- ChatPromptTemplate
- ConfigurableField
- RunnablePassthrough
- ChatOpenAI
通过这一代码示例和步骤,你将能够在LangChain中实现混合搜索,提高信息检索的精准度,充分利用Astra DB和其他支持混合搜索的向量存储库的功能。### 小结
本文结合实际示例,详细介绍了如何在LangChain中实现结合向量相似性与文本匹配的混合搜索。通过使用Astra DB的向量存储库和LangChain提供的可配置链路,您可以灵活地根据具体需求进行搜索配置。这种方法在提高文档检索的准确性方面具有重要的应用价值。### 参考文献