一、RAG的由来(Retrieval Augmented Generation)
有这样一个情景:有时候用大模型回答问题,有时候会答非所问,瞎编。前面的内容也提到过,大模型是基于概率来生成内容的,而不是基于事实生成内容。那么如果训练数据覆盖不周全,或者训练数据质量不是那么好的话,大模型基于以上这些“数据事实”进行生成,那么很容易会生成一些偏离事实的问题。网上那个9.11>9.9就是这么来的。
RAG的优势?
①、减少幻觉,提供大量知识作为依据,且这些数据是具有可追溯性的,从而能够减少这种情况 ②、使用最新的知识:外挂数据库与大模型是解耦的,这样子数据需要更新的时候,只需去维护外挂知识库,不用重新训练一个大模型。
RAG核心思想: 让大模型在回答问题之前,在一个外挂的知识库里面查找资料,结合找到的资料和自己的知识来给出答案。
二、RAG流程
1、加载数据
明确目标和范围,从规定范围的各种来源加载知识(txt、pdf、markdown)
2、切分数据
将文档切分成更小的文本块
技术要点:
①、为什么要切?
因为LLM上下文窗口长度有限。
②、怎么切?
如果太大,信息密度太稀疏,不利于检索;
如果太小,会丢失语义,会导致信息不完整
常见策略:
- 固定长度分块:按字符数或者token数进行划分;
- 递归字符分块:先按照段落,接着按照句子、字符进行分块;
- 结构化分块:按HTML/MArkdown格式根据标题、大纲进行分块;
- 语义分块:通过模型判断文本的语义相似度,根据语义进行分块。
3、文本嵌入
将文本块转换为向量嵌入
4、存储入库
存储到向量数据库里
5、用户提问检索
用户输入指令,然后指令转换为查询向量,用查询向量去向量数据库查询到最接近的top-K个文本块
技术要点:
①、查询预处理:
将用户的原始问题转换为对机器更友好的 ”标准问题“,如通过修正错别字,扩展同义词,识别用户意图
②、混合检索:
单纯的检索有时候可能会失灵
例如:贵司的“CP9”项目进展如何?模型可能因为不理解CP9项目,导致检索失效。
方式: 向量检索+关键词检索:
- 向量检索:匹配语义相似度
- 关键词检索:通过查询匹配关键字,如ID、项目名称、代号等。这些基于关系型数据库来查询,如MySQL
③、top-K:
要查询找回多少个相关数据,这个k的选择很重要:太少可能信息不足,太多可能会引入噪声
④、重排:
初步召回的top-K个回答,可能有些只是包含了相关的单词,不一定是最佳答案;
使用一个更轻量的模型对召回的top-K个片段和用户的原始问题进行二次打分,模型会判断(query、document_chunk)的真实相关性,选取打分后的片段作为最终上下文
6、增强生成
将用户输入的指令以及查询得到的相关文本块组织生成一个新的prompt,然后投喂给LLM,生成最终的答案。
技术要点
上下文工程: 怎么结合上下文来回答用户的问题
RAG的评估?
- 精确率:检索到的结果中,有多少是真正相关的
- 召回率:所有相关的结果中,找到了多少?
- MRR(Mean Reciprocal Rank):指第一个相关结果在搜索结果中的排名情况。假设用户输入关键词,第一个结果就是他想要的文档,那么此时MRR计算1/1=1,检索体验好;如果第十个结果才是他想要的文档,此时MRR计算1/10=0.1,那么说明这次检索没帮到什么用户,体验差。
RAG上手
①、首先去豆包生成员工手册。然后抓换为md文件导入到coze的知识库里。(如有雷同、纯属巧合)
②、然后进行自动分段和清洗。以及分块预览。
③、搭建工作流。
大模型给如下的prompt:
④、试运行:
询问无关公司问题,则回复下面链路:
询问相关问题,则按上面链路回复:
问题一:背景信息丢失。
在意图说明这里添加如下内容:
此时,再进行测试:
问题二:知识库划分太细。
还是原来的员工手册,但文本分块采用自定义分块。
然后更换知识库,测试原来的问题。
总结
这是简单的RAG上手,但有些问题还是实践过程中才能感受到。