通俗易懂的RAG,RAG到底做了什么?
提示是在教我们如何更好的跟大语言模型进行对话。那参数高效微调方法像lora方法是为了得到一个更好的大模型。那么今天我们来学习RAG技术。RAG是如何让大模型回答的更好(how to make LLMs answer better)。RAG实际解决的问题是解决了大模型的知识局限性缓解了幻觉问题。一定程度上也保证了数据的安全性。它利用额外的知识库解决了知识性的局限只要你的知识库足够丰富就可以跟进上实时性的非公开的离线数据。对于幻觉问题无法完全解决但是可以有一定程度的缓解。对于数据安全角度大模型本身有可能会造成数据信息的泄露。但它大多数泄露的是它在预训练过程中的一些数据。因此我们把知识库和大模型看成相互独立的两个部分知识库只是每次抽取相应的知识其实对于大模型来讲它不会有那么明显的一个数据泄露的问题这也是使用RAG的一个好处。RAG流程分为数据准备数据检索两个部分。数据准备阶段数据的爬取对爬取的数据进行处理切分和向量化。数据检索也叫应用阶段用户给了一个问题进入我们的数据库利用某种方法调用数据库中的某些和用户问题相关的数据把这个数据拿出来。这个数据和问题会一起以提示的形式最终输入到大语言模型中然后让大语言模型生成最后的答案。向量化我们肯定还是要判断它对应的一些其他特征方面的一些相关性。然后我们再把这些句子提取出来。所以这一步叫做向量化向量化一个比较常见的方法我们知道大语言模型它都是一个一层一层的模型它每一层输入到下一层它都是一个768乘以768位的向量那么我们把最后一层最终得到的向量一般我们讲是一个得到深层语义的一个向量还是一个768乘以768位的。我们把这个称为这个句子的向量化。下面是可以调用的模型输入端是句子输出端是向量。爬取的数据没那么大可以保存在python大的话可以放在数据库里。下图在应用阶段最关键的就是数据检索和注入prompt这两个部分。针对数据检索采用相似性检索即可。比如说你有20万条数据我们先用全文检索的方式把问题中的关键字和你知识中的关键字提取出来这个关键字提取是非常快的。然后20万数据我们提取到了前100条。然后这100条再进行与弦相似度的计算。我们提取前十条。相当于第一个很大的知识库通过先全文检索把它压缩到一个小范围我们再进行精检索。提示注入。我们其实注入一般干什么。假如你是一个专业的积极客人请根据什么背景知识回复。然后我们把检索出来的背景知识直接给你再把问题写上去。然后让他回答就行了。如下图所示。所以RAG学完之后你会发现数据提取是爬虫的事情。文本分割是token的事情。向量化其实是大语言模型的事情它变成特征向量。那数据入库是内存的事情用户提问不用我们管。注入提示我们之前章节很详细的介绍了提示。答案生成这是大模型本身。我们之前也讲了如何得到更好大模型通过微调大模型。所以RAG其实本质在干一个事就是数据检索。RAG的本质它就是在玩这一块。怎么检索更精确三种比较常见你可以直接上手的也是偏策略的东西。第一种反复检索。比如说用户给个问题我们先检索之后先让模型再回答一个问他回答可能没有那么好。我们再把回答放进去再检索新的知识再让他进行重新生成再检索再回答然后直到大概做个三到五轮。然后我们觉得ok我们检索知识可能比较合适了然后我们再去得到这个response就是最终的给用户的一个回复。这是第一种策略也可以叫做N轮检索策略。第二种策略用户给一个问题模型会先把这个问题分解成几个小问题。分解这几个小问题之后先分别针对几个小问题先做知识的检索。把这几个小问题全部回答完之后我把所有的知识、所有的小问题的回答和所有的小问题一起交给大模型得到最终的结果。但其实这是个比较强的假设。实话讲语义相似就一定能更有益于解决问题吗不一定吧如果一个复杂的问题它是不是要根据很多步的一个推理的不一定你语义跟我完全一致。我就能回答你这个问题。我跟你这个问题的语义相关不一定我就能解决你的问题。因此我们把问题大问题分解成几个小问题它包含的一些回答和都是比较直接的。通过小问题去检索知识它可能会更加精准。然后就是第三种策略也就是把前面两种策略结合起来。既然有多轮的检索生成又有小问题的分解这两点显然是可以结合起来的。我们可以一边让模型进行多轮检索一边让它对问题进行多个小问题的分解。你从这张图也可以看出来在多轮的时候我们要设计一个轮数。首先我们可以设定一个总的轮数上限比如最多进行五轮同时每一轮中也可以把当前的问题分解成多个小问题。这样一来整个流程就变成了一个多轮、多分支的检索与生成过程。在这个流程中我们会多了一个 judge 判断的东西也就是一个评判器。这个 judge 的作用是什么呢它用来自主判断我是否还要继续进行多轮检索以及是否还需要对问题进行进一步的分解。换句话说整个流程是一个完全自动化的东西听起来很厉害但实现起来其实并不复杂。我们直接去问大模型就可以了。比如我们可以问它你觉得我还要再进行下一轮的检索吗或者你觉得现有的材料足够解决当下的问题吗如果它回答“是”那就直接生成最终答案如果它回答“不是”那就继续检索新的知识再对问题进行分解。每次进入一个循环的时候我们还会再问一下大模型你觉得这个问题分得足够细了吗如果还不够细就继续分解如果已经足够细了就进入下一轮检索。不过这里有一个需要特别注意的问题当有更多的模型参与、有更多的轮次时就势必会带来一个代价。你的时间会越来越长。我们刚刚说过你检索一次可能就要面对上万条数据需要先做全文检索再做相似性检索来计算相似度。这还只是一轮的情况。何况现在要做 N 轮检索还要把问题分解成 N 个小问题每个小问题再分别进行 N 轮检索那复杂度就是 N 乘以 N会非常高。所以这种组合策略虽然效果可能更好但计算成本和时间开销也会显著增加。具体要不要采用这种策略以及轮数和问题分解的粒度怎么设置都需要根据你实际项目的需求、数据规模和时间预算来权衡决定。
