如何处理多查询场景下的查询分析

老铁们,今天我想和大家聊聊在处理查询分析时,我们可能会遇到产生多个查询的场景。这种情况下,我们需要确保运行所有的查询,并将结果结合起来。下面我用模拟数据来演示一下如何做到这一点。

安装依赖环境

首先,我们需要安装一些必要的库:

# 安装相关库
%pip install -qU langchain langchain-community langchain-openai langchain-chroma

设置环境变量

在这个示例中,我们将使用 OpenAI 的 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

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

class Search(BaseModel):
    """在作业记录数据库中进行搜索。"""
    queries: List[str] = Field(
        ...,
        description="要搜索的不同查询",
    )

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

@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")

# 输出: [Document(page_content='Harrison worked at Kensho')]

await custom_chain.ainvoke("where did Harrison and ankush Work")

# 输出: [Document(page_content='Harrison worked at Kensho'), Document(page_content='Ankush worked at Facebook')]

说白了就是通过这种方式,我们可以轻松地处理多个查询,同时保证检索的效率。老铁们,这波操作可以说是相当丝滑。

今天的技术分享就到这里,希望对大家有帮助。开发过程中遇到问题也可以在评论区交流~

—END—

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值