一、RAG是什么

检索增强生成(RAG, Retrieval-Augmented Generation)。该架构巧妙地整合了从庞大知识库中检索到的相关信息,并以此为基础,指导大型语言模型生成更为精准的答案,从而显著提升了回答的准确性。

RAG可以简单的总结为数据处理、检索、增强和生成四个阶段:

数据处理阶段:对原始数据进行清洗和处理,并转换为检索模型可用的格式,然后写入到向量数据库中。

  • 检索阶段:将用户的问题输入到检索系统中,并从数据库中搜索相关信息。
  • 增强阶段:将搜索的相关信息进行处理和增强,以便可以更好的理解和使用。
  • 生成阶段:将增强后的信息输入到生成模型中,生成模型根据这些信息生成答案。

RAG方法使得我们不需要为每个特定任务都重新训练一个大模型,仅仅挂上知识库,即可以为模型提供额外的知识,提高回答的准确性。

可扩展性:减少模型大小和训练成本,仅仅更新特定领域的知识,即可提升回答效果

  • 准确性:引用我们自己的知识库,增强人们对模型输出结果的信任
  • 可控性:允许更新和定制知识库
  • 及时性:通过更新我们的知识库,从而使我们可以在不重新训练模型的前提下,保证回答问题的准确性。
  • 安全性:通过在数据库中设置不同的角色和权限,保证数据的保密性。

虽然RAG在一定程度上可以增强其生成的结果,但它仍有一些弊端,如:

  • 检索效果依赖embedding和检索算法
  • LLM如何利用检索到的信息仍是黑盒
  • 对所有任务都无差别检索K个文本片段,效率不高

二、搭建自己的RAG服务

1.准备自己的知识库文件

常见的文档格式一般为txt、doc、PDF等,这里我将选择最简单的txt文档进行导入,需要注意以下几点:

  • 由于目前LLM均有token的限制,所以在写入向量库时会对我们上传的文档进行分割、切块,将较长的文本切分成较小的文本,每段文本即为一个单位的知识。
  • 当PDF、doc中设计到表格、图片时,需要特殊处理,现有框架如open-webui或者lang chain等在加载该类文档时,仅仅会处理文字部分,图片和表格部分均会忽略,如果图片内容对你来说也非常重要的话,需要自己转换下,如OCR识别或者WPS转换(效果针对与具体文档而言,这里不给评价)

这里,我以一个最简单的txt来作为参考,为了方便演示,内容相对简单且简洁,具体如下:

2.open-webui 前期准备工作

文档准备完成后,写入向量库之前,我们需要先在open-web ui中进行一些前置设置,open-webui的搭建指南可参考“系列文章三”。

  • 首先,我们需要选择选择我们的词向量模型,如m3e,bge等,这里我们拿ollama支持的向量模型,如nomic-embed-text、mxbai-embeded-large来作为示例,模型需要提前在自己的o llama服务中下载,下载方式可参考“系列文章一”。
  • 其次,我们进入我们open-webui的界面,点击“文档”栏,如下:        

点击文档之后,再点击右上角的文档设置,会出现如下图的设置页面:

点击红框中的箭头,然后会看到我们当前ollama下载的所有模型,如下图:

如果没有列出模型,说明你的ollama中没有模型,可以结合我的往期文章来看看自己少了哪一步。这里我以mxbai-embeded-large为例,选择好模型之后,按照下方指示进行保存设置。如下图:

注意:这里的块参数表示将你的文档切块的大小以及块和块之间文本的重叠度,相关介绍见末尾扩展知识,这个参数按照自己的需求进行设置。因为上方我提供的知识库文字较少,所以这里的块大小我设置为30,块重叠设置为5。

3.导入知识库并写入向量库

经历了前边几步的配置,我们的所需的基础建设就基本搭建完成了,现在我们便可以导入我们的文档并写入向量数据库。

  • 导入:首先我们在“文档”界面点击“+”,以上传自己的文档,如图:

选择我们要上传的文档即可,如图:

  • 查看:上传成功后,等段时间我们的文档会显示在当前界面里,如图:

    注意:你上传完文档后,会等一段时间(耗时根据文档的大小而定)才会显示出来,这段时间是embedding的过程

  • 另外,我们还可以在“系列文章三中”设置的open-webui挂载的宿主机目录下的vector_db里查看是否有新生成的文件,如图:

  • 如上所示,正常写入向量库时,会在这里生成文件,如果没有,先确定自己查看的目录有没有问题,其次再去查看embedding的过程中是否出现了问题。

