乐于分享
好东西不私藏

读懂 RAG:从文档分片到答案生成的完整流程(2)

读懂 RAG:从文档分片到答案生成的完整流程(2)

四、向量数据库

    向量数据库是专门用来存储和高效查询向量的数据库。面对海量向量,如果逐一遍历比较相似度,速度会非常慢。因此向量数据库会预先构建 ANN(Approximate Nearest Neighbor,近似最近邻)索引,用空间换时间,快速定位最相似的向量。

ANN 索引有多种实现方式,常见的有 HNSW 和 IVF:
    · IVF全称Inverted File Index(倒排文件索引),的思路是“先聚类,再分区”。假设图书馆有 100 万本书,管理员提前按主题把它们分到不同书架上(这就是“聚类”),每个书架中间贴一个代表标签(簇中心)。当查找“AI 医疗”时,系统先看哪个书架的标签最接近,比如“医学类”和“计算机类”,然后只在这两个书架里找,其余全部跳过,从而避免全库遍历。
    ·HNSW(分层导航小世界) 的思路是“多层地图”。最底层是所有向量,越往上层节点越少。查询时从顶层快速定位大致区域,再逐层往下精确查找。它的优点是精度高、查询快,适合数据量中等的场景;缺点是内存占用较大。相比之下,IVF 内存占用更小、构建更快,更适合数据量极大的场景。
    无论用哪种索引,向量数据库返回结果时都不会给出所有相似向量,而是只返回最相似的前 K 个,称为 Top-K。例如 K = 10 时,就返回 Top-10(最相似的前 10 个片段)。这个 K 值可以根据需求灵活配置。

    以"爱丽丝喜欢吃水果"这句话为例,做了 Embedding 后得到一个向量,存入向量数据库时,通常至少包含以下几列:向量(用于相似度计算)、原始文本(用于最终发给大模型)、ID,以及元数据(如文档来源、页码、章节、时间戳等)。这样,当通过向量相似度找到最相近的向量后,就能同时把对应的原始文本和元信息一并提取出来。

五、回答阶段:查询处理、召回、重排与生成

    用户提问后,首先进入查询处理。在实际工程中,召回之前通常还有一个查询处理步骤,包括查询重写(把口语化、模糊的问题改写成更适合检索的表达)、查询扩展(补充同义词、相关术语)等,以提高召回质量。

    接下来是召回(Retrieval)。召回是搜索与用户问题相关片段的过程:用户问题会先发给 Embedding 模型转换为向量,再发送给向量数据库。向量数据库利用 ANN 索引快速检索,返回与用户问题最相似的 Top-K 个片段(例如 50~100 个)。召回通常使用 Bi-Encoder(双编码器),分别把问题和片段编码成向量,再计算相似度,这种方式速度快、成本低,适合做粗筛;但缺点是问题和片段在编码时“互不照面”,缺乏直接交互,精度相对较粗。例如,问题问的是"苹果手机的缺点",召回结果里可能会混入"苹果(水果)的营养价值"。因此召回阶段宁可多取一些,把可能相关的都纳入候选,为后续精筛留足空间。

    召回的结果会进入重排(Rerank)阶段。重排的全称是重新排序,作用是从召回结果中进一步筛选出与用户问题最相关的少数片段(例如 3 个),作为最终送入模型的上下文。重排则通常使用 Cross-Encoder,将用户问题和每个片段拼接在一起作为一个整体输入模型,由模型直接输出相关性分数。这使得它能捕捉到问题与片段之间的深层交互关系,精度更高,但每对(问题+片段)都要过一次模型,计算量大、耗时长,适合精挑细选。

    如果把两者比作相亲:Bi-Encoder 像是“看简历”——男女双方各自填表,系统比对条件,效率高但可能错过细节;Cross-Encoder 像是“面对面聊天”——双方直接对话,模型判断合不合适,精准但耗时。

    召回的 Top-K 数量(如 50、100、200)和重排后送入模型的 Top-N 数量(如 3、5、10)都是可配置的超参数,需要根据文档总量、片段质量、模型上下文长度和成本来权衡。重排后只取最相关的少量片段,一方面是因为大模型有上下文长度限制,另一方面是片段过多会引入噪声,反而干扰模型判断。

    最后是生成(Generation)。重排选出的最相关的片段会和用户问题一起发送给大模型,由模型基于这些上下文生成最终答案。