对于Advanced RAG系统,你不得不知道的三个阶段优化技巧 原创
我阅读了一篇有关"Advanced RAG"的论文,在阅读这篇论文后,我发现其中的一些概念和技术具有很高的实用价值。接下来,我将结合我在公司的实践经验,分享以下RAG系统的三个阶段的优化:
- 预检索和数据索引技术
- 检索技术
- 检索后处理预检索和数据索引技术
使用LLM 增加信息密度
如果来⾃异构数据源(例如 PDF、抓取的⽹络数据、⾳频记录)的⾮结构化数据没有经过特定处理,信息密度比较低下,包含不相关的信息和/或噪⾳,或者有很多信息重复,这使得 RAG 系统在 LLM 上下⽂窗⼝中插⼊更多块以正确回答⽤⼾查询,从⽽增加令牌的使⽤和成本。此外,低信息密度会稀释相关信息,以⾄于LLM可能会做出错误的回应。GPT-4 似乎对这个问题有相对的抵抗⼒ 当使⽤少于 70,000 个令牌时,但其他模型可能不那么强 ⼤。
比如我们之前在用爬虫爬取用户网页的时候,但原始 HTML 包含⼤量不相关的信息(例如 CSS 类、标头/⻚脚导航、HTML 标签、⻚⾯之间的冗余信息)。即使通过编程⽅式剥离 CSS 和 HTML,信息密度仍然很低。因此,为了提⾼我们块中的信息密度,我们尝试使⽤ GPT-4 作为事实提取器,从⽂档中收集相关信息。删除 CSS 和 HTML 标签后,我们使⽤类似于下⾯的 LLM 调⽤来处理每个抓取的⽹⻚,然后将其分块并插⼊到我们的知识库中:
fact_extracted_output = openai.ChatCompletion.create(
model="gpt-4",
messages=[
{
"role": "system",
"content": "You are a data processing assistant. Your task is to extract meaningful information from a scraped web page from sendme. This information will serve as a knowledge base for further customer inquiries. Be sure to include all possible relevant information that could be queried by sendme's customers. The output should be text-only (no lists) separated by paragraphs.",
},
{
"role": "user",
"content": "<scraped web page>"
},
],
temperature=0
)
信息丢失的⻛险使用大型语言模型(LLMs)来提高信息密度的风险在于,关键信息可能会丢失。所以使用这种策略的时候你需要对知识信息密度有个判断,以防输入内容已经信息密集而经过LLM处理后丢失了一部分信息。
应用分层索引检索
通过利⽤ LLM ⽣成的摘要的多层检索系统可以提⾼搜索效率. 分层索引检索的实践利⽤⽂档摘要 来简化相关信息的识别,以便⽣成响应。
这些摘要⽂档⽀持对⼤型数据库进⾏⾼效搜索。与仅创建由⽂档块组成的单个数据索引不同,由 ⽂档摘要组成的附加数据索引创建了第⼀层过滤机制,该机制可从摘要与搜索查询⽆关的⽂档中 排除⽂档块。
生成假设性问题提高检索对称性
LLM 还可以将⽂档转换为适合 RAG 系统中使⽤的嵌⼊模型和查询的格式。⼀种⽅法是使⽤ GPT-4 为每个⽂档⽣成假设/可能的问答对列表,然后使⽤⽣成的问题作为要嵌⼊检索的块。
在检索时,系统将检索问题及其对应的答案并提供给LLM。因此,查询的嵌⼊可能与⽣成的问题 的嵌⼊具有更⼤的余弦相似度。这种相似性降低了在分块过程中丢失相关上下⽂的⻛险。因此, 每个问答对都是独⽴的,理论上将包含所有所需的上下⽂。
我们在自己的RAG推荐系统中,当用户上传一个文档时,可以指定是否生成QA, 检索的时候会对QA和chunk同时进行召回,从而提高检索的对称性。Langchain和llamaindex 都有对应的QA生成的工具,你可以参考相关文档,主要是参考它们的prompt. 这里给出一个示例prompt:
generated_question_answer_pairs = openai.ChatCompletion.create(
model="gpt-4",
messages=[
{
"role": "system",
"content": "Analyze the provided text or html from Example bank’s website and create questions an Example bank customer could ask a chatbot about the information in the text. You should not create a question if it does not have a useful/informative answer to it that would be helpful for a customer. For every question, please formulate answers based strictly on the information in the text. Use Q: for questions and A: for answers. Do not write any other commentary. Questions should not reference html sections or links. Create as many useful Q&A pairings as possible.",
},
{
"role": "user",
"content": "<scraped web page>"
},
],
temperature=0
)
假设性问题指数的⻛险和替代⽅案
使⽤这种先进的 RAG 技术,信息丢失的⻛险仍然存在。对于信息密度⾼的⽂档,LLM 可能⽆法 ⽣成⾜够的问答对来涵盖⽤⼾可能对⽂档中的信息提出的⼀系列查询。
此外,根据⽂档存储的⼤⼩,使⽤ LLM 处理和转换每个⽂档以缓解查询⽂档不对称可能会成本过 ⾼。
最后,根据 RAG 系统的流量,更有效的解决⽅案可能是反向⽅法,称为假设⽂档嵌⼊ (HyDE), ⽤于转换⽤⼾查询⽽不是⽂档。我们将在下⾯的检索技术部分进⼀步讨论 HyDE。
测试并优化你的分块策略
找到最佳分块策略的唯⼀⽅法是对您的 RAG 系统进⾏⼴泛的 A/B 测试。以下是测试时要考虑的⼀些最重要的因素。
嵌⼊模型
不同的嵌⼊模型在不同输⼊⼤⼩下具有不同的性能特征。例如,句⼦转换器的嵌⼊模型在嵌⼊单 个句⼦⽅⾯表现出⾊,⽽ text-embedding-ada-002 可以处理更⼤的输⼊。理想情况下,块⼤⼩ 应根据所使⽤的特定嵌⼊模型进⾏量⾝定制,反之亦然。
嵌⼊内容的性质
根据⽂档的信息密度、格式和复杂程度,块可能需要达到⼀定的最⼩⼤⼩,才能包含⾜够的上 下⽂,以供 LLM 使⽤。然⽽,这是⼀个平衡⾏为。如果块太⼤,它们可能会稀释嵌⼊中的相关 信息,从⽽降低语义搜索期间该块的检索⼏率。
如果您的⽂档不包含⾃然断点(例如,教科书章节中带有副标题),并且⽂档根据任意字符限制 (例如 500 个字符)进⾏分块,则存在关键上下⽂信息被拆分的⻛险。在这种情况下,应考虑重 叠。例如,重叠率为 50% 的分块策略意味着⽂档中两个相邻的 500 个字符的块将相互重叠 250 个字符。在决定重叠率时,应考虑信息重复和嵌⼊更多数据的成本。
要嵌⼊的查询的复杂性或类型
如果您的 RAG 系统处理⼤段落的查询,那么将数据分成⼤段落是有意义的。但是,如果查询只 有⼏个词,那么⼤块⼤⼩可能不利于最佳信息检索。这时候可以使用混合检索来提升信息检索能力。
我们的经验
通过在我们由 LLM 提供⽀持的 RAG 评估系统的帮助下进⾏⼴泛的 A/B 测试,我们可以评估每 个⽤例的最佳分块策略。
我们测试了以下分块策略,主要针对 GPT-4 处理的改进的信息密集型⽂档:
- 1,000 个字符的块,其中有 200 个字符的重叠
- 500 个字符的块,100 个字符的重叠
- 段落(处理后的⽂档中存在段落中断)
- 句⼦(使⽤ spaCy 拆分)
- 假设性问题(从上⾯详述的⽣成的假设性问题索引中嵌⼊问题)
在我们的RAG推荐系统中,采⽤ 200 个字符重叠策略的 1,000 个字符块的表现略优于其他策略。
检索技术
使用假设⽂档嵌⼊(HyDE)修复查询⽂档不对称
正如我们在预检索技术部分中提到的,我们可以利⽤ LLM 来解决查询⽂档不对称问题并改善检 索结果。我们还可以通过应⽤ HyDE 在检索阶段实现更⾼的语义相似度。
我们通过在检索发⽣之前的推理时间请求 LLM ⽣成⼀个假设⽂档或⽂档块来回答查询来实现这 ⼀点。下⾯是⼀个⽰例提⽰,我们将其与 1000 个字符的分块策略⼀起使⽤来⽣成⽤于语义搜索 的假设⽂档:
prompt = "Please generate a 1000 character chunk of text that hypothetically could be found on Example bank's website that can help the customer answer their question."
然后嵌⼊该假设⽂档或块,并⽤它代替⽤⼾查询进⾏语义搜索。这个想法是,在查询⽂档不对 称的 RAG 系统中,假设⽂档或块与所需块的语义相似度将⾼于⽤⼾查询本⾝。
使用 LLM 优化搜索查询
请看以下⽰例对话:
客⼾:“你们的存单利率是多少?” 助理:“我们的利率是 XYZ。”
顾客:“哪种信⽤卡适合旅⾏?”
助理:“XYZ 信⽤卡适合出于 ABC 原因的旅⾏” 客⼾:“告诉我更多关于这个利率的信息”
为了回答⽤⼾的最后⼀个问题,可能需要进⾏语义搜索来检索有关特定 XYZ 旅⾏信⽤卡的信息。那么,搜索查询应该是什么?仅仅使⽤最后⼀个⽤⼾消息是不够具体的,因为⾦融机构可能有许 多产品会产⽣利息。在这种情况下,语义搜索会产⽣⼤量可能不相关的信息,这些信息可能会挤 占 LLM 上下⽂窗⼝中的实际相关信息。
那么将整个对话记录⽤作语义搜索查询怎么样?这可能会产⽣更好的结果,但它们仍可能包含与 对话中⽤⼾最新问题⽆关的信息。
到⽬前为⽌,我们发现的最佳⽅法是使⽤ LLM 以对话作为输⼊来⽣成最佳搜索查询。对于上⾯的 ⽰例对话,提⽰如下所⽰:
systemPrompt = "You are examining a conversation between a customer of Example bank and an Example bank chatbot. A documentation lookup of Example bank’s policies, products, or services is necessary for the chatbot to respond to the customer. Please construct a search query that will be used to retrieve the relevant documentation that can be used to respond to the user."
实现查询路由或 RAG 决策器模式
查询路由器是我们⻅过的更流⾏的⾼级 RAG 技术之⼀。其理念是当 RAG 系统使⽤多个数据源 时,使⽤ LLM 将搜索查询路由到适当的数据库。这涉及在提⽰中预定义路由决策选项,并解析 LLM 的路由决策输出,以便可以在代码中使⽤。
为了帮助降低成本并提⾼ RAG 的质量,我们开发了这种技术的变体,称之为 RAG 决策模 式。
⼀个不太明显的例⼦是,回答⽤⼾查询所需的所有信息都已存在于最近的对话历史记录中。在这 种情况下,LLM 只需重复或稍微改述之前的内容。例如,“您能将您最后⼀条消息翻译成西班⽛ 语吗?”或“请像我五岁⼩孩⼀样解释⼀下最后⼀条消息。”这两个查询都不需要进⾏新的检 索,因为 LLM 只需使⽤其内置功能即可回答查询。
在我们的案例中,当 RAG 决策者决定对于给定的⽤⼾查询不需要进⾏完整的 RAG 查找时,我们 会⽤不提及 RAG 结果或⽂档的prompt来处理用户的query。
另⼀种⽅法可能是让单个 LLM 代理决定是否通过函数调⽤或其他机制(例如,在⾃⾝RAG ) ⽽ 不是委托给单独的 LLM 调⽤。
检索后处理( Post-Retrieval )
检索后优化涵盖检索发⽣之后但在最终响应⽣成之前采⽤的策略或技术。
此时需要考虑的⼀个重要问题是:即使部署了上述所有预检索和检索策略,仍然⽆法保证我们检 索到的⽂档将包含 LLM 回答查询所需的所有相关信息。这是因为检索到的⽂档可以是以下任意或所有类别的混合:
- 相关⽂档(即包含回答⽤⼾查询所需信息的⽂档)
- 相关但不相关的⽂件
- 不相关和不相关的⽂件
- 反事实⽂件(即与正确的相关⽂件相⽭盾的⽂件)
有研究表明相关但不相关的⽂档对 RAG 系统的危害最⼤研究⼈员发现“在某些情况下,准确度会下降超过 -67%。更重要的是,仅添加⼀份相关⽂档就会导致准确度急剧下降,峰值为 -25%……实证分析表明,引⼊语义⼀致但不相关的⽂档会增加⼀层复杂性,可能会误导 LLM 得出正确的答案。”
也许更令⼈惊讶的是,同样的研究⼈员发现与查询⽆关和不相关的⽂档“如果放置正确,实际上 有助于提⾼这些系统的准确性。
通过Rerank确定搜索结果的优先级
研究表明,将最相关的⽂档放在提⽰中最靠近查询的位置可以提⾼ RAG 的性能。
重新排序模型可优化给定查询的区块搜索结果的优先级。此技术与混合检索系统和查询扩展相结 合时效果很好。
使用上下⽂提⽰压缩优化搜索结果
LLM可以处理每个块中的信息,以过滤、重新格式化甚至压缩数据块生成提示符的最后几位信息。
LLMLingua是实现这种方法的一个很有前途的框架。LLMLingua使用一个小的语言模型,如GPT2-small或LLaMA-7B,以检测和删除不重要的提示中的令牌。它还支持使用黑盒中的压缩提示符进行推理llm,以最小的性能损失实现高达20倍的压缩。LongLLMLingua通过考虑输入查询,进一步使其适用于RAG系统在执行压缩以删除通常不重要的令牌时对正在讨论的查询不重要。
值得注意的是,除了充分理解和使用压缩提示回答查询(例如,作为RAG的一部分),即使提示不是 人类可读的GPT-4也可用于反转或解压缩输入。
使用 corrective RAG 对检索到的⽂档进⾏评分和过滤
corrective RAG 通过训练 T5-Large 模型来识别 RAG 结果对于给定问题⽽⾔是正确/相关、模糊还是不正确,然后将结果提供给 LLM 以⽣成最终答案。未通过分类为正确/相关或模糊的阈值的 RAG 结果将被丢弃。
与使⽤ Self-RAG 进⾏微调的 Llama-2 7B 模型所使⽤的批评⽅法相⽐,使⽤ T5-Large 模型更加轻量,并且可以与任何⼤型语⾔模型结合使⽤。
总结
下面给出一些简单的结论,这些结论可以根据你的实际需求应用到项目中:
- 信息密度:使用 GPT-4 提取信息后,信息量显著减少,信息密度提高。
- 检索效率:层次索引检索和假设问题索引显著提高了检索效率和结果的相关性。
- 分块策略:1,000 字符分块与 200 字符重叠的策略表现最佳。
- 假设文档嵌入:使用假设文档嵌入进行语义搜索,提高了检索结果的准确性。
- 查询路由和 RAG 决策模式:识别出不需 RAG 查找的查询,避免了不必要的计算资源消耗。
- 重新排序和压缩:重新排序搜索结果和使用 LLM 压缩生成提示,提高了生成响应的质量和效率。
- 评分和过滤:使用 T5-Large 模型评分和过滤 RAG 结果,显著提高了响应的准确性。
本文转载自公众号AI 博物院 作者:longyunfeigu