Involution Hell

RAG

RAG

本 RAG toy demo 适合给不了解 RAG 的人在 10 分钟内快速弄明白 RAG 的流程。

也可以参照"马克的技术笔记"配合食用。

RAG Retrieval-Augmented Generation 增强索引生成

解决的问题: 智能问答,构建外部知识库,使大模型更具特化。

需要的工具: 大模型,外部知识库,特定文件数据。

RAG 技术的本质 就是:

  1. 搜索特定文件里面的相关信息
  2. 把这些搜索出来的信息作为补充信息或者上下文信息
  3. 和用户的提问一起发送给大语言模型并获取答案

RAG 流程

分片 → embedding化 → 存储到向量数据库 → 用户提问 → 召回 → 重排 → 处理后的数据与用户提问一起打包扔给大语言模型 → 大语言模型返回答案

一、建立自己的小 RAG

1. Chunking(分片)

把我们的文档切分成特定片段。

例如:

  • 我们的文件:"今天天气真好"
  • 我们按照每个字分片:一整份文档变成了"今"、"天"、"天"、"气"、"真"、"好"这6个文件

优化方向: 实际的工程中,chunking 策略是 RAG 系统的一个优化方向。在这个简单的例子中,单独的字所包含的语义信息是孤立的,我们也可以改变 chunking 策略,例如把它切分成"今天","天气","真好",这种策略可能大大提高 RAG 系统的性能。

切分方式例子: 按照字数,按照段落,按照章节,按照页码等等等等。

在后续教程中我们把切分好的文件叫做"切片"。

2. 切片信息 embedding

Embedding 化就是把切片里面的信息处理成计算机可以处理的向量表示。

Embedding 化有很多种方式,首先我们需要一个 embedding 模型,通常我们可以通过 transformer sentence 库调用 hugging face 上已经存在的通用 embedding 模型。如果信息非常少,直接用 one-hot 编码也可以。初学者不必理解,这是 NLP(自然语言处理)的领域。

对于 0 基础,只需要知道有现存工具可以把切片信息转换成计算机可以处理的工具就可以。

  • 比如"今"可能转化为「0.23,0.34,0.54,0.23,0.76」这种向量。

通常我们需要处理的信息非常多,信息的 embedding 化需要大量的时间和计算成本。但是同一个模型相对相同的数据输出的向量几乎是相同的,且特定文件数据是不变的,所以我们不必每次都做一遍。我们将所有信息 embedding 化后存入一个数据库内。

优化方向: Embedding 模型不同效果不同,可以选择别人开源的预训练模型,如果自己有非常高质量的数据,也可以针对自己的目标训练一个 embedding 模型。

3. 存入向量数据库

向量数据库就是用来存储和查询向量的数据库。

为避免每次都要重新 embedding 化文件,我们把这些 embedding 化后的向量和对应的切片信息存入一个向量数据库中。(注意存入的是"切片文本"和"与之对应的向量")

向量数据库有轻量级本地嵌入(保存文件到本地机器),云端部署(保存到云端需要的时候联网查询)等多种数据库。

对于轻量级项目可以直接本地嵌入,直接调用 faiss 库或 MongoDB 库等。

优化方向: 向量数据库的优劣也可以影响 RAG 系统。

4. 基底大语言模型

大语言模型可以选择本地部署,也可以选择调用 API。

我们可以选择调用 Gemini,每日都有免费 token 额度。建议搜索 Gemini key 申领自己的 key。

优化方向: 基底大语言模型直接影响 RAG 的效果,除了 GPT、Gemini 等这种通用大模型,有些人会选择自己训练具有特化能力的模型或者拿通用大语言模型进行微调来作为基底大模型。例如专门针对医疗诊断的模型,专门针对法律咨询的模型等等,这些具有特化能力的模型虽然在通用能力上表现较差,但是在特定领域表现出色。

二、使用 RAG

一个 RAG 系统包含以上要素,假如我们现在已经建立了一个 RAG 系统,给你一个类似于 ChatGPT 那样的页面,我们直接与他交互。

5. 用户 query 与召回

假如现在我们问的问题是"今天天气怎么样?"

"今天天气怎么样?"作为用户 query 我们需要将它扔到我们 RAG 系统里相同的 embedding 模型中进行 embedding 化。我们把用户 query 得到的向量与向量数据库的向量进行匹配计算,然后从向量数据库里面取出与用户 query 相关的数据,我们把这个过程叫做召回。

召回通常追求命中率,可以对精度放宽。即召回的数据中尽量多的包含相关信息,"不放过一丝可能性"。

6. 重排

重排是对召回信息的进一步筛选,例如我们召回 20 条与 query 相关的切片内容。但是 20 条篇幅太大,我们选取里面与用户 query 的内容最相关的 5 条。

优化方向: 向量数据库的索引,和数据的召回重排,根据不同算法会得到不一样的结果。

7. 调用大模型返回结果

最后我们把用户 query 与这 5 条切片内容经过处理提示词工程后一起喂给大语言模型。大语言模型就能根据用户的 query 和相关的 5 条切片信息给我们答案。

优化方向: 好好学一下提示词工程。

例如 CoT(Chain of Thought)的基本逻辑:

  • "A is True then B is true" and "A is True" = "B is True"

贡献者