在构建自然语言处理系统时,我们经常需要处理用户输入并执行相应的查询操作。但有时,查询分析技术可能不会生成任何查询。本文将介绍如何处理这种情况,并构建一个灵活的查询分析和检索链。
1. 环境设置
首先,我们需要安装必要的依赖并设置环境变量:
# 安装依赖
!pip install -qU langchain langchain-community langchain-openai langchain-chroma
# 设置OpenAI API密钥
import os
import getpass
os.environ["OPENAI_API_KEY"] = getpass.getpass()
# 可选:设置LangSmith追踪
# os.environ["LANGCHAIN_TRACING_V2"] = "true"
# os.environ["LANGCHAIN_API_KEY"] = getpass.getpass()
2. 创建索引
我们将使用Chroma向量存储来创建一个简单的索引:
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()
3. 查询分析
我们将使用函数调用来结构化输出,并配置LLM使其不必总是生成搜索查询:
from typing import Optional
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI
class Search(BaseModel):
query: str = Field(
...,
description="Similarity search query applied to job record.",
)
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
4. 构建灵活的检索链
现在,我们可以构建一个灵活的检索链,它可以处理有查询和无查询的情况:
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
# 使用示例
print(custom_chain.invoke("where did Harrison Work"))
print(custom_chain.invoke("hi!"))
在这个例子中,custom_chain
函数首先使用 query_analyzer
来分析输入的问题。如果分析结果包含 tool_calls
,说明需要执行查询,那么它会解析查询并使用 retriever
检索相关文档。如果没有 tool_calls
,它会直接返回 LLM 的响应。
可能遇到的错误及解决方案
-
API 密钥错误:
错误:openai.error.AuthenticationError: Incorrect API key provided
解决方案:确保正确设置了OPENAI_API_KEY
环境变量,并且该密钥是有效的。 -
依赖安装问题:
错误:ModuleNotFoundError: No module named 'langchain'
解决方案:确保已正确安装所有必要的依赖,可以尝试重新运行 pip 安装命令。 -
向量存储为空:
错误:IndexError: list index out of range
解决方案:确保在创建向量存储时添加了一些文本数据。如果索引为空,检索操作可能会失败。 -
LLM 调用失败:
错误:openai.error.RateLimitError: You exceeded your current quota, please check your plan and billing details.
解决方案:检查你的 OpenAI 账户配额和计费信息,确保有足够的额度进行 API 调用。 -
类型错误:
错误:TypeError: Object of type AIMessage is not JSON serializable
解决方案:在处理 LLM 返回的消息时,确保正确地访问和序列化消息内容。可能需要将 AIMessage 对象转换为字典或字符串。
通过理解和实现这种灵活的查询分析和检索链,你可以构建更智能、更灵活的对话系统,能够根据用户输入的不同情况做出适当的响应。
如果你觉得这篇文章对你有帮助,请点赞,关注我的博客,谢谢!