RAG的工作流程涉及3个主要阶段:数据准备、数据召回和答案生成。数据准备阶段包括识别数据源、从数据源提取数据、清洗数据并将其存储在数据库中。数据召回阶段包括根据用户输入的查询条件从数据库中检索相关数据。答案生成阶段则是利用检索到的数据和用户输入的查询条件生成输出结果。输出质量的高低取决于数据质量和检索策略。图1-7描述了这一过程。
图1-7 RAG的工作流程
根据LLM需要处理的任务类型,数据准备通常包括识别数据源、从数据源中提取数据、清洗数据并将其存储在数据库中等环节。用于存储数据的数据库类型和准备数据的步骤可能会因应用场景和检索方法的不同而有所变化。例如,如果使用像Faiss这样的向量存储库,需要为数据创建嵌入并将其存储在向量存储库中;如果使用像Elasticsearch这样的搜索引擎,需要将数据索引到搜索引擎中;如果使用像Neo4j这样的图数据库,需要为数据创建节点和边,并将它们存储到图数据库中。下面将分别介绍不同类型的数据库以及准备数据的步骤。
向量存储库非常适合存储文本、图像、音频等非结构化数据,并根据语义相似性搜索数据。向量模型用于为数据库中存储的数据生成向量嵌入。根据数据类型、任务和向量模型的不同,数据需要被切分成更小的块。例如,如果要存储文本数据,则可以将数据切分成句子或段落。如果要存储代码,则可以将数据切分成函数或类。如果选择提供更多的上下文片段,则可以使用更小的块。将数据切分成块后,可以为每个块生成向量并将其存储在向量存储库中。在最简单的RAG系统中,当向量存储库接收到用户查询时,查询也会被转换为一个向量,向量存储库会返回与查询最相似的候选数据。
在RAG系统中,可以从通用搜索引擎(如百度、Bing等)或内部搜索引擎(如Elasticsearch、Solr等)中检索数据。在RAG架构的检索阶段,使用问题/任务详细信息查询搜索引擎,搜索引擎返回最相关的文档。搜索引擎对于从网络中检索数据和使用关键字搜索数据非常有用。可以将来自搜索引擎的数据与来自其他数据库(如向量存储库、图数据库等)的数据结合起来,以提高输出的质量。
图数据库以节点和边的形式存储数据。它适用于存储结构化数据,如表格、文档等,并使用数据之间的关系搜索数据。例如,如果你正在存储有关人员的数据,可以为每个人创建节点,并在彼此相识的人之间创建边。当对图数据库进行查询时,图数据库返回与查询节点相连的节点。这种使用知识图谱的检索对于完成像问题回答这样的任务非常有用,其中答案是人或实体。
数据召回部分的主要任务是从大型文本数据库中检索与输入相关的信息。为了尽可能保证正确答案被送入生成器部分,数据召回部分的召回率显得非常重要。一般来说,召回的数量越大,正确答案被召回的概率也就越高,但同时会面临大模型上下文长度限制的问题。
许多开源博客或框架在这部分的流程中都采用向量搜索出最相近的 k 个候选。例如,如果我们正在构建一个问答系统,并使用向量数据库存储相关数据块,可以为用户的问题生成向量,对向量数据库中的向量进行相似性搜索并检索最相似的数据块。除此之外,还可以根据用户问题,对同一数据库进行混合搜索或使用多个数据库进行搜索,并将结果组合起来作为生成器的上下文进行传递。
关于检索这部分,还有许多提高检索效果的技巧,这会引入更多的小模块,例如候选重排、大模型辅助召回等,这些都属于数据检索的范畴。在后续章节中,我们会介绍许多数据检索方面的技巧,以便在考虑大模型上下文长度的同时尽可能提高正确答案的召回率。
一旦检索到用户问题相关的数据片段,RAG系统就将其与用户的问题和相关数据一起传递给生成器(LLM)。LLM利用检索到的数据和用户的查询或任务生成输出。输出的质量取决于数据的质量和检索策略,同时生成输出的指令也会极大地影响输出的质量。
在中文的开源大模型中,对于70亿、140亿规模的开源模型,Qwen-chat是一个不错的选择。相较于ChatGLM、Baichuan等开源大模型,Qwen-chat具有更少的幻觉,更适用于大模型检索增强生成的模式。在RAG场景下,幻觉主要体现在跳脱知识片段回答问题上,即回答的答案并不出现在增强的知识片段中。模型对于未知答案的拒绝能力也属于这个范畴。对于参数量不够大的模型,可以考虑通过适量数据的微调来提升模型在问答场景的效果。