大家好,今天我们来聊聊在查询分析技术中,如何处理无法生成查询的情况。在一些场景中,查询分析技术可能允许生成的查询数量为零,这种情况下,我们的流程需要检查查询分析的结果,然后再决定是否调用检索器。
接下来,我会用模拟数据来给大家演示这个过程。
环境准备
首先,我们需要安装一些依赖库:
# %pip install -qU langchain langchain-community langchain-openai langchain-chroma
然后设置环境变量,在这个例子中,我们使用OpenAI:
import getpass
import os
os.environ["OPENAI_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"]
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_texts(
texts,
embeddings,
)
retriever = vectorstore.as_retriever()
查询分析
我们将使用函数调用来结构化输出,不过LLM在这里不需要调用表示搜索查询的函数(除非确实需要)。我们会使用一个提示来明确当不需要执行查询时的应有行为。
from typing import Optional
from langchain_core.pydantic_v1 import BaseModel, Field
class Search(BaseModel):
"""在职位记录数据库中搜索。"""
query: str = Field(
...,
description="应用于职位记录的相似性搜索查询。",
)
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI
system = """You have the ability to issue search queries to get information to help answer user information.
You do not NEED to look things up. If you don't need to, then just respond normally."""
prompt = ChatPromptTemplate.from_messages(
[
("system", system),
("human", "{question}"),
]
)
llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
structured_llm = llm.bind_tools([Search])
query_analyzer = {"question": RunnablePassthrough()} | prompt | structured_llm
通过调用这个分析器,我们可以看到有时会返回工具调用,而有时则不会:
query_analyzer.invoke("where did Harrison Work")
AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_ZnoVX4j9Mn8wgChaORyd1cvq', 'function': {'arguments': '{"query":"Harrison"}', 'name': 'Search'}, 'type': 'function'}]})
query_analyzer.invoke("hi!")
AIMessage(content='Hello! How can I assist you today?')
基于查询分析的检索
我们如何在一条链中包括这个查询分析呢?下面是一个示例:
from langchain_core.output_parsers.openai_tools import PydanticToolsParser
from langchain_core.runnables import chain
output_parser = PydanticToolsParser(tools=[Search])
@chain
def custom_chain(question):
response = query_analyzer.invoke(question)
if "tool_calls" in response.additional_kwargs:
query = output_parser.invoke(response)
docs = retriever.invoke(query[0].query)
# 可以在这里增加更多逻辑,比如另一个LLM调用
return docs
else:
return response
custom_chain.invoke("where did Harrison Work")
Number of requested results 4 is greater than number of elements in index 1, updating n_results = 1
[Document(page_content='Harrison worked at Kensho')]
custom_chain.invoke("hi!")
AIMessage(content='Hello! How can I assist you today?')
这波操作可以说是相当丝滑,通过这样的方法,我们能够在不需要搜索时保持灵活性并减少不必要的调用。
今天的技术分享就到这里,希望对大家有帮助。开发过程中遇到问题也可以在评论区交流~
—END—

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



