RAG from scratch: Part 11 (Query Structuring) by LangChain
查询构建;查询结构化 (Query Structuring)
“从零开始构建RAG”系列视频第11部分:查询构建笔记
本次内容为“从零开始构建检索增强生成(RAG)”系列视频第11部分,聚焦查询构建技术,讲解如何将自然语言转换为适配数据源的特定语言,实现高效信息检索。
一、RAG流程回顾与查询构建定位
1. 前期流程
此前已介绍查询翻译(将问题转化为更利于检索的形式)和路由(把问题导向正确数据源,如向量存储、图数据库、SQL数据库等)。
2. 查询构建的作用
作为RAG流程的关键环节,将自然语言转化为适用于特定数据源(本部分聚焦向量存储)的特定领域语言,实现精准检索 。
二、查询构建原理与方法
1. 问题陈述
- 示例场景:假设存在LangChain视频文字记录索引,用户提出需求如“找2024年之后发布的关于Chat LangChain的视频” 。
- 目标:通过查询构建,将上述自然语言问题转化为可应用于向量存储元数据过滤器的结构化查询,从而检索出符合条件(讨论Chat LangChain主题且2024年后发布)的文本块。
2. 实现方式
- 技术手段:利用函数调用(如借助OpenAI等供应商的服务 )。
- 具体流程:获取向量存储中的元数据字段,提供给语言模型;模型依据这些信息,生成符合指定模式的查询;将查询解析为类似Pydantic对象的结构化对象,用于后续搜索。Pydantic对象可对数据进行验证和管理,确保查询结构符合要求。
三、查询构建代码实现与演示
1. 数据准备
以YouTube视频为例,展示从文字记录获取的元数据(描述、网址、发布日期、时长等)。假设索引具备多种元数据字段和过滤器,支持对观看次数、发布日期、视频时长的范围过滤,以及对内容和标题的非结构化搜索 。
2. 对象构建
创建“本教程搜索对象”,封装可用搜索信息,枚举语义搜索(内容搜索、标题搜索)和结构化搜索(针对时长、观看次数等的过滤 )。
3. 提示设置与模型调用
设置提示“你是将自然语言转换为数据库查询的专家…返回优化检索的数据库查询” ;调用大语言模型(LLM)时,将包含索引信息的Pydantic对象绑定到LLM,转换为函数模式(如OpenAI函数模式),使模型输出结构化对象并解析为Pydantic对象。
4. 运行演示
- 纯语义输入:输入“从零开始构建检索增强生成(RAG)”,模型执行内容和标题搜索。
- 含过滤器输入:输入含日期过滤器的问题,如“查找2024年之前发布的关于Chat LangChain主题的视频”,模型不仅执行语义搜索,还依据日期过滤器进行检索 。
四、查询构建技术总结
1. 技术本质
将非结构化自然语言输入,转化为遵循自定义模式的结构化查询对象,适配不同查询需求。
2. 应用特点
基于具体向量存储情况定制,通用性强,可适配多种向量数据库;支持根据自然语言问题实时进行元数据过滤,提升检索效率与准确性 。
3. 拓展资源
相关文档提供与不同向量存储供应商的集成方法,可供深入学习和实践。
- 第一个链接https://blog.langchain.dev/query - construction/指向LangChain博客中关于查询构建的页面,可能包含查询构建相关的技术文章、教程等内容,帮助用户学习如何构建适用于图数据库和SQL的查询。
- 第二个链接https://blog.langchain.dev/enhancing-rag-based-applications-accuracy-by-constructing-and-leveraging-knowledge-graphs/是LangChain博客中关于通过构建和利用知识图谱提高基于RAG(检索增强生成)应用准确性的文章,涉及图数据库相关知识,对理解图数据库在RAG系统中的应用有帮助。
五、视频原文
第一页:这是我们“从零开始构建检索增强生成(RAG)”系列视频的第11部分,重点讲解查询构建。
第二页:之前我们讨论过查询翻译,也就是获取一个问题,并将其转换或翻译成一个更适合检索的问题的过程。然后我们谈到了路由,即获取该问题,并将其路由到正确的数据源的过程,例如特定的向量存储、图数据库或SQL数据库等。现在我们要讨论查询构建的过程,基本上就是将自然语言转换为适用于其中一个数据源的特定领域的特定语言。对于其中一个源,现在我们将具体讨论从自然语言转换为向量存储的元数据过滤器的过程。
第三页:问题陈述如下:假设我们有一个LangChain视频文字记录的索引。例如,你可能想问一个问题:“给我找一找2024年之后发布的关于Chat LangChain的视频”。查询构建的过程基本上就是将这个自然语言问题转换为一个结构化查询,该查询可以应用于向量存储的元数据过滤器。所以,大多数向量存储都会有某种元数据过滤器,这些过滤器可以对已索引的文本块进行某种结构化查询。例如,这种类型的查询将检索所有讨论Chat LangChain主题且在2024年之后发布的文本块。这就是问题所在。为了实现这一点,我们将使用函数调用。在这种情况下,你可以使用例如OpenAI或其他供应商来实现。从高层次来讲,我们要做的是获取向量存储中存在的元数据字段,并将它们作为信息提供给模型,然后模型可以利用这些信息生成符合所提供模式的查询。然后我们可以将这些查询解析为一个类似Pydantic对象的结构化对象,这个对象又可以用于搜索。
第四页:这就是问题陈述,现在让我们实际来看一下代码。这是我们之前已经看过的笔记本。我给大家举个例子,我们拿一个YouTube视频为例,看看从文字记录中获取的元数据。你可以看到,你会得到诸如描述、网址、发布日期、时长之类的信息。现在假设我们有一个索引,它基本上有许多不同的元数据字段和过滤器,这些过滤器允许我们对观看次数、发布日期、视频时长等进行范围过滤,或者对内容和标题进行非结构化搜索。所以,想象一下我们有一个具备这些可用过滤器的索引,我们能做的是将关于这些可用过滤器的信息捕获到一个对象中。我们称这个对象为“本教程搜索对象”,它基本上封装了关于我们可以进行的可用搜索的信息。所以我们在这里对其进行枚举,内容搜索和标题搜索是可以在这些字段上进行的语义搜索。然后这些过滤器是我们可以对时长、观看次数等进行的各种类型的结构化搜索。我们可以构建这个对象。现在我们可以用一个简单的提示轻松设置它,提示内容为:“你是将自然语言转换为数据库查询的专家。你可以访问数据库教程视频。给出一个问题,返回一个优化检索的数据库查询。”关键在于,当你使用结构化输出来调用这个大语言模型(LLM)时,你要将这个包含了我们索引所有信息的Pydantic对象绑定到LLM上,这正是我们之前讨论过的。实际上就是这个过程,你获取这个对象,将其转换为一个函数模式,例如OpenAI的函数模式,将其绑定到你的模型上,然后你就能从一个自然语言问题中得到一个结构化对象,而不是一个JSON字符串,这个结构化对象可以被解析为一个Pydantic对象。这就是整个流程,正如我们所说,这是利用了函数调用。如果我们回到下面,我们在这里设置了查询分析器链。现在让我们尝试仅在纯语义输入上运行它。“从零开始构建检索增强生成(RAG)”,我们运行一下,你可以看到它只是进行了内容搜索和标题搜索,这正是你所期望的。现在如果我们传入一个包含日期过滤器的问题,让我们看看是否可行。看,你仍然会得到语义搜索,但你也会得到例如对最早和最晚发布日期的搜索,正如你所期望的那样。让我们再试一个:“查找2024年之前发布的关于Chat LangChain主题的视频”。这只是用稍微不同的方式重写了这个问题,使用了不同的日期过滤器。然后你可以看到,我们得到了内容搜索、标题搜索,然后还得到了日期搜索。
所以这是一个非常通用的策略,可以广泛应用于你想要进行的不同类型的查询。它实际上是将非结构化输入转换为遵循你提供的任意模式的结构化查询对象的过程。正如所提到的,我们在这里创建的整个“本教程搜索”是基于我们感兴趣的向量存储的具体情况。如果你想了解更多关于这方面的信息,我在这里链接了一些文档,这些文档详细介绍了我们与不同向量存储供应商进行的各种集成,以实现这一点。这是一个非常有用的技巧,它允许你根据自然语言问题即时进行元数据过滤。这是一个非常方便的技巧,适用于许多不同的向量数据库。所以鼓励你尝试一下,谢谢。