LangChain开发AI应用利器之Transformer

向量数据库关系型数据库机器学习

简单RAG(检索增强生成)方法存在文档块包含无关内容、用户问题表达不佳以及需要生成结构化查询的问题。为了解决这些问题,LangChain提供了几种高级检索方法,其中包括:

1.多表示索引 :创建更适合检索的文档摘要,提高检索效果。

查询转换( Transformer) :将用户问题转化为更优化的检索形式。 3.查询构建 :将问题转化为特定查询语法。

picture.image

众所周知,Transformer、Router、Aggregator、Injector、Executor是LangChain

的核心组件,这里我们将重点介绍Transformer——查询转换方法:

1.重写-检索-阅读 :通过LLM重写用户问题,再进行检索,以提高检索效果。 2.回退提示 :生成备用问题,并结合原问题进行检索,提升检索结果的准确性。 3.跟进问题 :使用LLM将对话中的跟进问题转化为独立的搜索查询。 4.多查询检索 :LLM生成多个相关查询,并行检索不同子问题的答案。 5.RAG-融合 :通过多查询检索并使用互惠排名融合来优化文档排序。

这些方法的核心在于LLM提示词的设计与使用,不同提示词生成的查询形式可以显著影响检索效果。

查询转换

picture.image 查询转换

简单的RAG通常将文档拆分为多个块,嵌入它们,并检索与用户问题语义相似度较高的块。但这会带来几个问题:

(1)文档块可能包含无关内容,降低检索效果;

(2)用户问题可能表述不佳,影响检索;

(3)需要从用户问题生成结构化查询(例如,用于带有元数据过滤的向量库查询或SQL数据库查询)。

LangChain 提供了许多高级检索方法[1],帮助解决这些挑战。

(1)多表示索引 :创建适合检索的文档表示(如摘要),可参考上周的博客文章,了解使用多向量检索器的更多信息。

(2)查询转换 :本文将介绍几种将人类问题转换为提高检索效果的方法。

(3)查询构建 :将人类问题转换为特定查询语法或语言,后续文章将详细介绍。

在一个简单的RAG管道中,一般流程是将用户问题直接传递给嵌入模型。该嵌入结果与存储在向量库中的文档进行比较,返回k个最相似的结果。

picture.image

查询转换是指在将用户问题传递给嵌入模型之前,对其进行转换。

虽然这并不是新现象(查询扩展[2]已经在搜索中使用多年),但利用LLMs(大型语言模型)进行查询转换则是新的。

以下是一些利用LLMs生成新查询(或多个新查询)的方法,主要区别在于生成这些查询所用的提示词。

重写-检索-阅读

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

因为原始查询并不总是对LLM最优的检索方式,尤其是在现实场景中……我们首先提示LLM重写查询,然后进行检索增强的阅读。

picture.image

使用的提示词相对简单,可以在Hub上找到这里[3]:

picture.image

链接:

• 论文[4]

• LangChain 实现[5]

回退提示

这篇论文使用LLM生成一个“回退”问题。这可以结合检索使用,也可以不结合检索。结合检索时,既使用“回退”问题,也使用原始问题进行检索,然后将两者的结果用于生成语言模型的回答。

picture.image

这里[6]是使用的提示词:

picture.image

链接:

• 论文[7]

• LangChain 实现[8]

跟进问题

查询转换最基本的使用场景是对话链中处理跟进问题。在处理跟进问题时,通常有三个选项:

1.只嵌入跟进问题。这意味着如果跟进问题基于之前的对话,或引用之前的内容,它将丢失这些上下文。例如,我先问“在意大利我能做什么?”然后再问“那里有什么食物?”——如果只嵌入“那里有什么食物?”,那么就无法知道“那里”指的是哪里。 2.嵌入整个对话(或最后的k条消息)。问题在于如果跟进问题与之前的对话无关,可能会返回完全无关的结果,干扰生成。 3.使用LLM进行查询转换!

在最后这个选项中,你将整个对话(包括跟进问题)传递给LLM,并请求其生成搜索词。这是我们在WebLangChain[9]中使用的方法,也是大多数基于聊天的检索应用程序可能使用的方法。

