
为什么 RAG 系统"一看就会,一做就废"? 原创
随着大模型(LLM)的广泛应用,检索增强生成(RAG)技术作为一种创新架构,因其在结合外部知识库和生成模型方面的卓越表现而备受关注。RAG 技术通过将 LLM 与结构化或非结构化的外部数据源相结合,显著提升了生成内容的准确性、相关性和可信度。
第一、RAG 的优势
RAG 技术在多个领域表现出色,尤其是在聊天机器人、知识密集型任务和企业应用中。通过检索外部知识库,RAG 能够为 LLM 提供更丰富的上下文信息,从而生成更准确、更相关的内容。这种结合不仅提高了回答的可信度,还减少了生成模型的“幻觉”现象。
第二、RAG 的挑战
然而,从理论到工程实践,开发和优化一个高效的 RAG 系统并非易事。RAG 系统面临着诸多挑战,主要包括以下几个方面:
1、检索效率
检索阶段需要在大规模数据集中快速找到相关文档,这对检索系统的效率和准确性提出了很高的要求。如何在几亿篇文档中快速找到与查询最相关的文档片段,是 RAG 系统面临的一个关键问题。
2、生成质量
生成阶段需要将检索到的文档片段有效地整合到生成的回答中,这对生成模型的能力提出了挑战。如何避免生成的回答中出现冗余或不连贯的内容,是提升生成质量的关键。
3、上下文窗口限制
生成模型的上下文窗口有限,这意味着它能够处理的文档片段数量是有限的。如何在有限的上下文窗口中选择最相关的文档片段,是优化 RAG 系统的一个重要方向。
4、系统集成
RAG 系统需要将检索模块和生成模块无缝集成,确保整个系统的流畅运行。如何优化系统架构,确保检索和生成模块之间的高效协作,是 RAG 系统开发中的一个难点。
第三、RAG 的优化路径
为了克服这些挑战,我们可以从以下几个方面进行系统性的分析和优化:
1、改进检索模型
使用更高效的检索模型,如稀疏-密集混合检索模型,提高检索的效率和准确性。例如,结合稀疏嵌入模型和向量搜索,可以在大规模数据集中快速找到相关文档。
2、优化生成模型
使用更强大的生成模型,如预训练语言模型(比如:DeepSeek R1、QwQ 等),提高生成回答的质量。同时,可以通过微调生成模型,使其更好地适应特定领域的任务。
3、引入重排序(Rerank)
在检索阶段引入重排序模型,对检索到的文档片段进行重新排序,确保传递给生成模型的文档片段是最相关的。重排序模型可以显著提高检索结果的相关性,从而提升生成回答的质量。
4、优化系统架构
优化 RAG 系统的整体架构,确保检索模块和生成模块之间的高效协作。例如,可以通过两阶段检索策略,先快速筛选出候选文档,再进行精细排序,从而在保证效率的同时,提升系统的整体性能。
1、RAG 系统的12个问题
在工程实践中,RAG(检索增强生成)系统面临着诸多挑战。澳大利亚吉朗应用人工智能研究所的 Scott Barnett 等人在论文《Seven Failure Points When Engineering a Retrieval Augmented Generation System》中,深入探讨了这些问题,并总结了以下 7 个常见问题:
1. 缺失内容(Missing Content)
当用户的问题无法从文档库中检索到相关内容时,可能会导致大模型(LLM)产生“幻觉”现象。理想情况下,RAG 系统可以简单地回复“抱歉,我不知道”。然而,如果用户问题能够检索到文档,但文档内容与用户问题无关,LLM 仍可能被误导。
2. 错过超出排名范围的文档(Missed Top Ranked)
由于 LLM 的上下文长度限制,从文档库中检索时,通常只返回排名靠前的 K 个段落。如果问题的答案所在段落超出了排名范围,就会导致问题无法得到正确回答。
3. 不在上下文中(Not In Context)
即使包含答案的文档已经成功检索出来,但这些文档可能没有被包含在 LLM 所使用的上下文中。当从数据库中检索到多个文档,并通过合并过程提取答案时,这种情况尤为常见。
4. 未提取(Not Extracted)
答案可能存在于提供的上下文中,但 LLM 未能准确提取出来。这通常发生在上下文中存在过多噪声或冲突信息时。
5. 错误的格式(Wrong Format)
用户的问题可能要求以特定格式提取信息,例如表格或列表,但 LLM 忽略了这一指示。
6. 不正确的具体性(Incorrect Specificity)
尽管 LLM 正常回答了用户的问题,但回答可能不够具体或过于具体,无法满足用户的需求。这种情况也可能发生在用户不确定如何提问或提问过于笼统时。
7. 不完整的回答(Incomplete Answers)
例如,用户提问“文件 A、B、C 包含哪些关键点?”直接使用这个问题检索可能只能得到每个文件的部分信息,导致 LLM 的回答不完整。一个更有效的方法是分别针对每个文件提出具体问题,以确保全面覆盖。
其他问题
Wenqi Glantz 在文章《12 RAG Pain Points and Proposed Solutions》中,又提出了另外 5 个问题:
8. 数据摄取的可扩展性问题(Data Ingestion Scalability)
RAG 管道中的数据摄取可扩展性问题是指系统在处理大量数据时可能遇到的挑战。这些问题可能导致摄取时间延长、系统过载、数据质量问题和可用性受限等。
9. 结构化数据的问答(Structured Data QA)
准确检索用户问题所需的结构化数据可能很困难,尤其是当用户的问题比较复杂或模糊时。当前的文本到 SQL 转换技术不够灵活,且 LLM 在处理这类任务时仍存在局限性。
10. 从复杂 PDF 文档提取数据(Data Extraction from Complex PDFs)
复杂的 PDF 文档可能包含表格、图片等嵌入内容。传统的检索方法在处理这类文档时往往效果不佳,需要更高效的方法来提取数据。
11. 备用模型(Fallback Model(s))
在使用单一 LLM 时,可能会遇到模型故障或访问频率限制等问题。此时,需要一个或多个备用模型来确保系统的稳定运行。
12. 大语言模型的安全性(LLM Security)
防止恶意输入、确保输出安全、保护敏感信息不被泄露等,是每个 AI 架构师和工程师需要面对的重要挑战。
2、RAG 系统的12个优化策略
从 RAG(检索增强生成)的工作流程来看,各个环节都存在优化空间。结合上述提到的 12 个问题,我们可以从 RAG 工作流程的 5 个关键环节入手,详细了解具体的优化策略。
1. 数据清洗(Clean your data)
高性能的 RAG 系统依赖于准确且清洁的原始知识数据。为了确保数据的准确性,需要优化文档读取器和多模态模型。特别是处理如 CSV 表格等文件时,单纯的文本转换可能会丢失表格原有的结构。因此,需要引入额外的机制在文本中恢复表格结构,比如使用分号或其他符号来区分数据。
此外,还需要对知识文档进行基本的数据清洗,包括:
文本清理:规范文本格式,去除特殊字符、干扰和不相关信息;删除可能使检索过程产生偏差的重复文档或冗余信息;识别并更正拼写错误和语法错误,拼写检查器和语言模型等工具可以帮助解决这个问题。
实体解析:消除实体和术语的歧义以实现一致的引用。例如,将“LLM”、“大语言模型”和“大模型”标准化为通用术语。
文档划分:合理地划分不同主题的文档。如果作为人类都不能轻松地判断出需要查阅哪个文档来回答常见的提问,那么检索系统也无法做到。
数据增强:使用同义词、释义甚至其他语言的翻译来增加语料库的多样性。
用户反馈循环:基于现实世界用户的反馈不断更新数据库,标记它们的真实性。
时间敏感数据:对于经常更新的主题,实施一种机制来使过时的文档失效或更新。
2. 分块处理(Chunking)
在 RAG 系统中,文档需要分割成多个文本块再进行向量嵌入。分块的目的是在保持语义上的连贯性的同时,尽可能减少嵌入内容中的噪声,从而更有效地找到与用户查询最相关的文档部分。分块策略包括:
固定大小的分块:设定块中的字数,并选择块之间是否重复内容。通常保持块之间的一些重叠,以确保语义上下文不会在块之间丢失。
内容分块:根据文档的具体内容进行分块,例如根据标点符号(如句号)分割,或者使用更高级的 NLTK 或 spaCy 库提供的句子分割功能。
递归分块:通过重复应用分块规则来递归地分解文本。例如,在 LangChain 中会先通过段落换行符(\n\n)进行分割,然后检查这些块的大小。如果大小不超过一定阈值,则该块被保留。对于大小超过标准的块,使用单换行符(\n)再次分割。
从小到大分块:将同一文档进行从大到小所有尺寸的分割,然后把不同大小的分块全部存进向量数据库,并保存每个分块的上下级关系,进行递归搜索。但这种方法需要更大的存储空间。
特殊结构分块:针对特定结构化内容的专门分割器,如 Markdown 文件、Latex 文件以及各种主流代码语言分割器。
分块大小的选择:不同的嵌入模型有其最佳输入大小。例如,OpenAI 的 text-embedding-ada-002 模型在 256 或 512 大小的块上效果更好。文档的类型和用户查询的长度及复杂性也是决定分块大小的重要因素。
3. 嵌入模型(Embedding Models)
嵌入模型能够将文本转换成向量。不同的嵌入模型带来的效果不同。例如,Word2Vec 模型生成的词向量是静态的,这在处理一词多义的情况时可能导致问题。相比之下,引入自注意力机制的模型,如 BERT,能够提供动态的词义理解。在选择嵌入模型时,可以参考 Hugging Face 推出的嵌入模型排行榜 MTEB,同时注意模型是否支持中文。
4. 元数据(Metadata)
当在向量数据库中存储向量数据时,某些数据库支持将向量与元数据(即非向量化的数据)一同存储。为向量添加元数据标注是一种提高检索效率的有效策略。常见的元数据标签包括日期、章节或小节的引用、文本的关键信息、小节标题或关键词等。这些元数据不仅有助于改进知识检索的准确性,还能为最终用户提供更加丰富和精确的搜索体验。
5. 多级索引(Multi-Level Indexing)
当元数据无法充分区分不同上下文类型时,可以考虑进一步尝试多重索引技术。多重索引技术的核心思想是将庞大的数据和信息需求按类别划分,并在不同层级中组织,以实现更有效的管理和检索。这意味着系统不仅依赖于单一索引,而是建立了多个针对不同数据类型和查询需求的索引。例如,可能有一个索引专门处理摘要类问题,另一个专门应对直接寻求具体答案的问题。这种多重索引策略使 RAG 系统能够根据查询的性质和上下文,选择最合适的索引进行数据检索,从而提升检索质量和响应速度。但为了引入多重索引技术,还需要配套加入多级路由机制,确保每个查询被高效引导至最合适的索引。
6. 索引/查询算法(Indexing/Query Algorithms)
利用索引筛选数据,但最终仍需从筛选后的数据中检索出相关的文本向量。由于向量数据量庞大且复杂,寻找绝对的最优解变得计算成本极高,有时甚至是不可行的。因此,通常采用最近邻搜索(Approximate Nearest Neighbor Search,ANNS)来找到“足够接近”或“相似”的项。在某些垂直领域,如法律、医疗、金融等,大模型的不确定性可能会带来致命的结果。因此,LLM + RAG 结合互补,以期望解决 LLM 在某些场景的短板。
7. 查询转换(Query Transformation)
在 RAG 系统中,用户的查询问题被转化为向量,然后在向量数据库中进行匹配。查询的措辞会直接影响搜索结果。如果搜索结果不理想,可以尝试以下几种方法对问题进行重写,以提升召回效果:
结合历史对话的重新表述:利用 LLM 重新表述问题,特别是在多轮对话中,将历史信息和用户提问一并交给 LLM 重新表述。
假设文档嵌入(HyDE):先让 LLM 在没有外部知识的情况下生成一个假设性的回复,然后将这个假设性回复和原始查询一起用于向量检索。
退后提示(Step Back Prompting):如果原始查询太复杂或返回的信息太广泛,可以选择生成一个抽象层次更高的“退后”问题,与原始问题一起用于检索。
多查询检索/多路召回(Multi Query Retrieval):使用 LLM 生成多个搜索查询,特别适用于一个问题可能需要依赖多个子问题的情况。
8. 检索参数(Retrieval Parameters)
在具体的检索过程中,可以根据向量数据库的特定设置来优化一些检索参数,包括:
稀疏和稠密搜索权重:结合稀疏搜索(如 BM25)和稠密搜索(向量搜索),并设定两者对最终结果评分的权重比例。
结果数量(TopK):足够的检索结果可以确保系统覆盖到用户查询的各个方面,但结果数量过多可能导致信息过载。
相似度度量方法:选择合适的相似度度量方法,如余弦相似度,因为它不受向量长度的影响,只反映方向上的相似度。
9. 高级检索策略(Advanced Retrieval Strategies)
在向量数据库检索之上,开发或改进整个系统的策略是关键和复杂的步骤。一些常用或新提出的策略包括:
上下文压缩:通过 LLM 的帮助对单个文档内容进行压缩,或者对返回结果进行一定程度的过滤,仅返回相关信息。
句子窗口搜索:将匹配到的分块周围的块作为上下文一并交给 LLM 进行输出,增加 LLM 对文档上下文的理解。
父文档搜索:先将文档分为尺寸更大的主文档,再把主文档分割为更短的子文档两个层级,用户问题会与子文档匹配,然后将该子文档所属的主文档和用户提问发送给 LLM。
自动合并:对文档进行结构切割,如按三层树状结构进行切割,在检索时只拿叶子节点和问题进行匹配,当某个父节点下的多数叶子节点都与问题匹配上则将该父节点作为结果返回。
多向量检索:给一个知识文档转化成多个向量存入数据库,这些向量不仅包括文档在不同大小下的分块,还可以包括该文档的摘要,用户可能提出的问题等。
多代理检索:选取部分优化策略交给一个智能代理合并使用,如子问题查询、多级索引和多向量查询结合。
Self-RAG:通过检索评分和反思评分来提高质量,主要分为检索、生成和批评三个步骤。
10. 重排模型(Re-ranking)
在完成语义搜索的优化步骤后,能够检索到语义上最相似的文档,但语义最相似并不一定代表最相关。例如,当用户查询“最新上映的科幻电影推荐”时,可能得到的结果是“科幻电影的历史演变”,虽然从语义上这与科幻电影相关,但并未直接回应用户关于最新电影的查询。
重排模型可以帮助我们缓解这个问题。重排模型通过对初始检索结果进行更深入的相关性评估和排序,确保最终展示给用户的结果更加符合其查询意图。这一过程通常由深度学习模型实现,如 Cohere 模型。这些模型会考虑更多的特征,如查询意图、词汇的多重语义、用户的历史行为和上下文信息等。
例如,对于查询“最新上映的科幻电影推荐”,在首次检索阶段,系统可能基于关键词返回包括科幻电影的历史文章、科幻小说介绍、最新电影的新闻等结果。然后,在重排阶段,模型会对这些结果进行深入分析,并将最相关、最符合用户查询意图的结果(如最新上映的科幻电影列表、评论或推荐)排在前面,同时将那些关于科幻电影历史或不太相关的内容排在后面。这样,重排模型就能有效提升检索结果的相关性和准确性,更好地满足用户的需求。
在实践中,使用 RAG 构建系统时都应考虑尝试重排方法,以评估其是否能够提高系统性能。
11. 提示词(Prompt Engineering)
大型语言模型的解码器部分通常基于给定输入来预测下一个词。这意味着设计提示词或问题的方式将直接影响模型预测下一个词的概率。通过改变提示词的形式,可以有效地影响模型对不同类型问题的接受程度和回答方式。
为了减少模型产生主观回答和幻觉的概率,一般情况下,RAG 系统中的提示词中应明确指出回答仅基于搜索结果,不要添加任何其他信息。例如,可以设置提示词如下: “你是一名智能客服。你的目标是提供准确的信息,并尽可能帮助提问者解决问题。你应保持友善,但不要过于啰嗦。请根据提供的上下文信息,在不考虑已有知识的情况下,回答相关查询。”
此外,使用少量样本(few-shot)的方法,将想要的问答例子加入提示词中,指导 LLM 如何利用检索到的知识,也是提升 LLM 生成内容质量的有效方法。这种方法不仅使模型的回答更加精准,也提高了其在特定情境下的实用性。
12. 大语言模型(LLM)
最后一步是 LLM 生成回答。LLM 是生成响应的核心组件。与嵌入模型类似,可以根据自己的需求选择 LLM,例如开放模型与专有模型、推理成本、上下文长度等。此外,可以使用一些 LLM 开发框架来搭建 RAG 系统,比如 LlamaIndex 或 LangChain。这两个框架都拥有比较好用的 debugging 工具,可以让我们定义回调函数,查看使用了哪些上下文,检查检索结果来自哪个文档等。
3、总结
构建 RAG 系统不仅需要深厚的技术功底,还需注重工程实践的细节。从提升检索精度、优化生成质量到确保系统稳定性,每一个环节都需要精心设计与打磨。借助最新的优化策略和前沿工具链(例如 Cursor、MCP 技术),可以有效攻克开发过程中的关键难题,打造出高效、稳定且灵活的 RAG 系统。
随着多模态技术的不断进步、大模型上下文理解能力的增强、动态学习机制的完善以及隐私保护技术的成熟,RAG 系统将在更多垂直领域大放异彩,成为推动下一代智能应用发展的核心技术之一。它将为用户提供更智能、更可靠的服务体验,助力各行业实现智能化转型与升级。
本文转载自公众号玄姐聊AGI 作者:玄姐
