在大模型应用中,检索增强生成(RAG)在解决知识局限性和减少生成"幻觉"方面表现突出。RAG技术结合了检索和生成的双重优势,通过从外部知识库中检索相关信息并生成回答,显著提升了模型的响应能力。
一、RAG定义与发展历史
RAG(Retrieval-Augmented Generation,检索增强生成)是一种结合检索和生成技术的方法。2020年,Facebook AI Research(FAIR)团队发表名为《Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks》的论文,首次提出了RAG概念。在大语言模型(Large Language Models)的领域中,RAG特指一种模式:模型在回答问题或生成文本时,首先从广阔的文档库中寻找相关信息。然后,模型使用这些找到的信息来生成回答或文本,从而提高其预测的准确度。
使用RAG原因:
- 信息滞后,私有数据匮乏:训练数据早且不全。
- 幻觉:底层原理是基于概率。
- 上下文限制:需要在有限上下文窗口给高价值的提示词语料。
- 数据安全:不能放到大模型上训练。
RAG三个阶段:
- 原始RAG只具备了最基础的部分:离线索引构造、在线检索以及大模型生成。
- 高级RAG则是在这3个流程里增加更多细化的工作,例如数据预处理、滑动窗口、文章切片、用户query重写等,重点在检索层面的优化。
- 而模块化RAG对RAG流程步骤和能力做模块化,供各个业务场景灵活的选择和编排。本文主要讲解高级RAG的原理及其实践应用。
二、RAG架构
如图所示,是一个RAG的基本架构,可以分为离线和在线两部分。
- 离线:对知识库文档进行解析、拆分、索引构建和入库。这部分会从用户给定的文档、图片、表格和外部URL等资源中提取内容,然后通过chunking(可以认为是将连续的文本分成一个个小块)进行合理切割,再使用Embedding模型变成向量数据存入向量数据库或Elasticsearch等载体中,同时结合这些非结构化文件所附带的元数据(时间、文件名、作者、副标题、文件类型等)进行索引创建。
- 在线:当用户输入问题之后,我们会对query进行分析,如关键词提取、意图识别等,然后再根据路由条件进行知识库的多种召回检索或者联网搜索等。如果是做向量数据库的检索,会先将查询内容通过Embedding模型转化为向量数据,接着在向量数据库中进行相似度匹配,比如从百万的数据块中找出匹配度较高的100个,然后再将这100个数据块进行更精准的重排序(如使用交叉熵校验的Rerank算法),将最相关的top k结果找到,最后将用户问题、经过技术处理的top k数据块、还有prompt一起提交给LLM,让它生成最终可靠的答案。
另外,为了进一步提高系统的稳定性,我们也会引入后置处理的环节,如风控检测、结果缓存和RAG相关指标的监控上报等。
2.1 为什么是向量数据库
有传统的MySQL、MongoDB等数据库存在的情况下,RAG采用向量数据库的原因是什么?
传统数据库,搜索功能都是通过不同的索引方式(B-Tree、倒排索引等)加上精确匹配和排序算法(BM25、TF-IDF)等实现的,本质还是基于文本的精确匹配,做关键字匹配的词法搜索。这种索引和搜索算法对于关键字的搜索功能非常合适。
但在AIGC时代,搜索的主要诉求主要是做语义搜索,捕捉用户所输入语句后面的真正意图,并以此来进行搜索,从而更准确地向用户返回最符合其需求的搜索结果。如搜索"孟字去掉子",用户想要找的并不是含有"孟"、“去掉子”,而是"皿"。
深入分析,向量数据库在处理高维数据,深度学习模型生成的向量数据方面具有特殊的优势,表现如下:
- 维度:深度学习模型生成的文本、图像或语音向量通常位于高维空间中。传统的关系型数据库并不擅长处理这类高维数据,因为它们主要是为处理结构化数据(如表格数据)而设计的。
- 速度:向量数据库专门设计用于存储高维向量,并支持快速的相似性搜索。向量数据库通过优化的索引结构和近似最近邻(ANN)搜索算法,能够高效地完成这一任务,显著提高检索速度。
- 推理:向量数据库支持基于向量相似度的复杂查询,可以根据查询的语义内容相关性而非仅仅是关键字匹配来检索信息,这使得向量数据库具有一定"推理"的能力,而非只是"查询"。
2.2 文档解析
RAG离线流程的第一步是做文档解析。文档解析不仅包括文本内容的识别,还涉及到图像、图表和表格等非文本元素的解析。很多时候,企业内部数据以各种各样的文件格式存在,如PDF、Word文档、PPT和Excel表格等,如何从大量非结构化数据中提取出内容,需要文档智能解析技术解决。下面我们以图片形式的文档(如对纸质文档进行了扫描、拍照等)为例进行说明。
首先,我们需要对文档进行版面分析(Layout Analysis,也称布局分析),用于识别和理解文档中的视觉和结构布局。这里会使用到区域检测和区域分类技术。区域检测用于识别文档中的不同区域,如文本块、图像、表格和图表等。而区域分类则将检测到的区域进一步分类,如文本可以进一步被细分为标题、副标题、正文文本等;图像可能被分类为图片、图表或公式等;表格需要识别为包含数据的结构化形式。
区域检测和分类后,需要对识别出来的具体区域分别进行识别,提取出数据内容。比如,对于表格区域,解析表格的行和列,识别单元格边界,提取结构化数据。对于文本区域,使用OCR引擎将图像中的文字转为机器可读的字符。
当前随着大语言模型(LLM)和多模态技术的发展,文档理解领域逐渐出现了端到端的多模态模型,长期来看,大模型和文档理解进行结合应该是一个趋势,但目前多模态大模型与传统取得最优效果的模型方案相比,还不具备很好的竞争力,尤其是在处理细粒度文本的场景下。
文档智能解析技术的应用非常广泛,可用于法律文档的信息提取、财务报表的数据整理、医疗记录的分析等多个领域,是搭建RAG系统不可或缺的部分。下面列举了几个用于文档解析的开源项目,有兴趣可以深入了解和使用。
- RAGFlow:基于深度文档理解构建的开源RAG引擎。最大特色是多样化的文档智能处理,其DeepDoc模块提供了对多种不同格式文档的深度解析。
- Unstructured:灵活的Python库,专门用于处理非结构化数据,可以处理各种文档格式,包括PDF、CSV和PPT等。被网易有道的QAnything、Dify等项目使用。
- PaddleOCR:百度推出的OCR开源项目,提供全面且高效的文字识别和信息提取功能。
- DeepSeek OCR
2.3 文本分块
文本分块(text chunking)或称为文本分割(text splitting),是指将长文本分解为较小的文本块,这些块会被Embedding、索引、存储,用于后续的数据检索。通过将大型文档分解成易于管理的部分(如章节、段落,甚至是句子),可以提高搜索准确性和LLM处理性能,主要体现如下:
- 提高搜索准确性:较小的文本块允许更精确的关键词匹配和语义相似性检索。
- 提升模型性能:LLM在处理过长的文本时可能会遇到性能瓶颈,通过将文本分割成较小的片段,检索出来后输入给大模型,可以使模型更有效地处理和理解每一部分,使得查询返回的信息更准确。
以下介绍一些常用的文本分块策略:
按大小分块:将文本按固定字符数或单词数进行分割,这是最直接、最经济的分块方法,但也存在明显的问题——语义不连贯。按大小分块通常不考虑文本的语义内容,因此有可能将相关联的信息切割开,导致分出的文本块在内容上缺乏连贯性和完整性。
特定格式分块:针对具有特定结构或语法特征的文本文件进行分块的一种方法,如Markdown、LaTeX、Python代码等。这种分块方式依据各自格式的特定字符或结构标记来实现,以保证分块后的内容在结构上的完整性和逻辑上的连贯性。
递归分块:以一组分隔符为参数,以递归的方式将文本分成更小的块。如果在第一次分割时无法得到所需长度的块,它将递归地继续尝试。每次递归都会尝试更细粒度的分割符号,直到块的长度满足要求。
语义分块:首先在句子之间进行分割,句子通常是一个语义单位,它包含关于一个主题的单一想法,再使用Embedding表征句子,最后将相似的句子组合在一起形成块,同时保持句子的顺序。
命题分块:也是一种语义分块,它的原理是基于LLM来逐步构建块。整体流程先从基于段落的句法分块开始,得到文本段落,接着对于每个段落,使用LLM生成独立的陈述(或者命题),比如我们可以使用简单的提示"这段文字讨论了哪些主题"。下一步再移除LLM生成的冗余重复命题,对剩下的命题做索引并存储。在查询时,从命题语料库中检索,而不是原始文档语料库。
文本分块并没有固定的最佳策略,选择哪种方式取决于具体的需求和场景,需要根据业务情况进行调整和优化。关键是找到适合当前应用的分块策略,而不是追求单一的完美方案。可以使用ChunkViz工具进行可视化,帮助调整分割参数。
2.4 数据Embedding和存储
在使用向量数据库情况下,我们需要对上面解析和分块好的数据,基于嵌入模型(Embedding Models)将文本向量化(Embedding),存储到向量数据库中。
Embedding的本质是一种将高维稀疏数据转换为计算机易于处理的低维稠密向量的技术,通过这种转换,能够捕捉数据中的语义或特征关系。具体来说,Embedding用一个多维稠密向量来表示事物的多维特征,从而在一个连续的向量空间中刻画事物之间的相似性和差异性。
Embedding模型会根据不同的算法生成高维度的向量数据,代表着数据的不同特征。例如,对于文本,这些特征可能包括词汇、语法、语义、情感、情绪、主题、上下文等。对于音频,这些特征可能包括音调、节奏、音高、音色、音量、语音、音乐等。
目前常用的Embedding模型包括:
- 文本:OpenAI的text-embedding-ada-002(1536维)
- 图像:clip-vit-base-patch32
- 音频:wav2vec2-base-960h
在实际的业务场景中,往往不需要在整个向量数据库中进行相似性搜索,而是通过部分的业务字段过滤后再进行查询,所以存储在向量数据库的向量往往还需要包含元数据,例如时间、用户ID、文档ID等信息,这样就可以在搜索的时候,根据元数据来过滤搜索结果,提高搜索结果的准确性和相关性。
2.5 用户Query理解
在线部分第一个重要的步骤是对用户的query进行理解,这一步也是RAG系统中非常关键的一步。query理解指的是对用户提出的问题进行深入分析,提取出关键信息,从而更准确地从知识库中检索出与用户查询最相关的信息,进而生成高质量的回答。query进行理解的原因:
- 用户表达的模糊性:相同的词汇在不同的上下文中可能有不同的含义,通过query理解,系统可以分析上下文,判断用户的意图,从而检索到相关的正确信息。比如,用户输入"book",可能指一本书,也可能指预订一个座位。
- query和检索文档不在同一个语义空间:检索系统需要在不同的表达方式、术语使用、上下文信息等方面建立联系。用户的query通常是非结构化的,可能使用非正式或口语化的语言进行自由表达,而文档则可能采用正式的书面表达。
- 用户的query可能比较复杂:处理复杂query时,RAG系统需要能够识别并分解用户的查询,将其拆分为更小、更具体的子问题。
在RAG系统中,常用query理解技术分为三大类:query改写、query增强和query分解。
(1)Query改写 - 上下文信息补全
在多轮对话中,用户的当前输入往往包含隐含的指代关系和省略的信息。我们可以通过使用大型语言模型(LLM),对当前的query进行重写,将上下文中隐含的信息纳入到新生成的query中。
示例:
User:最近有什么好看的电视剧?
Bot:最近上映了《庆余年 2》,与范闲再探庙堂江湖的故事
User:我想看第一季
通过采用上下文信息补全,可以把前面的对话信息也纳入其中,生成类似"我想看庆余年第一季"的完整query。
(2)Query改写 - RAG Fusion
RAG Fusion用于提升搜索精度和全面性,它的核心原理是根据用户的原始query生成多个不同角度的query,接着通过使用倒数排名融合(Reciprocal Rank Fusion,RRF)技术,将多个query的检索结果进行融合,生成统一的排名列表。工作流程如下:
- 多查询生成:通过使用LLM将原始用户查询扩展成多样化的查询,从而增加搜索的视野和深度。
- 倒数排名融合(RRF):将多个系统的排名结果进行加权综合,生成一个统一的排名列表。
- 生成性输出:将重新排名的文档和查询输入到LLM,生成答案。
(3)Query改写 - Multi Query
跟RAG Fusion类似,Multi Query是一种通过生成多种视角的查询来检索相关文档的方法。它使用LLM从用户输入的查询生成多个不同的查询视角,然后为每个查询检索一组相关文档,并去重合并这些结果以获得更全面的文档集合。跟RAG Fusion不同的是,Multi Query没有使用RRF来融合多个搜索结果列表的排名,而是将多个搜索结果放到context中。
(4)Query增强 - HyDE
RAG向量检索在度量查询(query)和文档(doc)之间的相似性时存在一个挑战:query和doc不在同一个语义空间。为了解决这个问题,一种可行的方法是HyDE(假设性文档嵌入,Hypothetical Document Embeddings)技术。这种技术基于这样一个假设:与query相比,假设性回答,即LLM直接对query生成的答案,与文档共享更相似的语义空间。
HyDE具体的工作流程:首先,HyDE针对query直接生成一个假设性文档或者回答(hypo_doc),接着对这个假设性回答进行向量化处理,最后使用向量化的假设性回答去检索相似文档。经过这么一顿操作,以前的query-doc检索就变成了query-hypo_doc-doc的检索。
HyDE的核心优势:
- 避免了在同一向量空间中学习两个嵌入函数的复杂性。
- 利用无监督学习,直接生成和利用假设文档。
- 在缺乏标注数据的情况下,仍能显著提高检索的准确性和效率。
(5)Query增强 - Step-back Prompting
Step-back prompting技术旨在提高LLM进行抽象推理的能力,它引导LLM在回答问题前进行深度思考和抽象处理,将复杂问题分解为更高层次的问题,其包含如下两个主要步骤:
- 抽象(Abstraction):首先促使LLM提出一个更高级别的"回溯问题"(step-back question),涉及更广泛的高级概念或原则,并检索与这些概念或原则相关的相关事实。
- 推理(Reasoning):在高级概念或原则的基础上,利用语言模型的内在推理能力,对原始问题进行推理解答,这种方法被称为基于抽象的推理(Abstraction-grounded Reasoning)。
Step-Back Prompting适用于需要复杂推理的领域,如:STEM领域(物理和化学等科学原理的应用问题)、知识问答(需要大量事实性知识的问题回答)、多跳推理(需要通过多个步骤或信息源进行推理的问题)。
(6)Query分解 - IR-CoT
IR-CoT(Interleaving Retrieval with Chain-of-Thought Reasoning,交错检索与思维链推理)是一种用于解决多步骤问题(Multi-Step Questions)的技术。IR-CoT通过交替执行检索(retrieval)和推理(reasoning)步骤来提高大型语言模型处理复杂问题时的表现,其核心思想是将检索步骤与推理步骤相结合,以指导检索过程并反过来使用检索结果来改进推理链(Chain-of-Thought,CoT)。
(7)Query分解 - Least-to-Most
Least-to-Most prompting也可以用于解决多步推理的问题,它将复杂问题分解为一系列更简单的子问题,并按顺序解决这些子问题。包括两个主要阶段:
- 分解(Decomposition):将复杂问题分解为更简单的子问题。
- 子问题解决(Subproblem Solving):使用之前解决的子问题的答案来帮助解决当前子问题。
2.6 路由和数据检索
理解用户query后,进入查询路由步骤,通过定义查询路由器以及各个查询数据插件,将用户查询情况传给LLM,通过LLM决策,决定接下来要调用哪个查询插件,然后调用执行路由选择的插件,最后将各个插件预定义格式返回的结果汇总。
向量数据库的核心在于相似性搜索(Similarity Search)。实际上,只要维度够多,我们就能够将所有的事物区分开来,世间万物都可以用一个多维坐标系来表示,它们都在一个高维的特征空间中对应着一个坐标点。这样就能够通过计算向量之间的距离来判断它们的相似度,这就是相似性搜索。
ANN近似最近邻搜索
最原始的方法是遍历数据集中的每一个向量vi,计算查询向量q与每个向量vi的距离,并最终获得k个真实的最近邻。这种NNS (Nearest Neighbor Search)最近邻搜索,可以找到数据集中与给定查询向量q距离最小的向量。但是,在大规模高维数据集中,由于数据集规模的增长和维度灾难,精确的最近邻搜索可能非常耗时。高效的搜索算法通过两种方式提高搜索效率:
- 减少向量大小——通过降维或减少表示向量值的长度。
- 缩小搜索范围——可以通过聚类或将向量组织成基于树形、图形结构来实现,并限制搜索范围仅在最接近的簇中进行。
实际上,除了暴力搜索能完美搜索出最相邻,所有的搜索算法只能在速度和质量还有内存上做一个权衡,因此这些算法也被称为ANN(Approximate Nearest Neighbor)近似最近邻搜索算法。现有ANN算法主要可以分为四种类型:基于树的算法 (KD-tree、R-tree);基于哈希的算法(LSH);基于量化的算法(PQ、IVF-PQ);以及基于图的算法(基础图搜索算法、HNSW)。
向量相似度算法
| 名称 | 欧几里得距离 | 余弦相似度 | 点积相似度 |
|---|---|---|---|
| 特点 | 反映向量的绝对距离,适用于需要考虑向量长度的相似性计算 | 对向量的长度不敏感,只关注向量的方向,适用于高维向量的相似性计算 | 兼顾长度和方向,简单易懂,计算速度快 |
在RAG架构主要做语义搜索场景里面,一般选择余弦相似度进行向量计算召回,主要考虑:
- 长度不敏感:在文本数据中,文档的长度可能会有很大的差异,这会影响到向量的长度。余弦相似性只关注向量的方向。
- 方向敏感:在问答系统中,我们通常关心的是文档的主题或者内容是否相似,余弦相似性可以很好地反映出文档的主题或者内容是否相似。
- 高维数据:向量Embedding模型表征的高维度(768/1024/1536…)向量,适合余弦相似性处理。
元数据过滤
在实际的业务场景中,由于往往不需要在整个向量数据库中进行相似性搜索,而是通过部分的业务字段进行过滤再进行向量查询,所以存储在数据库的向量往往还需要包含元数据。为此,向量数据库通常维护两个索引:一个是向量索引,另一个是元数据索引。过滤过程可以在向量搜索之前或之后执行:
- Pre-filtering:在向量搜索之前进行元数据过滤。虽然这可以帮助减少搜索空间,但也可能导致系统忽略与元数据筛选标准不匹配的相关结果。
- Post-filtering:在向量搜索完成后进行元数据过滤。可以确保考虑所有相关结果,在搜索完成后再将不相关的结果进行筛选。
2.7 搜索结果重排
得出搜索结果后,我们需要对搜索结果进行重排,为什么需要重排这个步骤呢?
一方面是在RAG框架中,将信息编码为向量时不可避免地会遭受信息丢失,同时近似最近邻搜索(ANN)只能提供近似匹配而非精确匹配,导致检索结果中含有一定程度的噪声。
另一方面则是提高LLM推理速度与准确率。引入重排后,能够去除上下文不相关的污染数据,提供更精准的上下文信息。重排后精准的上下文不仅可减少token的使用量,也可以提高LLM推理速度与准确率。
在实际业务场景中,我们可以增加top_k的大小,比如从原来的10个增加到30个,然后做筛选后使用更精确的算法来做rerank,常用的筛选和排序策略如下:
- 基于相似度分数进行过滤和排序
- 基于关键词进行过滤,比如限定包含或者不包含某些关键词
- 让LLM基于返回的相关文档及其相关性得分来重新排序
- 基于时间进行过滤和排序,比如只筛选最新的相关文档
- 基于时间对相似度进行加权,然后进行排序和筛选
目前rerank模型里面,较为知名的是Cohere公司的模型(收费),开源的是智源发布的bge-reranker-base和bge-reranker-large。bge-reranker-large的能力基本上接近Cohere公司的模型。
2.8 大模型生成结果
检索模块基于用户查询检索出相关的文本块,回复生成模块让LLM利用检索出的相关信息来生成对原始查询的回复,但由于可能检索出来多个文本块,有两种不同的回复生成策略:
- 策略一:依次结合每个检索出的相关文本块,每次不断修正生成的回复。有多少个独立的相关文本块,就会产生多少次的LLM调用。
- 策略二:在每次LLM调用时,尽可能多地在Prompt中填充文本块。如果一个Prompt中填充不下,则采用类似的操作构建多个Prompt。
大模型生成步骤真正发挥巨大作用的是LLM,唯一需要我们关注的就是Prompt工程。Prompt的编写技巧主要可以参考OpenAI提到的6条原则:
- Write clear instructions(写出清晰的指令)
- Provide reference text(提供参考文本)
- Split complex tasks into simpler subtasks(将复杂的任务拆分为更简单的子任务)
- Give the model time to “think”(给模型时间"思考")
- Use external tools(使用外部工具)
- Test changes systematically(系统地测试变更)
另外,《Lost in the Middle: How Language Models Use Long Contexts》文章指出,当相关信息出现在输入上下文的开头或结尾时,性能往往最高,而当模型必须在长上下文中间获取相关信息时,性能会明显下降。
2.9 后置处理
这一步主要是提高系统的稳定性,可以引入后置处理的环节,如:
- 风控检测:校验是否存在风险词、违禁词、涉黄涉政;医疗领域的开药规则,金融领域的话术约束;回复是否正确或仍存在幻觉等。
- 结果缓存:提升搜索性能。
- 监控上报:RAG相关指标的系统指标和业务指标(大模型调用性能,RAG整体执行性能,回复率,搜索召回率等)。
三、RAG的挑战与解决方案
在实际的业务场景中,RAG的落地应用会遇到各种各样的问题,需要我们去逐步迭代解决。
3.1 数据处理
当选用按字符或token数分割数据的朴素分块方法时,会出现数据分块频繁重复的问题,使得向量数据存储中出现重复向量或Embedding空间中由相同向量表示类似的单词等情况。
解决策略:
- 源数据去重:在生成Embedding之前,确保源数据没有重复,如对于文本数据,重复数据删除方法可以包括大小写规范化、词干提取、词序化以及删除标点和特殊字符等。
- 向量相似阈值:如果两个或多个向量的余弦相似度高于某个阈值,则将向量视为重复,保留一个并删除其他向量。
其他数据处理问题和解决方法:
- 文件中冲突的内容:分门别类存放数据,减少文件中相似的内容,或将其分在不同的知识库中。
- 减少具有歧义的句子:避免汉语的高级用法,如歧义句,防止相似度模型对比时搜索错误。
- 结构复杂的数据:先根据大模型以问答对的形式输出。
- 数据的有效性:存储的数据知识也需要定期维护更新。
3.2 分块策略和Top-k召回
出于实现成本和复杂度考虑,一般数据分块会采用按大小或者按特定格式分块的分块策略。微软对不同分块尺寸下数据检索召回表现的分析显示,数据块越大,数据召回率会降低。但分出的数据块越小,丢失的信息就越多,因此过小的分块可能也不太理想。当前寻找最优块大小就像参数调优一样,需要不断用自身的数据做实验来逐步调整。
重叠可以帮助将相邻的块链接在一起,并为块提供更好的上下文信息。然而,根据微软的分析,即使是非常激进的25%重叠也只能将准确率提高1.5%。这意味着重叠并不是优化RAG性能的最有效方法。
确定最佳块大小的方针:
- 清洗数据:在确定应用程序的最佳块大小之前,需要首先预处理清洗数据以确保质量。
- 选择一个范围的块大小测试:考虑内容的性质、将要使用的Embedding模型及其能力。从128或256个tokens到512或1024个tokens的范围进行测试。
- 评估每个块大小的性能:运行一系列查询来评估质量,并比较不同块大小的性能。
3.3 Embedding模型选择
Embedding在RAG系统中扮演着至关重要的角色,主要有以下作用:
- 对query和私域知识进行向量化表示:通过使用预训练的语言模型(如BERT、DPR等),将query和分块文本转换为向量。
- 动态更新知识库:新文档经过处理之后会被实时转换为向量并添加到向量数据库中。
- 数据隐私和安全:向量模型通过将私域知识转换为向量表示,实现了数据的匿名化。
以下推荐的Embedding模型:
| 模型 | 特点 |
|---|---|
| OpenAI Embedding | text-embedding-ada-002,支持8K tokens输入,需付费 |
| JinaAI Embedding | 支持8K tokens的开源模型,中文友好 |
| BAAI/bge | 智源开源,bge-m3支持100+语言和8K长度,免费商用授权 |
Hugging Face推出了MTEB(Massive Text Embedding Benchmark)测试框架,旨在评估文本Embedding模型在多种任务上的性能。可通过MTEB排行榜对比不同模型的表现。但排行榜只能作为参考,具体选择还需结合业务特点进行综合权衡。
3.4 向量数据库选型
主流的向量数据库主要分为四个类别:
| 类型 | 代表产品 | 特点 |
|---|---|---|
| 基于传统数据库改造 | PG Vector | 无缝集成现有PostgreSQL |
| 基于倒排搜索扩展 | Elasticsearch | 丰富的API和插件支持 |
| 基于向量检索库实现 | Chroma | 轻量级,运行效率高 |
| 原生分布式向量数据库 | Milvus | 从零设计,功能完整,支持分布式 |
各数据库优缺点对比:
| 数据库 | PG Vector | Elasticsearch (ES) | Qdrant | Milvus |
|---|---|---|---|---|
| 优点 | 无缝集成PostgreSQL;开源易用 | 多种数据存储方式;丰富的API和插件 | HNSW算法向量索引;查询性能出色;分布式支持 | 多种向量索引算法;查询性能出色;分布式支持 |
| 缺点 | 向量索引能力相对较弱;大规模数据性能不如专业向量数据库 | 需借助第三方插件支持向量索引;大规模下性能不如专业向量数据库 | 数据持久化能力相对较弱;集成方面有局限性 | 数据持久化需与其他存储系统结合;项目较新,集成有限制 |
3.5 检索模块的调优
值得强调的是,检索模块才是RAG模块调优空间最大的部分,而并非大模型本身,尤其是在项目前期。毕竟"查的准"是大模型最终能吐出正确结果的前提条件。以下是一些检索模块的常用调优思路:
- 构造意图识别模块:可以是分类模型、词典,甚至是知识库检索时加阈值,对知识库外的内容进行拒识,同时对知识和query进行分类对应,提升检索准确性。
- 新增字面检索:用户的输入往往是长尾效应,前期覆盖高频说法就能明显提升指标。字面检索还能做得更精细,例如配合实体抽取来做。
- 增加追问机制:通过Prompt中加入追问策略,依靠大模型能力引导用户逐步明确问题。
- query拓展:借助上下文、同义词、大模型拓展、相似度召回等方式。
- 多路召回和精排:字面、向量召回都做,甚至向量召回用多个不同策略,然后用规则或模型做精排。
- Embedding模型调优:早期用预训练模型即可,后期结合业务数据进一步调优。
- 多层索引:在大型数据库情况下,创建两个索引(摘要+文档块),分两步搜索。
3.6 幻觉检测
让机器识别幻觉内容极具挑战性。目前主要方法包括:
- 交叉验证:使用三个不同的大模型对同一个问题进行回答,然后用Embedding模型进行相似度计算。如果结果间相似度非常高(超过阈值),那么通过。如果出现分歧,记录log推给人检查。
- 验证链(Chain-of-Verification,CoVe):通过系统地验证和完善回答以尽量减少不准确性。大型语言模型生成的响应可以用来验证自身。
- 引用或归因生成:在RAG的知识问答场景下,让模型生成的内容能够与参考信息对齐,提供证据来源。具体方法包括模型生成引用和动态计算引用。
四、RAG适用场景
在大语言模型的应用过程中,有Prompt Engineering、RAG、微调三种应用方案,目前考虑业务效果,主要以RAG、微调两种技术方案为主。
| 特征比较 | RAG | 微调(Fine-tuning) |
|---|---|---|
| 知识更新 | 直接更新检索知识库,确保信息持续更新,适合动态变化的数据 | 存储静态数据,需要重新训练用于更新 |
| 外部知识 | 擅长利用外部资源,适合处理文档或数据库 | 适合将外部知识与大语言模型对齐 |
| 数据处理 | 对数据的处理和操作要求极低 | 依赖于构建高质量的数据集 |
| 模型定制 | 侧重于信息检索和融合外部知识 | 允许根据特定风格或术语调整模型行为 |
| 可解释性 | 答案能追溯到具体数据来源,可解释性高 | 黑盒子,可解释性相对较低 |
| 计算资源 | 需要支持检索策略和数据库的资源 | 需要准备训练数据集和计算资源 |
| 延迟要求 | 因涉及数据检索,可能带来较高延迟 | 可以不通过检索直接回应,降低延迟 |
| 降低幻觉 | 每个回答基于检索到的实际证据,更不容易产生幻觉 | 面对未训练过的输入时仍可能出现幻觉 |
五、RAG的评估
“如果你不衡量,你就无法改进”。构建了基本的RAG应用程序后,需要创建一个评估过程。
5.1 评测指标
论文《RAGAS: Automated Evaluation of Retrieval Augmented Generation》把RAG系统的评估指标拆分为三个维度:
- 事实准确度(Faithfulness):评测生成的回答是否忠实于contexts,对避免幻觉并确保检索到的上下文可以作为生成答案的理由非常重要。
- 答案关联性(Answer Relevance):生成的答案应解决所提供的实际问题。
- 上下文相关性(Context Relevance):检索的上下文应重点突出,尽可能少地包含无关信息。
5.2 评测方法
- RAGAS:一个开源的RAG评估框架,基于gpt-3.5-turbo-16k模型全自动衡量答案的准确性、相关性和上下文相关性。
- LlamaIndex Evaluating:提供了衡量生成结果质量和检索质量的关键模块。
总结
RAG技术通过结合检索和生成的双重优势,显著提升了大模型的响应质量。从离线文档解析、文本分块、向量化存储,到在线Query理解、路由检索、结果重排和回复生成,整个RAG pipeline的每个环节都有丰富的优化空间。结合具体的业务场景,灵活选择和编排各RAG模块的能力,才能发挥出RAG技术的最大价值。