老铁们,今天我想和大家聊聊在处理查询分析时,我们可能会遇到产生多个查询的场景。这种情况下,我们需要确保运行所有的查询,并将结果结合起来。下面我用模拟数据来演示一下如何做到这一点。
安装依赖环境
首先,我们需要安装一些必要的库:
# 安装相关库
%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—

被折叠的 条评论
为什么被折叠?



