如何应对多查询的查询分析:一步步解析

69 阅读2分钟

引言

在数据分析中,处理复杂问题通常需要生成并分析多个查询。这篇文章将展示如何在查询分析中处理多个查询,并结合结果提供一个完整的解决方案。我们将使用LangChain框架,并通过一个简单的示例演示如何从多个查询中获取信息并合并结果。

主要内容

设置环境

安装依赖

首先,你需要安装必要的库。如果尚未安装,可以使用以下命令:

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

设置环境变量

我们将在示例中使用OpenAI API:

import getpass
import os

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

注意,由于网络限制,开发者可能需要考虑使用API代理服务来确保稳定访问。

创建索引

我们将使用虚拟数据创建一个向量存储,用于模拟信息检索:

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

texts = ["Harrison worked at Kensho", "Ankush worked at Facebook"]
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_texts(
    texts,
    embeddings,
)
retriever = vectorstore.as_retriever(search_kwargs={"k": 1})

查询分析

我们将使用函数调用来结构化输出,并支持返回多个查询:

from typing import List, Optional
from langchain_core.pydantic_v1 import BaseModel, Field
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

class Search(BaseModel):
    queries: List[str] = Field(..., description="Distinct queries to search for")

output_parser = PydanticToolsParser(tools=[Search])

system = """You have the ability to issue search queries to get information to help answer user information.

If you need to look up two distinct pieces of information, you are allowed to do that!"""
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

@chain
async def custom_chain(question):
    response = await query_analyzer.ainvoke(question)
    docs = []
    for query in response.queries:
        new_docs = await retriever.ainvoke(query)
        docs.extend(new_docs)
    return docs

代码示例

以下是使用异步方式处理查询的完整代码示例:

await custom_chain.ainvoke("where did Harrison Work")
# Output: [Document(page_content='Harrison worked at Kensho')]

await custom_chain.ainvoke("where did Harrison and Ankush Work")
# Output: [Document(page_content='Harrison worked at Kensho'),
#          Document(page_content='Ankush worked at Facebook')]

常见问题和解决方案

  1. 处理重复文档:合并结果时可能会有重复文档。考虑使用去重或重新排序算法。

  2. API访问限制:由于网络限制,确保使用API代理服务以提高访问稳定性。

  3. 性能问题:异步调用有助于提高性能,尤其是在处理多个查询时。

总结和进一步学习资源

通过本文,我们学习了如何在查询分析中处理多个查询,并使用LangChain框架的功能合并结果。为了进一步学习,推荐以下资源:

参考资料

  1. LangChain GitHub Repository
  2. OpenAI API Documentation

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

---END---