背景介绍
ChatGPT的横空出世,让人们对问答机器人重新燃起了信心。有了大模型的加持,ChatGPT甚至成功通过了谷歌的编程面试。普通人如今可以借助ChatGPT完成日常问答、翻译、文本生成、文本分类等各类任务。但是,如果直接拿它来回答专业领域的问题,效果可能就不那么理想了。具体问题出在哪儿呢?
其一,大模型依赖其内在知识,但那些知识可能已经过时,或者来自非权威渠道,甚至还经常产生大量的“幻觉”。
其二,如果尝试对大模型进行微调,由于其参数量巨大,微调成本高得吓人,而且很容易出现过拟合的问题。
而检索增强生成(Retrieval Augmented Generation,RAG)通过将检索技术和大模型结合起来,很好地绕开了这些难题,目前已经成为处理领域知识问答最受青睐的方案。
RAG简介
RAG能从权威的、预先确定的知识库中检索出相关的上下文片段,然后把问题和检索结果一起喂给大模型,让大模型基于这些特定的输入来生成最终答案。这样一来,既保证了来源的可靠性,避免了大模型信马由缰地自由发挥,也省去了微调大模型所需的高昂成本。

常见的RAG工作流程如上图所示,可以拆解成三个步骤,正好对应RAG这个名称里的三个单词:
检索(Retrieval):根据用户的问题,从已知的知识库里检索出相关的上下文信息。具体来说,是把用户的问题通过Embedding模型转化成向量,然后和向量数据库里的内容做比对,通过相似性搜索,找出最匹配的Top K个结果。
增强(Augmented):把用户问题和检索结果一起,塞进一个Prompt模板里,为下一步大模型的生成做好准备。
生成(Generation):把增强后的Prompt交给大模型,生成最终的回答。
从工程的角度看,RAG又可以分为离线和在线两个阶段:
数据准备阶段(离线):导入各种格式的领域知识文件,经过文本分割和向量化,存到向量数据库里。主要步骤包括:数据提取、文本分割、向量化、数据入库等。
应用阶段(在线):主要包括数据检索和大模型生成,也就是前面提到的检索、增强、生成这套完整的工作流程。
面临挑战
不过,RAG方案是一个面向领域知识问答的整体架构,落地的时候还是会遇到不少挑战。毕竟,领域知识问答对回答的准确性和完整性要求非常高。
如果RAG的回答效果不好,大部分原因可能是在知识库中没有找到正确的上下文,这跟数据准备和数据检索都脱不了干系。拿到检索结果之后,Prompt的质量和大模型的能力又会直接影响最终的输出。下面我们看看每个阶段具体有哪些关键挑战。
数据准备
数据准备通常是离线进行的,主要包括以下几个环节:
数据提取:解析不同格式的领域知识文件,比如Word、PDF、Markdown、HTML等,把它们处理成统一的格式,同时做一些必要的过滤、压缩、格式化等数据处理工作,有时甚至需要记录一些元数据信息,作为后续检索时的参考。
文本分割:文本分割既要考虑Embedding模型的Tokens限制,也要顾及语义的完整性。常见的方法有按段落或句子切分、固定长度切分等。
向量化:向量化是把切分好的文本转化成向量的过程,需要使用Embedding模型。可以直接选用开源的常用模型,比如BGE、M3E等,也可以基于领域知识微调后再用。
数据入库:数据向量化后建立索引,存入向量数据库。常见的向量数据库有Faiss、Chroma、ElasticSearch、LanceDB等。
这个阶段的主要挑战在于:
挑战1. 文本分割不合理,导致召回的内容不准确或不完整。
切分后的文档块会直接影响检索时和用户问题的匹配程度。块太小可能回答不了某些问题,块太大又可能导致答案里塞进一些不必要的信息。
目前的切分方式有很多,但哪种才是最适合本领域文档的,还得看文件格式、写作习惯、表达方式等因素。需要结合不同情况灵活选择最佳方案,甚至可能要对不同类型的内容做一些特殊处理。最关键的一点,还是要根据语义来进行合理的切分。
数据检索
常见的数据检索方法包括向量检索和关键词检索等。
向量检索:也叫相似性检索,它计算用户问题转化后的向量和向量数据库中存储的向量之间的相似度。常见的相似度计算方法有余弦相似度、曼哈顿距离(L1)和欧式距离(L2)等。
关键词检索:主要通过关键词构建倒排索引,在全文中找到关键词的位置和出现频次等。
由于各种检索方法的效果不同,一般建议采用多种检索方法混合的方式,来提升召回率。多种检索方式找出来的相关知识片段可能不一样,这时还需要通过Rerank模型做一个整体的排序,帮助大模型得到更好的输出。
这个阶段的主要挑战在于:
挑战2. 向量检索作为主流检索方式,主要基于相似度判断,但可能因为各种原因出现偏差。
语义歧义:向量表示可能捕捉不到概念之间的细微差别,导致术语混淆。
大小与方向:余弦相似度是一种常见的度量方式,它重点关注向量的方向而不是大小。这可能导致语义上相差很远、但方向上却很相似的匹配结果。
粒度不匹配:用户问题的向量可能代表某个特定概念,但如果知识库只包含更广泛的主题,检索结果就可能比预期宽泛很多。
全局相似性与局部相似性:大多数向量搜索机制识别的是全局相似性,但可能漏掉了那些在局部或上下文上更相似的内容。
稀疏检索挑战:当所需信息稀疏地分散在多个文档中时,检索机制可能很难在庞大的知识库里准确找到正确的段落。
挑战3. 多个检索结果的排名和优先级不合适,导致大模型的回答抓不住重点。
判断多个检索到的段落对于生成任务的重要性和相关性,本身就不容易。增强过程需要恰当地权衡每个段落的价值,这意味着在排序阶段,可能也需要具备一定的领域认知能力。
大模型生成
在RAG中,Prompt需要包含用户问题、检索结果和任务描述。一般会这样设定:“你是什么领域的专家,你需要基于这些检索结果,来回答这个用户问题。”
在大模型的选择上,需要综合考虑领域知识的语言、大模型对领域知识的理解水平等因素,确保能够获得较好的结果输出。
这个阶段的主要挑战在于:
挑战4. 如何优化Prompt,让大模型基于现有知识和提示信息,生成更优的回答。
Prompt不只是简单地把问题和检索结果拼在一起。针对不同的生成模型,需要有不同的表达方式和补充限定。为了防止大模型过度发挥,可能需要给它设定一个固定的“人设”,并对各种可能的情况做好限定。比如,“你是这个领域的专家”、“你只能基于提供的问题和相关结果做概括和总结”,等等。
挑战5. 大模型如何保证回答的连贯性和一致性。
因为提供的知识片段可能来自不同的文档,也可能来自用户问题中不同关键词找到的内容,大模型需要把这些信息整合起来,确保生成的输出在逻辑上连贯且一致。
挑战6. 大模型如何更好地理解领域知识片段。
不同的大模型对领域知识和术语的理解程度也不一样,这会导致对检索结果的理解和输出存在差异。可以通过适当的微调来提升大模型在特定领域的语言理解和生成能力。
语料准备
RAG各个环节的调优以及RAG的评估,都离不开领域知识的语料——也就是QA对。主要包括以下几种:
用于Embedding模型微调的QA对:包含领域知识问题、正向回答和负向回答,目的是提升用户问题与向量数据库的相似度匹配能力。
用于Rerank模型微调的QA对:包含领域知识问题和回答,目的是提升多个检索结果的排序能力。
用于大模型微调的QA对:包含领域知识问题和回答,目的是提升对Prompt内容的理解和总结能力。
用于评估RAG质量的QA对:包含领域知识问题和回答,目的是为RAG质量评估提供依据。
这个阶段的主要挑战在于:
挑战7. 如何提供高质量的QA对,辅助RAG的调优。
一般的调优都要求尽可能多地提供QA对。但如果全靠人工来创造,工作量会非常巨大;交给机器去生成,又觉得不太靠谱。所以,如何提供高质量的QA对,是影响RAG最终效果的一个重要因素。
意图识别
大模型经常会编造一些内容,而且光靠Prompt提示大模型,有时也不一定管用。这时候就需要在进入RAG流程之前先做好意图识别,基于不同的场景进行分流,避免大模型自由发挥。
比如,判定为闲聊场景时,就不走知识召回流程,用一个闲聊的Prompt传递给大模型来回答;判定为该领域的内容时,再进入领域知识问答流程;判定为特定问题时,直接给出模板化的回答。
这个阶段的主要挑战在于:
挑战8. 什么情况下拒绝回答是合适的?
当用户提出一个仅凭现有文档无法回答的问题时,需要及时拒绝,避免给出不合适的答案误导用户。一般情况下会设定一个相似度阈值,或者依据已有的场景语料来判断,但这样做也无法保证完全准确。拒绝得太多,显得“高冷”;回答得太多,又显得“不可信”。如何平衡,是个难题。
多模态RAG
知识库里除了文字,表格、图片、样例代码、样式、参考文档链接等多模态信息也必不可少。这些信息对人来说更友好、更容易理解,但对机器来说却不太友好。所以,从数据准备到数据检索,再到大模型生成,每个步骤都需要处理好这些多模态内容,否则就会丢失这部分信息,进而影响回答结果的呈现。
这个阶段的主要挑战在于:
挑战9. 多模态的支持已经是箭在弦上,不得不发了。
在多模态RAG的研究中,针对图像、代码、结构化知识、音频和视频等不同模态,都有各自不同的检索和合成程序、目标任务和挑战。比如,通过图像检索来扩展文本生成的上下文,或者利用样例代码和相关文档来增强代码生成的能力。
RAG评价
RAG生成的结果好不好,需要有一套科学的评价体系来说话。
提到评价,大家一般都会用到各种指标。比如RAGAs(Retrieval-Augmented Generation Assessment)框架,它就提供了一系列评估指标,包括上下文精度(Context Precision)、上下文召回(Context Recall)、忠诚度(Faithfulness)和答案相关性(Answer Relevancy)等。
这些指标共同构成了RAGAs评分,用来全面评估RAG的能力。它通过计算RAG中的question(用户问题)、contexts(RAG检索到的文档块)、answer(大模型的回答)和ground_truth(问题的标准答案)之间的一致性程度,来判断当前RAG在特定领域的知识能力。其中,question和ground_truth需要人工提供,而contexts和answer来源于RAG系统本身。
这个阶段的主要挑战在于:
挑战10. 如何评价RAG在该领域是否已经达到了可用的程度?
像RAGAs这样的评分方式,需要单独提供question和ground_truth。因此,question的设计和ground_truth的质量,就直接决定了评估结果的可靠性。
同时,因为评价过程本身还需要依赖大模型和Embedding模型,所以这些模型的可靠性,以及传递给模型的Prompt的准确性,也都有了更高的要求。否则,计算出来的指标也是不可信的。
总结和期望
RAG作为一个热门方向,目前仍在不断优化和迭代。它给领域知识问答带来了新的希望,但要真正满足领域用户的问答需求,还需要大量的实践积累。期待有朝一日,RAG能像各领域的专家一样,不仅完全理解领域内的所有知识库内容,还能持续学习新知识,不断自我提升,成为一个值得信赖的专业领域机器人。到那时,用户就再也不用为“找不到知识”而头疼了。
