14个文本转图像AI API
从预检索到生成的15种高级RAG技术(篇一)
缘起
今晚浏览WillowTree网站的时候,发现了一本宝藏级的RAG技巧指南。
这篇指南中,WillowTree 的数据和人工智能研究团队 (DART) 分享了 15 种用于微调的高级 RAG 技巧,并证实,在优化客户的应用程序时取得了明显的效果。
从今天开始,我将分为以下五篇文章,翻译介绍这15种RAG高级技巧,欢迎大家一起学习:
- 预检索和数据索引,5种高级RAG技巧
- 检索中,3种高级RAG技巧
- 检索后,3种高级RAG技巧
- 生成中,4种高级RAG技巧
- 其它注意事项及技巧
预检索和数据索引技术
预检索优化主要包括提高数据索引或知识数据库中信息的质量和可检索性。这里所需的技术和工作量在很大程度上取决于数据的性质、来源和规模。例如,优化信息密度可以提高用户体验,通过生成更准确的响应并减少token数来降低成本。但是,我们如何在系统之间进行优化变化呢?针对旅行行业聊天机器人增强检索的优化可能会在金融人工智能助手中产生惊人的逆效果,因为每个系统依赖于不同性质和独特监管框架的信息。在预检索阶段,LLMs为我们提供了许多优化信息的方式,使我们能够根据目标测试和微调不同的方法。以下是五种值得在预检索阶段探索的基于LLM的高级RAG技术。
技术1:使用LLMs增加信息密度
您可以通过使用LLMs在存储之前处理、清洁和标记数据,显著提高RAG系统的性能。这种改进是因为来自异构数据源(例如PDF、抓取的网络数据、音频转录)的非结构化数据未必为RAG系统而构建,会导致以下问题:
- 信息密度低
- 不相关的信息和/或噪音
- 信息重复
低信息密度会迫使RAG系统向LLM上下文窗口中插入更多块以正确回答用户查询,增加token使用和成本。此外,低信息密度会使相关信息稀释到LLM可能错误回复的程度。当使用低于70,000个token时,GPT-4似乎相对抵抗这个问题,但其他模型可能没有那么强大。以下是我们最近遇到的一个场景,当在RAG系统上工作时可能很容易发生:我们作为主要数据源抓取了数百个网页,但原始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 XYZ
Corp. 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 XYZ Corp’s customers. The output
should be text-only (no lists) separated by paragraphs.”,
},
{“role”: “user”, “content”: <scraped web page>},
],
temperature=0)
以下是经过我们管道处理的匿名抓取⽹⻚内容⽰例。从左列开始,我们发现原始 HTML 代码段 的有⽤信息密度较低。
在程序化剥离CSS、JS和HTML后,中央片段的情况有所改善,但仍不包含高质量信息。现在,看看右侧片段,其中包含经过GPT-4处理的事实提取内容,注意信息密度的飞跃。这是我们在分块和嵌入过程中使用的方法。值得注意的是,单个网页文本在不同阶段的token计数如下:
- 原始HTML:约55,000个token
- 剥离HTML:1,500个token
- GPT-4处理后的HTML:330个token
尽管token数量最显著的减少(20倍)是通过对CSS、JS和HTML进行编程剥离实现的,但应用于剥离后的HTML的GPT-4事实提取步骤始终将标记数量进一步减少了500%。我们尝试了一个流程,其中保留HTML标记,以防HTML结构中存在某种语义含义,但在我们的案例中,我们的RAG评估指标显示,去除标记后性能有所提升。警告:信息丢失的⻛险使用大型语言模型(LLMs)增加信息密度的风险在于可能丢失关键信息。减轻这一风险的一种策略是确保事实提取LLM输出的最大大小要么a)没有限制,要么b)小于输入内容的大小,以防输入内容已经非常丰富且100%有用。
技术2:应用分层索引检索
通过利用LLM生成的摘要,可以通过多层检索系统使搜索变得更有效。分层索引检索的实践利用文档摘要来简化识别用于响应生成的相关信息。
前一节着重于提高信息密度而不丢失相关信息,类似于无损压缩。然而,在生成文档摘要时,LLMs执行的更类似于有损压缩。
这些摘要文档支持对大型数据库的高效搜索。与仅创建由文档块组成的单个数据索引不同,由文档摘要组成的额外数据索引创建了一个第一层过滤机制,该机制排除了具有与搜索查询无关的摘要的文档块。
技术3:通过假设性问题索引改善检索对称性
LLMs还可以将文档转换为对于嵌入模型和RAG系统中使用的查询都最优的格式。一种方法是使用GPT-4为每个文档生成一组假设/可能的问题和答案对,然后使用生成的问题作为要嵌入以进行检索的块。在检索时,系统将检索问题及其相应的答案,并将它们提供给LLM。因此,查询的嵌入很可能与生成的问题的嵌入具有更高的余弦相似度。这种相似性降低了在分块过程中丢失相关上下文的风险。每个问答对因此是独立的,并在理论上将包含所有所需的上下文。查询和用于检索的文档之间的不对称在RAG系统中是一个常见问题。查询通常是简短的问题,比如:“XYZ金融机构提供的最佳旅行信用卡是什么?”然而,针对该查询的相关文档块要长得多(例如,包含所有由XYZ金融机构提供的信用卡的详细内容的段落)。这个金融服务示例为语义搜索提出了问题:如果查询与文档块明显不同(即,不对称性过大),语义相似性可能很低,这可能导致搜索结果不佳,并使系统偏向错误的信息。下⾯的图表说明了我们如何使⽤假设问题索引:
这是我们使⽤的提⽰:
generated_question_answer_pairs = openai.ChatCompletion.create(
model=”gpt-4”,
messages=[
{
“role”: “system”,
“content”: “Analyze the provided text or html from Example bank’s
Here’s a diagram illustrating how we used a hypothetical question index:
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)
利用LLMs生成问答对对于RAG系统的基准测试和评估也可能是有益的。这些问答对可以作为问题和期望答案的黄金标准数据集,整个RAG系统应该能够回答这些问题。
至于减少块大小,该方法只能走得这么远,因为块必须保持最小尺寸以保留足够的上下文信息以便有用。即使使用更大的块大小,始终存在在分块过程中丢失关键上下文信息的风险。可以通过基于诸如大小和重叠比率之类的分块考虑进行实验来减轻(但无法消除)这种风险。注意事项:假设性问题索引的风险和替代方案信息丢失仍然是这种先进的RAG技术的风险。对于高度信息密集的文档,LLMs可能无法生成足够的问答对来覆盖用户可能对文档中信息的各种查询。此外,根据您的文档存储大小,使用LLM处理和转换每个文档以减轻查询-文档不对称可能成本过高。最后,根据您的RAG系统的流量,一个更有效的解决方案可能是一种名为假设性文档嵌入(HyDE)的反向方法,用于转换用户查询而不是文档。我们将在下面的检索技术部分进一步讨论HyDE。
技术4:使用LLMs在数据索引中去重信息
使用LLMs作为信息去重器可以提高数据索引的质量。LLM通过将块精简为较少的块来去重信息,提高了获得理想响应的几率。这是一项有价值的技术,因为根据情况不同,数据索引中的信息重复可能有助于或阻碍RAG系统的输出。一方面,如果用于回答查询所需的正确信息在LLM生成响应的上下文窗口中重复,那么LLM产生理想响应的可能性增加。相反,如果重复的程度削弱甚至完全排除了LLM上下文窗口中的所需信息,那么用户可能会收到非答案,甚至更糟糕,是来自RAG系统的AI幻觉。我们可以通过在嵌入空间中对块进行k均值聚类,使每个块簇中的聚合token数适合LLM的有效上下文窗口。从这里,我们可以让LLM从原始簇中简单地输出一组经过精简的新块,以去除重复信息。如果一个给定的簇包含N个块,我们应该期望这个去重提示输出小于或等于N个新块,其中新块中删除了任何多余信息。以下图显示了信息去重之前和之后在嵌入空间中的块。
注意:这个过程使得在您的RAG系统中包含任何引用系统变得更加困难,因为新的块可能包含来自多个文档的信息。此外,信息丢失的风险仍然存在,以及降低信息重复在检索系统中可能受益的风险。
技术5:测试和优化您的分块策略
上述技术强调了分块策略的重要性。但是,最佳的分块策略是特定于用例的,许多因素影响着它。找到最佳的分块策略的唯一方法是广泛地对您的RAG系统进行A/B测试。在测试时需要考虑以下一些最重要的因素。
1、嵌入模型:
不同的嵌入模型在不同的输入大小下具有不同的性能特征。例如,来自句子转换器的嵌入模型在嵌入单个句子时表现出色,而text-embedding-ada-002可以处理更大的输入。块的大小应该理想地根据所使用的具体嵌入模型进行定制,反之亦然。
2、要嵌入的内容的性质:根据文档的信息密度、格式和复杂性,块可能需要具有一定的最小尺寸才能包含足够的上下文信息以便LLM使用。然而,这是一个平衡的过程。如果块太大,它们可能会在嵌入中稀释相关信息,降低在语义搜索期间该块的检索概率。如果您的文档没有自然的断点(例如,用子标题分割的教科书章节),并且文档是基于任意字符限制(例如,500个字符)进行分块的,那么存在关键上下文信息被分割的风险。在这种情况下,应该考虑重叠。例如,具有50%重叠比率的分块策略意味着文档中两个相邻的500字符块将相互重叠250个字符。在决定重叠比率时,应考虑信息重复和嵌入更多数据的成本。
3、查询的复杂性或嵌入类型如果您的RAG系统处理以大段落提出的查询,那么将数据分块成大段落是有意义的。然而,如果查询只有几个词长,大块大小可能不利于最佳信息检索。4、LLM的能力、上下文窗口和成本虽然GPT-4似乎能够处理许多大块,但更小的生成模型可能表现不佳。此外,在许多大块上运行推断可能成本高昂。5、要嵌入的数据量嵌入必须存储在某个地方,而较小的块大小会导致相同数据量的更多嵌入,这意味着增加的存储需求和成本。更多的嵌入还可能增加用于语义搜索的计算资源,这取决于您的语义搜索是如何实现的(精确最近邻 vs. 近似最近邻)。我们的经验通过借助我们基于LLM的RAG评估系统进行广泛的A/B测试,我们可以为我们的每个用例评估最佳的分块策略。
我们主要在由GPT-4处理的改进信息密集文档上测试了以下分块策略:
- 1,000字符块,重叠200个字符
- 500字符块,重叠100个字符
- 段落(文档中存在段落分隔)
- 句子(使用spaCy进行分割)
- 假设性问题(从上述生成的假设性问题索引中嵌入问题)
在构建我们的金融服务AI助手时,我们发现分块策略的选择并没有太大影响(请参见下表中的结果)。具有重叠200个字符的1,000字符块策略表现略优于其他策略。
我们对分块策略为何显著影响我们的用例提出的假设包括:
- 我们构建RAG应用程序的领域并不太复杂
- 数据集对分块策略的影响不大,因为数据集太小
- 我们使用GPT-4进行处理以提高信息密度产生了最大的影响
然而,只要我们对应用程序进行了一次改变,比如为更复杂的领域构建,我们很可能会看到不同的结果。
其他预检索优化技术
我们渴望测试更先进的RAG技术,用于预检索和数据索引。这些技术包括递归检索,通过迭代一个检索步骤的输出并将其用作另一个步骤的输入来支持复杂的多步查询。通过句子窗口和父子块检索进行上下文丰富化也让我们感兴趣,这是一种改进搜索和丰富LLM响应的方式。
后记
以上分享的5种高级RAG技巧,主要是面向预检索和数据索引方向,后面会陆续针对RAG检索中、检索后、生成中等方向分享另外的10种RAG技巧。
文章转自微信公众号@耳东观察