原文地址:Improving RAG: Self Querying Retrieval
2024 年 2 月 11 日
让我们来解决构建 RAG 系统时的一个大问题。
我们不能依赖语义搜索来完成每个检索任务。只有当我们追求单词的含义和意图时,语义搜索才有意义。
But in case,我们正在对数据库中的内容进行搜索,就像我们可能只想执行查找任务一样,使用语义搜索是不合逻辑的。它甚至可能给出不准确的结果,并使用不必要的计算能力。
在处理 Excel 文件或财务数据时,通常会出现此问题。对于这些情况,LangChain 提供了一个名为“自查询检索”的实用程序。
我们所做的很简单。我们在检索和输入之间插入一个“步骤”。
- 用户输入查询。
- 我们使用语言模型对查询进行重新格式化,以获取查询的语义要素。
- 我们还将转换查询,以便对元数据进行搜索。
重申一下,这个想法非常简单。如果我们要查找一部电影,并想查看年份,我们就会进入矢量存储。我们只需查找年份,然后将结果筛选回该年份。
基础知识已经清楚了,现在让我们来了解一下 LangChain 如何帮助我们实现自查询。
我们使用 "自查询"(Self Query)检索器。自查询"检索器允许我们查询矢量数据库。让我们来看看这种自查询检索器是如何实现的。
自查询基类的唯一类方法是 from_llm
。创建自查询类需要四个必需参数:llm
、vectorstore
、document_contents
和 metadata_field_info
。
llm
用于传递语言模型。vectorstore
用于传递一个向量存储空间document_contents
参数指文档内容的简短描述。metadata_field_info
是AttributeInfo
对象的序列,是包含矢量数据库中数据信息的字典。我们定义了一个AttributeInfo
对象列表,其中包含每个属性及其数据类型的信息,以便语言模型知道它正在处理什么。
我不打算讨论可选参数。
现在,让我们看看如何处理参数。根据传入的参数,我们使用一系列 if 语句来决定要做什么。
首先,我们会检查是否有已定义的结构化查询翻译器。如果没有,我们就使用已定义向量存储的内置翻译器。
接下来,我们检查链关键字参数。我们可以将它们设置为传入的值,也可以保持为空字典。在接下来的两个 if
语句中,我们将继续检查这些参数。我们查找的两个键是 allowed comparators
和 operators
。这些键决定了我们如何编写过滤表达式。
定义好一切后,我们就可以创建查询构造函数了。我们需要传递 LLM、文档内容描述、元数据字段、是否要启用限制以及要传递给链的关键字参数。定义完所有这些元素后,函数将返回一个 Runnable
对象,允许我们执行指定的脚本。
query_constructor = load_query_constructor_runnable(llm,document_contents,metadata_field_info,enable_limit=enable_limit,**chain_kwargs,)
在这个类方法的最后,我们需要返回 自查询检索器。该方法返回 self query 类的一个实例。我们传入刚刚定义的查询构造函数,以及传入的向量存储、是否使用原始查询、翻译器和关键字参数列表。
return cls(query_constructor=query_constructor,vectorstore=vectorstore,use_original_query=use_original_query,structured_query_translator=structured_query_translator,**kwargs,)
通过这种方法,我们只需传递四个必填字段即可创建 RAG 应用程序。LLM、矢量数据库、文档描述和元数据信息。