公司动态
【AI大模型】“无”中生有:基于知识增强的RAG优化实践
RAG背景检索增强生成Retrieval-augmented Generation简称RAG是一种利用预先检索知识库来增强大模型生成能力的方案简单来讲对于大模型在业务上的落地来说我们用的大模型一般都是较好的开源通用大模型但通用大模型只有通用的归纳总结能力并没有对领域问题回答的能力。因此实际落地时如何让大模型能领域化回答问题有两种方案一种是用领域化数据再去训练和微调另一种则是外接领域化知识库对用户提问先检索知识库再由大模型生成回答。我们是做内部的平台答疑助手在我们的场景下平台的变动是频繁的对知识库的更新编辑是非常多的因此去训练和实时更新大模型的成本很高所以很自然地开始了基于RAG的这一套技术方案。这个技术思路确实很直白也很简单三两句即使没有接触过大模型算法的同学也能对RAG这个技术的概念有一个认知检索文档给大模型生成答案且落地成本很低无论是通过开源框架还是利用内部的RAG、AGENT平台都能快速上手搭建一套属于自己的知识库问答能力但这些能力在实际落地效果差异性很大。五月去北京参加AI Con大会会上听了很多RAG在领域里的实践一位同行的师兄的感想里写了这么一句话也是我做RAG过程中逐渐对它的认知“简单做做很简单复杂做做很复杂”。在实践中也发现很多比较先进的技术研究的也是大模型生成的部分落地上很多做法对于知识构建这一块更是“简单做做”居多。所以这篇文章也是想先从“简单做做”分析目前的RAG中的知识难题再从为解决这类知识难题我们所做的一些探索的思路。“简单做做很简单”的RAG知识难题分析RAG的“简单做做”在于无论是用开源的框架还是一些中心化RAG平台所提供的能力我们其实可以很容易就搭建属于自己的一套RAG问答能力这套RAG能力往往是完整的涵盖【query改写】、【向量嵌入】、【多路检索】、【大模型总结】多个模块这种能力从0-60分的搭建是快速高效的大模型能从大量知识库中找到一些相关知识并做出一些像样的回答找不到相关知识时候也能作出看似合理的回答。但随着将该类模型不止用于简单闲聊的场景而是在实际需要解放人力的场景下落地的时候这样的能力给用户的实感是空有智能外壳实际能力并不如传统检索。上图也是一篇比较全的RAG综述[1]里对RAG发展的框架概述我们今天想聊的知识增强在这张RAG技术框架图里也只是不显眼的【Documents-Indexing】简单做做的【文档分割-存储】也是实现上最简单的一个步骤。但简单做做后的效果往往不如人意以下两个问题也是我们在实践过程中的思考从知识角度分析为什么简单做的RAG看上去会有人工智障感人工智障感主要是源于大模型并没有理解灌入模型的知识大模型去总结很多文档时缺乏一些领域内常识又在杂乱的文档中进行生成会有较多幻觉。一个没有常识的人看了点看似相关可能无关的只言片语也很难不胡说八道因此核心问题在于【大模型悟性不高且知识质量低】解决方案也是两类并行提高大模型的悟性【Prompt工程里尽可能详细引导/参考微软RAFT方法(2)微调/许愿开源大模型越来越牛…】另一类即是从源头上提高外接给大模型的知识质量即是我们这篇文章聊的重点。接下来进入正题灌入大模型的知识质量上存在哪些需要解决的难题从知识角度思考灌入大模型的知识质量上存在哪些需要解决的难题这个问题最直接的回答是本身业务侧提供的知识库不够/质量不行实际上这个原因也确实有影响但在实践后也可以发现一些算法上的设计同样影响大模型的知识质量。1. 知识分块矛盾一般来说RAG的第一步就是先对文档进行分块简单做做的第一步就是先按默认的大小对文档进行分块overlap设个小点的值以防句子被截断。但这里在实践中容易出问题的点在于RAG中检索和生成所要求的粒度不同要想检索器检索的精准需要小分块要想大模型生成时候参考得多需要大分块同时即使有overlap但文档语义很可能恰恰在分块处隔断。如下图所示本身包含的一致性语义信息更多的章节很可能会被分在不同chunk中。因此只通过默认大小一致的分块策略及检索生成用同样的分块策略都对RAG的性能损失极大。2. 知识本身缺失假设分块问题能解决另一个知识质量上更难的点在于知识不存在于任何一个分块里其一答案可能存在在文档中但不存在确切的某一分块中。从query到document本身的语义鸿沟来说用户的问题可大可小和沉淀的文档的语义维度不可能始终一致其二一些先验的领域型知识并不在确切的分块里但大模型没有该类领域性常识时在回答具体问题时较为困难其三一些过往问答里出现过的知识仅能依靠业务侧人工整理才能进入知识库。3. 知识相互冲突假设知识全都call出来但call出来的知识本身不清晰或者是不同的文档中对相似问题的诠释不同模棱两可的知识容易让大模型想不通以至于幻觉。总结归纳到以上三点的时候也慢慢清晰了为什么明明知识管理在RAG中重要性极高但调研时较少算法研究集中这块。因为理想化情况下知识本身是ok的我们才会让大模型去外接知识同时对于人员投入较多的场景来说由有经验的同学去保证知识的正确是最优解。但在我们的场景下往往是业务难以投入太多人力配合知识补充内部知识库更新也并不会有严谨性保证因此结构化较好的语雀文档对我们来说已经是最佳知识库源。如何利用智能化算法来让这些文档发挥它最大的作用也是我们在优化中最主要的方向。“复杂做做很复杂”的RAG知识优化实践对应于前一章节所带出的三类知识质量上的问题【知识分块矛盾】【知识本身缺失】和【知识相互冲突】这一章节将会以思路为主介绍下对这三类难题的优化实践。一、从【知识分块矛盾】出发的知识检索优化1. 知识分块优化一开始做知识分块优化完全源于我们所用的数据基本上都是内部平台的语雀文档数据内部平台的文档一般都是很规范语雀文档的markdown属性也是天然包含了很多信息能把这类结构化的markdown文档里的标题信息用上一定是能比纯文本长度分割提升明显很多。但即使是开源里知名度最高的索引框架LlamaIndex对于Markdown文本的分割都是十分诡异的思路相对来说比较新的中心化的框架确实难以集成符合特定场景需求的算法。到这里我们就放弃了直接用开源类的想法直接按结构分割可能会造成大的chunk过大、小的chunk过小直接按长度分割则会造成结构信息丢失。因此在该部分我们结合了结构分割和长度分割两种实现了“先结构化分割-对大chunk再长度分割-对小chunk进行结构化合并”的三步分割逻辑对每个文档进行结构-长度均衡的块分割。具体步骤如下step1: 递归分割文档得到最小标题单元的Chunk保留了各级标题信息。step2: 对最小标题单元的chunk进行判断若chunk长度较长按长度进行二次分割获取包含标题信息的最小单元Segments。step3: 对Segments进行判断从最低级标题到高级标题开始依次判断并在长度范围内合并获取包含了segment周围尽可能多语义信息的Blocks【这一步在实际实现时使用的是归并算法的思想按标题从低级到高级依次归并】。我们实现的算法所构建的知识Blocks既包含各级标题信息对大chunk有分割对小chunk合并又是基于结构的归并尽可能多地包含了附近的上下文信息。因此给大模型的知识块尽可能实现了语义和长度的平衡。2. 检索-生成的块粒度解耦由于检索中文档块越小、检索越精准而大模型生成阶段则是文档块越大、生成越全面原有的检索文档块-大模型生成的思路会造成检索和生成两阶段的效果削弱。因此在对文档进行三步分割过程中我们分割的不同粒度的知识在最终检索过程中均是有用的。Sentence对chunk进行句子分割得到会再拼接标题等结构化信息细粒度的知识适用于检索阶段。Segment见上一节其包含了结构化段落信息完整的语义知识适用于重排阶段。Block见上一节其包含了Segment周围尽可能多的语义信息更多的上下文信息适用于大模型生成阶段。我们对检索生成两阶段的文档的块粒度进行了解耦实现了“先句子粒度检索-分割段粒度重排-结构化块生成”的从小到大索引。二、从【知识本身缺失】出发的知识增强扩充知识本身缺失很自然的思路就是对知识库做增强扩充扩充知识库在靠人力补齐外我们探索了几类借助模型去从多个维度扩充的方法扩充知识粒度解决Q-D不匹配的问题扩充领域知识来补充大模型的先验知识缺陷扩充知识来源丰富本身知识库。1. 知识粒度扩充-通用性知识增强针对由于语义粒度上Query-Document匹配困难的问题现有的解决思路做的尝试都是把让Q-D进行对齐要不把query也扩充到document粒度要不把document精炼到query粒度。将query扩充到document粒度这类方案参考HyDE[2]当query进来后预先去生成可能的答案再由可能的答案去检索相关document。这类方案的动机也很明确在很多RAG的落地实践中看起来也可行但由于对query的答案预先生成需要本身的大模型在线服务资源翻倍、等待时间上也大加长在我们的场景中并没有去尝试。将document精炼到query粒度该类方案的思路基本上是借助大模型做文档预先提取文档摘要做跨文档的预先关联。方案很多很明确结合场景里的具体问题分析我们所需要的粒度扩充再利用大模型辅助即可较快实现离线的一系列抽取。我们通过知识增强下表中的检索块指检索时用query所匹配的块内容生成块指匹配到检索块后给大模型进行生成的块内容。问题类型扩充粒度检索块生成块细粒度query从文档中预先抽取用户可能问的3-5个核心问题用户可能问的核心问题对应文本块粗粒度query对段落/文档粒度进行摘要后存入索引段落/文档粒度的摘要对应段落/文档注意长度分割以上无论是细粒度query还是粗粒度query都还是停留在单文档的多粒度知识扩充上跨文档场景下的query仍然无法得到解决。解决跨文档的query问题本质上还是解决文档间的关联问题提到关联很自然的也就来到了Graph这项技术。因此我们尝试了微软的GraphRAG[3]思路来解决跨文档的关联问题。线下跑的代码确实是有效的不过GraphRAG的检索目前用在线上的成本很高【更新索引所需资源多在线Graph存储链路有待我们探索】所以也不符合我们的低成本优化方案。但探索到了有用的技术哪能轻言放弃虽然GraphRAG全链路尚未在我们的场景的在线链路里落地但思路用在了下一节先验知识扩充里。2. 先验知识扩充-领域型知识抽取这一节想要解决的知识缺失问题也是领域化智能问答里一个老生常谈的话题许多模型预先并不知道一些领域内的先验知识单凭检索出来的相关内容进行回答总会有效果不好的问题。因此也有许多领域化的探索想方设法将领域化知识传入大模型中。这类探索也大致可以归纳成以下两类。将领域型知识内化进大模型将领域型知识内化进大模型也就是让大模型在回答前就已经学习了相关的领域类知识最常用的就是领域化数据微调方案。一开始都会去尝试微调但我们前期的微调效果不佳后续没有再走这条路的原因有几个数据收集对我们来说难度高需要有业务的同学帮忙去整理一些领域高质量数据同时领域化数据也需要配比一些通用型数据进行微调数据质量也很影响最终的不同研发平台的领域化概念可能不同为每个平台都定制领域化微调模型并部署这个资源上是完全不可行的RAG做到后面其实生成部分用的开源大模型的更迭是很快的我们不太可能及时去训新开源的模型换更新的大模型的收益又比用微调后的原有模型增益高。这个问题也是我们后续一个可能的方向如果后续能有一些知识编辑的策略可以低成本地将我们内部的所有的研发文档输入到模型的某个记忆单元在模型层面也就相当于做了增量的预训练。但短期内在落地上更有效的方案还是将领域型知识显示地灌入大模型。将领域型知识显式给大模型实际落地上我们暂时没法让模型长期记忆里存储领域型知识于是选择的方案是对query进行知识检索的同时也去检索一遍相关领域专有知识类似于MemoRAG[4]的机制去建立我们的领域Memo Model。这套方案的核心也是在于领域的Memo Model如何构建。如果有专心看到这里的朋友可能会想起来上一节有个实用但还没用起来的技术是GraphRAG[5]。在这里我们构建了基于领域图谱的MemoRAG。由于我们在构建领域图谱的时候大模型遍历了整个知识库它能获取的领域关联在一次次遍历和总结时候的可用率是非常高的。构建领域图谱的具体步骤如下step1: 模型会先多次读取文档分块从中提取出领域实体可结合不同场景规定实体类型。step2: 在遍历完所有文档分块后模型会再多次遍历提取出的领域实体将其中的相似相关实体进行合并再总结。step3: 对合并后的实体模型再根据文本块去提取实体之间的关联。step4: 对抽取的实体和关联做社区发现并对所聚集的社区做报告摘要因此在一整个链路后模型能够获取跨文档完整的领域实体相关知识。对每个实体模型也会做社区发现生成社区报告。这类实体和社区报告在这里完全可以作为Memo Model的重要组成。query进来后我们首先对query分词去我们的领域Memo Model中检索属于该租户的相关领域线索并后续一并给模型显式地将领域知识灌入模型。3. 知识来源扩充-经验性知识沉淀这一节比起前两节对知识扩充的思路会更直给。说白了就是知识库里内容不够的话我们多从其他相关知识源来挖点内容。不过每个场景下可用知识源都不会太相同为什么还是把这一节放上来了主要还是在于智能答疑的场景下一般都是先有人工答疑再有用智能问答替代人工答疑这个过程。所以人工答疑的数据往往是语雀知识库外、甚至是超越语雀知识库的最有用的知识源。但历史人工会话如何用在RAG也是一个比较难的命题信息挖掘存在几个难点其一为数据源较杂乱不同于标准化的书面文本其中掺杂了较多口语化内容且格式不一其挖掘难度大其二为关键信息关联性低往往用户的问题是通过多轮交互后才能得到解决方案解决方案较为分散其三为信息准确度要求高若挖掘出来的信息准确率较低在后续的检索中会削弱模型性能降低智能问答效率。在历史会话的挖掘上我们也在调研后考虑了两个方案。历史会话总结与摘要初期调研时针对大部分历史会话的探索基本上还是微调大模型对会话进行总结和摘要的能力。但在我们的场景下一些研发平台的人工答疑链路会很长直接利用整个总结数据灌入知识库又回到了Query-Document匹配难的问题。这里要解决也可以再进行细粒度query抽取从总结里再生成问题和对应答案。但整体方案这样看起来会有个误差累积的风险所以我们在构思是不是也可以直接微调一版能够从历史会话中直接抽取有效问答对的模型。历史会话问答对挖掘如上述思路我们将方案转变到历史会话的问答对直接挖掘。下图为利用会话问答对大模型对历史工单进行问答对抽取的推理流程。第一个核心模块是会话问答对大模型这里我们利用了多尺度的问答对提取策略。针对会话问题中多轮回答的复杂性单步提示难以让模型同时感知到全局和局部的知识。我们设计了一种分步提示Multi-Step Prompting策略该生成策略用于训练数据准备、训练任务构造及大模型推理三个部分。本策略将针对历史会话的问答对抽取分解为两层子任务分别构建不同的提示词prompt包括全局层和局部层。全局问答对抽取由于往往一个历史会话工单中用户有最初进入提问的主要问题而该类主要问题的解决方案往往横跨了整个对话。因此在全局层首先要求大模型熟悉会话全文并理解全文判断会话中客服是否解决了用户所提出的主要问题若解决了则输出全局的问答对。局部问答对抽取考虑到内部研发问题的复杂度往往较高在多轮对话中往往存在多个衍生子问题该类问题对于知识库建设也起着较为关键的作用。因此在局部层要求大模型从局部出发判断用户可能提出的业务问题及客服是否有解决方案若有解决方案则输出多个局部问答对。针对上下两层子任务我们分别设计了相应的提示词基于这个策略我们借用开源模型抽取人工检验标注了基于2000个会话的问答对数据最终可用数据有1300条。我们用这批数据lora微调了Qwen-14b的模型。为了保证问答对抽取的完整性并未限制抽取的问答对的数量因此局部抽取模块的问答对抽取自由度较高导致可能会有脏数据产生。我们也利用大模型对抽取的问答对作质量评估将质量较低的问答对筛选掉。由于前文所述的会话问答对大模型在经过对话数据微调后对于对话有相应理解能力此处我们仅用该大模型作简单的评估即可对部分无关问题进行剔除。我们抽取问答对的可用率在试点租户上可达70%。三、从【知识相互冲突】出发的知识标签策略前面两章讲的还是知识本身搜不到的问题这一章节关注的问题是在于我们之前会有一些case是在知识库非常大的智能体下面会发现有这样一种bad case对同一个query在不同的文档里确实是都能找到回答但这两个文档的质量又确实有差异。一方面是在面对这类问题时往往大模型是无法直接判断错对优先另一方面是本身模糊不清的知识更易让大模型产生幻觉。因此我们在构建知识库时可以考虑运用一些天然的知识标签和低成本构建的知识标签来增强知识库以化解知识冲突问题。1. 从知识标签到文档优先级为了前置去解决给大模型的知识文档冲突的问题我们需要在给大模型前事先判断出文档之间的重要性次序可以利用文档的一些内容以外的信息作为文档标签来进行文档之间的相对优先级比较。从天然标签上来说文档的时间信息及阅读量信息均可作为参考从人工标签上来说配合的业务方能从专业的角度进行简单的标记将一些高保障知识库优先级打高、非常用知识库优先级打低。标签的用法上一方面是可以前置做一些规则上的定制化过滤另一方面当我们需要的只是在大模型思考时候减少知识冲突带来的混乱时则是可以将其综合对文档做相对的优先级分数区分。2. 文档优先级运用思路从文档标签中获取优先级后到底如何使用一开始也比较困扰。调研大部分的落地方法里一般在这里会带过说结合场景设计策略。最开始和业务同学聊说希望能加入文档优先级能够更明确地剔除一些无效文档把高质量文档的权重调高。我们尝试了在多个环节将文档优先级化成权重再将这个权重做一些策略加入到检索/重排分数中但一番尝试后发现这个调权过程非常之没有道理。权重调低了这个优先级基本没用调高了一些高度相关但优先级不高的文档在一些query里又会完全失效。且即使对现有评测集里的case利用权重我们能调出一版最优的结果但这些权重对后续未知case就全是黑盒并不是合理的应用方法。后续我们在实践中改变了做法。筛除无关文档文档优先级一个最简单有效的用法是语雀知识库中大量知识但很多平台的早期更新文档或者是个人记录其实都是无关紧要的信息。因此文档优先级可以用在过滤无关文档上。结合CoT的Ref Selection而对于都可能有用的文档来说检索召回阶段的目标是召回相关文档那这个阶段优先级加权怎么都不合理因为必然会影响本身文本的相关性。我们不在检索中直接按优先级排序而是将原有的通过相关性检索出来的文档和文档之间的相对优先级均通过prompt的方式告诉大模型启发大模型先去选出要参考的文档再从中进行作答。这类优先级用法要解决的是具体两类问题1. 一类情况是我们已经知道了哪些是相关的但这些相关文本里可能有些知识冲突或者是一些重复时候优先让模型参考优先级高的答2.还有一类情况是对于重排后文档整体相似度阈值如果说检索出来的文档相关性其实都低于某个水位的时候让模型优先参考优先级高的至少答的是比较高质量的内容。在实践时的一个小trick在于让模型选出参考文档时让模型给出简单的思考过程会比让模型直接给出参考文档的效果好很多。这个trick的有效性可能在于作为生成式的模型大模型确实是在生成过程中进行思考而辨别文档相关性、知识冲突这些需要思考的指令又十分需要思考过程。我们也发现让模型选出参考文档优先级确实是只能给模型辅助唯一风险是优先级的使用有时候也比较黑盒有的时候真的不懂模型的想法。后续我们也会尝试微调的方案在参考文档的选择时也可以结合RAFT的思想对模型进行微调让模型具有在一些冲突时候优先选择优先级高的文档作答的能力。未来规划我们目前的研发助手业务会持续跟进除了在线链路上的优化外后续在知识增强上依然会持续优化。对很多线上case的分析上来说目前我们对知识增强做了很多方案上的探索整体思路已大致确立但仍有一些落地中实用但难做的点需要继续探索历史会话的深度挖掘不止一个业务方反馈非常需要对历史会话内容的挖掘这块不止包括问答对抽取能力的优化也包括如何配合进行历史会话的智能化分析、整理高频问题。目前也是在探索中。多模态知识的扩充我们目前扩充的知识库也都是基于文本信息对图片信息和文档链接的处理相同将其作为url链接前端上能对模型吐出的图片url链接进行展示。所以如果大模型从这段话里认为这个图片信息需要展示会吐出但这个做法也是损失了图片本身的信息。后续我们也需要尝试利用图片信息再扩充知识库。最后的最后感谢你们的阅读和喜欢我收藏了很多技术干货可以共享给喜欢我文章的朋友们如果你肯花时间沉下心去学习它们一定能帮到你。因为这个行业不同于其他行业知识体系实在是过于庞大知识更新也非常快。作为一个普通人无法全部学完所以我们在提升技术的时候首先需要明确一个目标然后制定好完整的计划同时找到好的学习方法这样才能更快的提升自己。这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】大模型知识脑图为了成为更好的 AI大模型 开发者这里为大家提供了总的路线图。它的用处就在于你可以按照上面的知识点去找对应的学习资源保证自己学得较为全面。经典书籍阅读阅读AI大模型经典书籍可以帮助读者提高技术水平开拓视野掌握核心技术提高解决问题的能力同时也可以借鉴他人的经验。对于想要深入学习AI大模型开发的读者来说阅读经典书籍是非常有必要的。实战案例光学理论是没用的要学会跟着一起敲要动手实操才能将自己的所学运用到实际当中去这时候可以搞点实战案例来学习。面试资料我们学习AI大模型必然是想找到高薪的工作下面这些面试题都是总结当前最新、最热、最高频的面试题并且每道题都有详细的答案面试前刷完这套面试题资料小小offer不在话下640套AI大模型报告合集这套包含640份报告的合集涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师还是对AI大模型感兴趣的爱好者这套报告合集都将为您提供宝贵的信息和启示。这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】