问题变成了:使用什么提示词将整个对话转换为搜索查询?这里需要大量的提示词工程。以下是我们在WebLangChain中使用的提示词(将“查询生成”部分表述为构建独立问题)。可以在Hub上查看这里[10]。

picture.image

多查询检索

在这种策略中,LLM被用来生成多个搜索查询。然后可以并行执行这些搜索查询,并一起传递检索到的结果。这在一个问题依赖多个子问题时非常有用。

例如,考虑以下问题:

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

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

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

链接:

• LangChain 实现[11]

RAG-融合

最近的一篇文章基于多查询检索的想法。然而,与其传递所有文档,它们使用互惠排名融合来重新排序文档。

picture.image

链接:

• 博客文章[12]

• LangChain 实现[13]

示例

以java版langchain4j中的实现为例,压缩query转换(Compressing Query Transformer):


            
"Read and understand the conversation between the User and the AI. " +
            
                    "Then, analyze the new query from the User. " +
            
                    "Identify all relevant details, terms, and context from both the conversation and the new query. " +
            
                    "Reformulate this query into a clear, concise, and self-contained format suitable for information retrieval.\n" +
            
                    "\n" +
            
                    "Conversation:\n" +
            
                    "{{chatMemory}}\n" +
            
                    "\n" +
            
                    "User query: {{query}}\n" +
            
                    "\n" +
            
                    "It is very important that you provide only reformulated query and nothing else! " +
            
                    "Do not prepend a query with anything!"
        

拓展query转换(Expanding Query Transformer):


          
"Generate {{n}} different versions of a provided user query. " +
          
                    "Each version should be worded differently, using synonyms or alternative sentence structures, " +
          
                    "but they should all retain the original meaning. " +
          
                    "These versions will be used to retrieve relevant documents. " +
          
                    "It is very important to provide each query version on a separate line, " +
          
                    "without enumerations, hyphens, or any additional formatting!\n" +
          
                    "User query: {{query}}"
      

结论

如你所见,进行查询转换有很多种方式。再次强调,这并不是一个新话题——但使用LLMs来做这件事是新的。这些方法的差异在于使用的提示词。编写提示词非常容易——几乎和想到它们一样容易。这不禁让人思考:你会想出哪些查询转换方法?让我们知道!

声明

本文由山行整理自:https://blog.langchain.dev/query-transformations/项目和网络,如果对您有帮助,请帮忙点赞、关注、收藏,谢谢~

References

[1] 高级检索方法: https://python.langchain.com/docs/modules/data\_connection/retrievers/?ref=blog.langchain.dev
[2] 查询扩展: https://www.searchenginejournal.com/what-is-google-query-expansion-cases-and-examples/7924/?ref=blog.langchain.dev
[3] 这里: https://blog.langchain.dev/query-transformations/smith.langchain.com/hub/langchain-ai/rewrite
[4] 论文: https://arxiv.org/pdf/2305.14283.pdf?ref=blog.langchain.dev
[5] LangChain 实现: https://github.com/langchain-ai/langchain/blob/master/cookbook/rewrite.ipynb?ref=blog.langchain.dev
[6] 这里: https://smith.langchain.com/hub/langchain-ai/stepback-answer?ref=blog.langchain.dev
[7] 论文: https://arxiv.org/pdf/2310.06117.pdf?ref=blog.langchain.dev
[8] LangChain 实现: https://github.com/langchain-ai/langchain/blob/master/cookbook/stepback-qa.ipynb?ref=blog.langchain.dev
[9] WebLangChain: https://blog.langchain.dev/weblangchain/
[10] 这里: https://smith.langchain.com/hub/langchain-ai/weblangchain-search-query?ref=blog.langchain.dev
[11] LangChain 实现: https://python.langchain.com/docs/modules/data\_connection/retrievers/MultiQueryRetriever?ref=blog.langchain.dev
[12] 博客文章: https://towardsdatascience.com/forget-rag-the-future-is-rag-fusion-1147298d8ad1?ref=blog.langchain.dev
[13] LangChain 实现: https://github.com/langchain-ai/langchain/blob/master/cookbook/rag\_fusion.ipynb?ref=blog.langchain.dev

0
0
0
0
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论