什么是 RAG
RAG is an AI framework for retrieving facts from an external knowledge base to ground large language models (LLMs) on the most accurate, up-to-date information and to give users insight into LLMs' generative process. —— from IBM Research.
RAG 是一个人工智能框架,用于从外部知识库中检索事实,使大型语言模型(LLM)基于最准确的最新信息,并让用户深入了解 LLM 的生成过程。
大语言模型训练完后,其内部知识库就已经确定了,所以它无法回答你超过其知识库内容的问题。除非你有能力对其进行微调,否则最简单的方法就是使用 RAG 检索外部知识库。
有人可能会认为,RAG 是不是就是让模型在回答问题前先去指定的外部知识库检索一下知识,然后再回答?这里只对了一半,模型没有那么智能,它不能主动去'检索'知识库,而是需要我们把检索到的知识'喂'给模型,让它结合'知识'和'问题',做出合理解答。
上图展示了没有使用 RAG 和使用 RAG 后的两种工作流程。黑色箭头就是没有使用 RAG 的工作流程。那这里为什么要引入一个嵌入模型呢?别急,我们这里还需要再了解一些基础知识。
非结构化数据和向量搜索
什么是结构化数据?二维表格(行和列)是最常见的结构化数据形式。它具有非常良好的关键字查询功能,只要找到对应的单元格,就能定位到行和列。它就好比传统的 SQL 搜索,能进行精确查询和模糊查询,但不能进行相关性查询。
那什么是非结构化数据呢?答案是任何文本、图片、音频、视频文件等。将这些数据进行多维展开,实现空间上的向量化。任何两个数据向量化后,如果在空间上具有相似性,就可以认为这两个数据相关联。比如一张小孩一个人荡秋千的照片和单词'孤独'可能在空间中非常接近,这样一来,使用关键词'孤独'进行向量搜索,能把这张图片查询出来。这在传统数据库加结构化数据中是很难做到的。
现在你知道什么是向量搜索了吧?向量搜索是一种基于向量空间模型的搜索技术。向量搜索的目标是在向量空间中找到与查询向量最相似的向量,即与查询向量距离最近的文档向量。
向量搜索的最常见算法是'余弦相似度',这个我们不做展开。
到了这里,你一定了解了为什么 RAG 中要引入一个嵌入模型的原因了吧。
构建知识库
知识库可以是任意非结构化数据组成的,我们这里用一个 txt 文本做示例。
文本分割
首先第一步需要将文本分割,这一步很好理解,就是将大文本分割成多个小块。不管是 pdf 还是 word,分割成小块后就可以用于检索了。因此这一步很重要,分割后的文本质量影响检索的准确性。这里给一个通用的算法,根据指定的文本长度进行分割。
def split_document_direct(document, chunk_size):
separator = "\n"
splits = [s for s in document.split(separator) if s != ""]
chunks = []
length = 0
start = 0
for i, split in enumerate(splits):
if (length + len(split)) > chunk_size:
chunks.append("\n".join(splits[start: i]))
start = i
length = 0
if i == len(splits) - :
chunks.append(.join(splits[start: i + ]))
length += (split)
chunks