4.搭建并使用自己的RAG服务

经历如上几步,我们的知识库便挂载进去了,现在我们便可以利用我们的知识库进行聊天。

如上图所示,我们新建个聊天窗口并选择所要用的模型,这里以qwen2:1.5b为例,当不使用知识库时间,大模型回答如下:        

当使用知识库时,只需要在输入问题之前输入“#”,然后选择要挂载的文档即可,如:

这里选择我门要使用的知识库,然后再输入问题即可,如下:

可以看到,挂了知识库后,大模型的回答和我们想要的基本一致,如此,我们便可以使用自己的知识库来搭建自己的RAG服务了。

三、扩展知识

1.词向量

在机器学习和自然语言处理(NLP)中,词向量(Embeddings)是一种将非结构化数据,如单词、句子或者整个文档,转化为实数向量的技术。这些实数向量可以被计算机更好地理解和处理。如图所示:

它的优势主要包括以下两点:

  • 词向量比文字更适合检索。当我们在数据库检索时,如果数据库存储的是文字,主要通过检索关键词(词法搜索)等方法找到相对匹配的数据,匹配的程度是取决于关键词的数量或者是否完全匹配查询句的;但是词向量中包含了原文本的语义信息,可以通过计算问题与数据库中数据的点积、余弦距离、欧几里得距离等指标,直接获取问题与数据在语义层面上的相似度;
  • 词向量比其它媒介的综合信息能力更强,当传统数据库存储文字、声音、图像、视频等多种媒介时,很难去将上述多种媒介构建起关联与跨模态的查询方法;但是词向量却可以通过多种向量模型将多种数据映射成统一的向量形式。

2.向量数据库

向量数据库是用于高效计算和管理大量向量数据的解决方案。向量数据库是一种专门用于存储和检索向量数据(embedding)的数据库系统。它与传统的基于关系模型的数据库不同,它主要关注的是向量数据的特性和相似性。

在向量数据库中,数据被表示为向量形式,每个向量代表一个数据项。这些向量可以是数字、文本、图像或其他类型的数据。向量数据库使用高效的索引和查询算法来加速向量数据的存储和检索过程。

常见的向量数据库如下:

  • Chroma:一个轻量级、易用的向量数据库,专注于提供高效的近似最近邻搜索(ANN)。它支持多种向量数据类型和索引方法,使得用户可以轻松集成到现有的应用程序中。Chroma特别适用于小型到中型数据集,是初学者和小型项目的理想选择
  • Pinecone:一个实时、高性能的向量数据库,专为大规模向量集的高效索引和检索而设计。
  • Weaviate:结合了向量搜索和图数据库特性的多模态语义搜索引擎。它支持多模态数据(文本、图像等)的语义搜索,让用户能够以前所未有的方式探索和理解数据。
  • Milvus:支持多种索引类型和查询优化策略,提供卓越的查询性能和扩展性。它特别适用于大规模内容检索、图像和视频搜索等场景
  • Faiss:提供高效的相似度搜索和稠密向量聚类能力,支持多种索引构建方法和查询策略优化。Faiss易于与深度学习框架集成(如PyTorch),使得用户可以轻松将向量检索功能嵌入到深度学习应用中

3.文档切割

在二.2中我们提到了两个概念,一个是“块大小”,一个是“块重叠”。这里我们简单介绍下这两个的由来及作用。

由来:由于单个文档的长度往往会超过模型支持的上下文,导致检索得到的知识太长超出模型的处理能力,因此,在构建向量知识库的过程中,我们往往需要对文档进行分割,将单个文档按长度或者按固定的规则分割成若干个块,然后将每个块转化为词向量,存储到向量数据库中。在检索时,我们会以块作为检索的元单位,也就是每一次检索到 k 个块作为模型可以参考来回答用户问题的知识,这个 k 是我们可以自由设定的。

块大小:每个块包含的字符或 Token (如单词、句子等)的数量

块重叠:两个块之间共享的字符数量,用于保持上下文的连贯性,避免分割丢失上下文信息。