4.1RAG知识库基础
一、RAG知识库整体使用流程
整体流程如下图所示,接下来会一一讲解详细流程
整个流程分为两大板块 1.建立索引 2.检索生成
首先是“建立索引”板块:核心本质就是收集“知识”,然后把知识按照“相应格式”存储到“知识库”中
1.文档的收集与切割
本质:就是我们给出一大段文档知识,然后对这一大段知识做详细的划分(就好比每一本书籍都有不同的章节,这样才方便读者进行针对性的查找)
对AI也是一样的,AI如果直接对着一大段没有经过任何处理的纯文本进行检索,AI也是非常吃力的,因此我们在提供玩文档知识后,我们必须要对其进行“切割”
文档切割:将长文档分割成适当大小的片段(俗称 chunks)
- 基于固定大小(如 512 个 token)
- 基于语义边界(如段落、章节)
- 基于递归分割策略(如递归字符 n-gram 切割)
其中,比较推荐的就是第二三种切割方式,第一种基于固定大小切割方式非常不合理,了解即可
2.向量数据的转换
本质:把知识文档中的内容按照语义转换成“向量”,储存到向量数据库,方便检索系统查询对应知识
刚刚划分好了文档,但是我们依旧需要一一对文档进行检索,有没有什么好的检索方案呢?
文档知识转成向量,目的就是为了让程序更容易按“语义相似度”检索知识,而不是只按文字是否完全匹配来找。
举个例子:
普通文字检索像这样:
用户问:怎么维持异地恋?
文档里写:远距离关系如何保持亲密?
如果只按关键词搜,可能因为“异地恋”和“远距离关系”不是完全同一个词,就搜不到或排名靠后。
向量检索像这样:
“异地恋”
“远距离关系”
“长期分隔的情侣”
这些表达虽然字不一样,但语义接近,所以它们在向量空间里的位置会比较近。程序就能判断:它们大概率是在说同一类问题。
具体实现:
向量转换:使用 Embedding 模型将文本块转换为高维向量表示,可以捕获到文本的语义特征
向量存储:将生成的向量和对应文本存入向量数据库,支持高效的相似性搜索
接下来是“检索生成”板块,是用户使用时的板块
1.文档过滤与检索
本质:把用户问题转换成向量,然后拿这个“问题向量”去向量数据库中查找语义最相近的文档片段。
检索到相关片段后,系统会把这些片段作为上下文,和用户问题一起组装成 Prompt 发给 AI。
最后由 AI 基于这些上下文整理生成最终答案。
流程如下图所示:
用户问题
-> Embedding 模型转成问题向量
-> 向量数据库按相似度检索相关文档片段
-> 可选:按标签、分类、来源、权限等过滤
-> 取出命中的原文片段
-> 和用户问题一起组装成增强 Prompt
-> 发给大模型
-> 大模型基于资料组织回答
其中值得注意的是:
过滤不只靠向量相似度
- 向量相似度是核心。
- 但还可以加条件过滤,比如:
- 只查“恋爱中”分类。
- 只查“单身篇”文档。
- 只查某个用户自己的资料。
- 只查最新版本知识。
AI 不是自己去向量数据库查
- 这一点很重要。
- 是我们的程序 / Spring AI Advisor 先检索知识。
- 然后把检索到的文字塞进 Prompt。
- AI 看到的是“用户问题 + 检索出来的文字上下文”。
2.查询增强与关联
本质:刚刚的文档检索到相关片段后,系统会把这些片段作为上下文,和用户问题一起组装成 Prompt 发给 AI。
最后由 AI 基于这些上下文整理生成最终答案。
提示词组装:将检索到的相关文档与用户问题组合成增强提示
上下文融合:大模型基于增强提示生成回答
源引用:在回答中添加信息来源引用
后处理:格式化、摘要或其他处理以优化最终输出
二、信息检索板块细节划分
这个部分就是我们上面“文档过滤检索”板块的详细说明,具体流程步骤可以如下图所示:
召回
本质上就是从向量数据库找可能相关的向量数据
召回是信息检索中的第一阶段,目标是从大规模数据集中快速筛选出可能相关的候选项子集。强调速度和广度,而非精确度。
举个例子,我们要从搜索引擎查询 “编程导航 - 程序员一站式编程学习交流社区” 时,召回阶段会从数十亿网页中快速筛选出数千个含有 “编程”、“导航”、“程序员” 等相关内容的页面,为后续粗略排序和精细排序提供候选集。
混合检索策略
本质:它是实现召回的一种增强方案,多种检索方式一起找资料
实现混合检索的原因:
精排
本质:用高级模型或者算法,把之前收集到的内容做删选排序,匹配度高的放在前面优先展示
Rank模型
本质:如同它的名字一样,就是一个用于排序的模型,多用于精排阶段
Rank 模型 = 排序模型
主要用于粗排 / 精排阶段,尤其精排阶段最典型。
信息检索板块完整流程理解:
三、RAG基础实战实现---本地简化知识库
1.原始文档的切片实现
(注意,这个简化本地知识库实战并没有实现真正意义上的Transfomer的切片,仅仅只是对md进行了转换,然后根据md的井号标题做了轻量划分为一小个的document文件)
对文档进行切片要求必须是切便于SpringAI框架读取的document格式,那么我们就在切片之前必须先对我们的初始md文件做预处理
首先就要“读取”文档,因此对文档“处理”之前,我们需要先读取文档
1.引入MarkdownDocumentReader依赖,获取相应方法,这样我们才能“读”md文件
2.创建LoveAppDocumentLoader类,用于读取md文件并且把md文件转换为document的格式
2.1补充:document格式是什么
编写测试方法,看看md文件转为document的轻量划分:
2.向量的转换与基于内存的存储
首先,文件数据的写入是一定要实现DocumentWriter这个接口的,为了方便实现,我们实现VectorStore这个接口即可
详细代码注释(当时学习的时候突然忘记Bean注解作用了,因此这里注释比较多)
回顾@Bean注解
3.实现基于RAG的查询增强方法
主类编写基于rag的交互方法
四、RAG云知识库
1.从第三方平台创建云知识库
创建的同时,第三方已经帮我们做好了文档的录入、划分以及向量的转换,因此创建完后,我们只需要写好配置类(配置APIkey、云知识库名称、以及rag检索参数)
2.编写配置类,完善rag的配置
该类用于配置检索rag的大模型、检索的知识库名称、知识库检索的参数
3.实现查询增强的与AI交互的方法
编写测试方法测试
测试成功
