Query Transformations

查询转换

4 分钟阅读

标准的 RAG 通常会将文档拆分成块,对其进行嵌入,然后检索与用户问题语义相似度高的块。但这会带来几个问题:(1) 文档块可能包含无关内容,从而降低检索效果;(2) 用户问题可能措辞不当,不利于检索;(3) 可能需要从用户问题生成结构化查询(例如,用于带元数据过滤的向量存储或 SQL 数据库进行查询)。

LangChain 提供了许多 高级检索方法 来帮助解决这些挑战。(1) 多表示索引:创建一个适合检索的文档表示(例如摘要)(在上周的 博文 中使用 Multi Vector Retriever 阅读此内容)。(2) 查询转换:在本文中,我们将回顾几种转换人类问题以改进检索的方法。(3) 查询构建:将人类问题转换为特定的查询语法或语言,这将在未来的文章中介绍。

如果您想到标准的 RAG 流程,其通用流程是获取用户问题并直接将其传递给嵌入模型。然后将该嵌入与存储在向量存储中的文档进行比较,并返回最相似的 k 个文档。

查询转换处理的是在传递给嵌入模型之前对用户问题进行转换。

💡
虽然这并非新现象(搜索领域多年来一直在使用查询扩展),但新颖之处在于能够利用 LLM 来实现这一点。

以下是利用这一点的几种论文和检索方法的变体。它们都使用 LLM 来生成一个新的(或多个新的)查询,主要区别在于它们用于生成查询的提示。

Rewrite-Retrieve-Read

这篇论文使用 LLM 来重写用户查询,而不是直接使用原始用户查询进行检索。

因为原始查询不一定总是最适合 LLM 进行检索,尤其是在现实世界中……我们首先提示 LLM 重写查询,然后进行检索增强阅读。

使用的提示相对简单(在 Hub 上此处

链接

Step back prompting

这篇论文使用 LLM 来生成一个“回溯”问题。这可以与检索一起使用,也可以不与检索一起使用。在使用检索时,将同时使用“回溯”问题和原始问题进行检索,然后将两个结果都用于为语言模型响应提供依据。

此处是使用的提示

链接

后续问题

查询转换最基本和最核心的应用是在对话链中处理后续问题。处理后续问题时,基本上有三种选择:

  1. 仅嵌入后续问题。这意味着,如果后续问题建立在先前的对话之上或引用了先前的对话,那么它将丢失该问题。例如,如果我先问“在意大利我可以做什么?”,然后问“那里有什么样的食物?”——如果我只嵌入“那里有什么样的食物?”,我将无法知道“那里”指的是哪里。
  2. 嵌入整个对话(或最后 k 条消息)。这样做的问题是,如果后续问题与之前的对话完全无关,它可能会返回完全不相关的结果,从而在生成过程中造成干扰。
  3. 使用 LLM 进行查询转换!

在最后一个选项中,您将迄今为止的整个对话(包括后续问题)传递给 LLM,并要求它生成一个搜索词。这就是我们在 WebLangChain 中所做的,也是大多数基于聊天的检索应用程序可能做的事情。

那么问题来了:我应该使用什么提示将整个对话转换为搜索查询?这就是需要进行大量提示工程的地方。以下是我们为 WebLangChain 使用的提示(它将“查询生成”部分表述为构建一个独立的查询)。在 Hub 上此处可以找到它。

Multi Query Retrieval

在此策略中,LLM 用于生成多个搜索查询。然后可以并行执行这些搜索查询,并将检索到的结果一起传入。当单个问题可能依赖于多个子问题时,这非常有用。

例如,考虑以下问题:

红袜队和爱国者队谁最近赢得了总冠军?

这实际上需要两个子问题:

  • “红袜队上一次赢得总冠军是什么时候?”
  • “爱国者队上一次赢得总冠军是什么时候?”

链接

RAG-Fusion

一篇最近的文章建立在 Multi-Query Retrieval 的想法之上。然而,它们没有传入所有文档,而是使用倒数排名融合来重新排序文档。

链接

结论

如您所见,有许多不同的方法可以进行查询转换。同样,这不是一个新话题——但新的是利用 LLM 来实现这一点。这些方法之间的差异在于所使用的提示。编写提示非常容易——几乎和想到它们一样容易。这就引出了一个问题——您将想出什么样的查询转换?请告诉我们!

© . This site is unofficial and not affiliated with LangChain, Inc.