CrabNote螃蟹笔记

RAG 是什么?RAG 检索增强面试题万字图解

本文《RAG 是什么?RAG 检索增强面试题万字图解》由小宇宙从原站整理搬运,详细讲解相关技术要点。

原创公众号@小宇宙coding图解Agent大约 66 分钟约 19675 字 RAG 是什么?RAG 检索增强面试题万字图解 大家好,我是小宇宙。 之前发了一篇「万字长文图解 Agent 面试题」,意外收获了很多读者的好评与认可。 也收到了不少林友的催更,大家都希望我能出一期 RAG 相关的面试题解析,毕竟现在RAG已是面试中的重点考察内容。 但很多同学一聊到 RAG,就只会说「就是给大模型外挂一个知识库嘛」,再深入问几句:RAG 的完整流程是什么?文档怎么切分?向量数据库怎么选?什么是 Re rank?什么是多路召回?怎么评估 RAG 的效果? 一连串的问题,就卡壳了。 为了帮大家解决这个痛点,我特意收集了近期大厂RAG高频面试题,整理如下: 🌟什么是 RAG? 🌟RAG 整体工作流程是怎样的? 🌟微调和 RAG 各自区别是什么? 🌟RAG 中的文档切割策略有哪些? 🌟Re rank 是什么? 🌟Embedding有哪几种算法你了解过吗? 🌟什么是向量数据库?有没有做过向量数据库的对比选型? 🌟什么是多路召回?具体怎么做? 🌟怎么量化你的 RAG 效果? 🌟什么是大模型幻觉?怎么降低幻觉? 别急,今天这篇文章,我就用最通俗易懂的方式,把 RAG 相关的核心知识一次性给你讲透。 这些也是面试中经常会被问到的高频问题,搞懂了不仅能应付面试,更能帮你真正理解企业级 RAG 系统的设计思路。 废话不多说,直接开始。 1、什么是 RAG? 聊 RAG 之前,咱们得先搞清楚一个问题: 大模型为什么需要「外挂」? 大模型的「知识困局」 你有没有遇到过这样的情况:问 ChatGPT 一个你们公司内部的问题,比如「我们公司今年的年假政策是什么」,它要么告诉你「我无法获取你们公司的内部信息」,要么就开始一本正经地编答案,说得头头是道,但全是错的。 这就是大模型的第一个困境: 知识有截止日期 。大模型的知识来自于训练数据,而训练数据是有时间窗口的。比如 ChatGPT 的某个版本,训练数据的截止日期是 2023 年 4 月,那么 2023 年 4 月之后发生的任何事情,它都不知道。你问它 2026 年发生了什么大事,它要么说不知道,要么就开始「编」。 第二个困境是: 大模型不知道你公司的私有数据 。你公司的产品文档、内部规章制度、客户信息、项目资料……这些数据从来没有出现在大模型的训练集中,它怎么可能知道? 第三个困境是: 大模型会「幻觉」 。所谓幻觉,就是大模型会非常自信地说出一些听起来很专业但完全是编造的内容。你问它一个不存在的研究论文,它能给你编出一个标题、作者、摘要、甚至 DOI 号,看起来像模像样,但全是假的。这在需要高准确性的场景(比如医疗、法律、金融)中,是不可接受的。 img 那怎么办?给大模型「开卷考试」 理解了这三个困境,你就能理解 RAG 要解决什么问题了。 打个比方。大模型就像一个参加了「闭卷考试」的学生,所有知识都得靠脑子记。但这个考试有个问题:题目会问到最新的知识(知识截止日期)、会问到课本上没有的内部资料(私有数据),而且这个学生还会「编答案」(幻觉)。 那怎么解决?最直觉的办法就是 给他开卷考试 ,允许他翻参考书。 RAG 就是这个思路。RAG 的全称是 Retrieval Augmented Generation ,翻译过来就是「检索增强生成」。核心思想非常简单: 1. 先从外部知识库中 检索(Retrieval) 出和用户问题相关的资料 2. 把检索到的资料作为 增强(Augmented) 上下文,和用户的问题一起给到大模型 3. 大模型基于这些真实的资料来 生成(Generation) 回答 这样一来,大模型的回答就有了「依据」,不再是凭空编造,而是基于真实文档生成的。知识可以随时更新(更新知识库就行),私有数据也能用了(把公司文档放进知识库),幻觉问题也大幅减少了(有真实资料做参考)。 img RAG 这个概念是怎么来的? RAG 这个概念最早是由 Facebook(现 Meta)的研究团队在 2020 年提出来的。 简单来说,他们提出了一个思路:在模型回答问题之前,先从外部文档中检索出相关的内容,再把检索到的内容作为参考喂给模型,让模型基于这些内容来生成回答。 但说实话,2020 年那会儿大模型还没那么火,RAG 这个概念也只是学术圈在讨论。真正让 RAG 火起来的,是 2023 年 ChatGPT 爆红之后,大家发现大模型在实际应用中有那么多局限性,而 RAG 恰好能很好地解决这些问题。13 到了现在,RAG 已经成为企业落地 AI 应用的 标配技术 。不管是大厂还是创业公司,只要做大模型应用,几乎都绕不开 RAG。 RAG 不是万能的 聊到这里,你可能觉得 RAG 好像什么都能解决。但等一下, RAG 真的万能吗? 答案显然不是。它解决的是「大模型缺乏特定知识」的问题,但它不能: img 改变大模型的推理能力(如果模型本身推理不行,给再多资料也没用) 改变大模型的输出风格(如果你希望模型用特定风格回答,这需要微调) 保证 100% 的准确性(检索可能召回错误的文档,模型也可能曲解文档内容) 所以 RAG 更准确的定位是: 一种让大模型基于真实、可更新的知识来回答问题的技术方案 。它和微调、Prompt Engineering 等技术是互补的,而不是替代关系。 2、RAG 整体工作流程是怎样的? 搞清楚了 RAG 是什么,下一步自然就是: RAG 系统到底是怎么运转的? 很多同学对 RAG 的理解停留在「就是检索+生成」这个层面,但真正要搭建一个 RAG 系统,远比这复杂。一个完整的 RAG 系统其实分为两个大阶段: 索引阶段(离线) 和 查询阶段(在线) 。 img 先用一个生活化的例子来理解 在讲技术流程之前,咱们先用一个生活化的例子来理解。 想象你在准备一场开卷考试。考试前,你需要先把所有参考书整理好:给每本书贴上标签、做目录索引、把重点内容标注出来。这就是「索引阶段」,它是在考试前完成的准备工作,不需要实时响应。 考试开始了,你拿到一道题目,你会怎么做?首先理解题目在问什么,然后在参考书中快速找到相关的章节,接着阅读找到的内容,最后基于这些内容组织你的答案。这就是「查询阶段」,它是实时进行的,需要快速响应。 RAG 的工作流程和这个一模一样。 img 索引阶段:把知识「整理好」 索引阶段的目标是把各种非结构化的文档,变成可以被高效检索的形式。这个阶段通常包括以下几个步骤: img 第一步:文档加载 这一步是把各种格式的文档加载进来。企业里的文档格式五花八门,PDF、Word、Excel、PPT、HTML、Markdown……每种格式都有不同的解析方式。比如 PDF 就比较麻烦,尤其是包含表格、图片、多栏排版的 PDF,解析起来很费劲。这一步的目标是把各种格式的文档统一转成纯文本。 第二步:文档切割(Chunking) 文档加载完之后,你不可能把一整本 100 页的文档直接扔给大模型,因为大模型的上下文窗口是有限的。所以需要把长文档切成一个个小的文本块(Chunk),每个文本块大概几百到几千个字符。 但切割这个事情没有看起来那么简单。你如果机械地按固定长度切,很可能一句话被切成了两半,或者一个完整的段落被拆开了,这样检索的时候就会丢失上下文。所以文档切割策略是 RAG 系统中非常关键的一环,后面我会专门用一整节来讲。 第三步:向量化(Embedding) 文本块切好之后,下一步是把每个文本块转换成一个数学向量(一串数字)。这个步骤叫 Embedding(嵌入)。你可以这样理解:Embedding 模型把一段文本「翻译」成了一个高维空间中的坐标点,语义相近的文本在这个空间中的距离也相近。 比如「今天天气很好」和「今天阳光明媚」这两句话意思差不多,它们经过 Embedding 之后,在向量空间中的距离就会很近。而「今天天气很好」和「Python 是一种编程语言」意思差很远,在向量空间中的距离也会很远。 img 第四步:存入向量数据库 最后一步,就是把所有文本块的向量存入向量数据库。向量数据库是专门用来存储和检索向量的数据库,它能高效地进行「相似度搜索」,也就是给你一个查询向量,它能快速找到和它最相近的 Top K 个向量。 这一步做完,你的知识库就建好了。 查询阶段:让大模型「翻书找答案」 知识库建好之后,当用户提出问题时,就进入查询阶段。 img 第一步:用户提问向量化 用户提出一个问题,比如「公司年假政策是什么」。系统首先用同样的 Embedding 模型,把这个问题也转换成一个向量。 第二步:相似度检索 拿着问题的向量,去向量数据库中进行相似度搜索,找到和这个问题语义最相近的 Top K 个文本块。比如可能检索出了这样几个文本块: 「公司全职员工入职满一年后享有 10 天带薪年假」 「年假可以拆分使用,每次不少于半天」 「未使用的年假可以累积到下一年,但最多累积 5 天」 第三步:构造增强 Prompt 把检索出来的文本块和用户的原始问题拼在一起,构造一个增强版的 Prompt。大概长这样: 「请根据以下参考资料回答用户的问题。参考资料:[检索出的文本块]。用户问题:公司年假政策是什么?」 第四步:大模型生成回答 把增强版的 Prompt 发给大模型,大模型基于这些真实的参考资料来生成回答。因为它有了具体的参考资料,就不会凭空编造了。 完整流程一览 把索引阶段和查询阶段合在一起,就是 RAG 的完整工作流程: 索引阶段(离线):文档加载→文档切割→文本向量化→存入向量数据库 查询阶段(在线):用户提问→问题向量化→向量检索→构造增强Prompt→大模型生成回答 这是最基础的 RAG 流程,也被称为 Naive RAG (朴素 RAG)。 在实际生产中,为了提升效果,还会加入查询改写、多路召回、重排序(Re rank)等高级技术,这些后面都会讲。 3、微调和 RAG 各自区别是什么? 了解了 RAG 的基本概念和工作流程后,你可能会有一个疑问: 想让大模型学会新知识,不是还可以用微调吗?那 RAG 和微调到底有什么区别?什么时候该用哪个? 这个问题非常重要,也是面试中的高频问题。 先搞清楚什么是微调 微调(Fine tuning),简单来说就是拿一个已经预训练好的大模型,用你自己的数据对它进行进一步的训练,让它在特定领域或特定任务上表现更好。 打个比方。大模型预训练完之后,就像一个高中毕业生,知识面很广,语数外理化生样样都懂一些。但如果你要让他当一个专业的医生,就需要送他去医学院继续学习,这个过程就类似于「微调」。 img 微调的方式也有不同的级别。 最重的方式是 全量微调 ,也就是更新模型的所有参数,效果最好但成本极高,需要大量 GPU 资源,一般只有大厂才玩得起。 比较轻量的方式叫 参数高效微调 ,比如现在最流行的 LoRA 技术,它只训练一个很小的「低秩适配器」,不动模型主体,所以硬件需求大幅降低,一张消费级显卡就能跑。 还有一种叫 指令微调 ,是用「指令 回答」格式的数据来微调,目的是让模型学会听懂指令、按指令来回答,而不是自由发挥。 用一个最直观的类比来理解区别 网上有个类比我觉得非常好,分享给大家。 微调 相当于让模型去上了一门课,知识已经「内化」到脑子里了。考试的时候是 闭卷考试 ,模型靠「记忆」来回答。但记忆可能会出错,而且新知识需要重新上课(重新训练)。 RAG 则相当于给模型配了一个参考书架,考试的时候是 开卷考试 ,模型可以翻书找答案。参考书可以随时更新,新增知识不需要重新训练模型。 这个类比把两者的核心区别说得非常到位。 img 核心维度的对比 接下来咱们从几个关键维度来对比一下。 img 知识更新方式 这是两者最核心的差异。微调要更新知识,就得重新训练模型,成本高、周期长。你们公司每个月都更新产品手册吧?如果用微调,每个月都得重新训练一次模型,想想都觉得累。但 RAG 就简单多了,只需要把新的产品手册替换掉知识库里的旧文档,重新做一下索引就行,模型完全不用动,成本极低,而且几乎可以实时更新。 准确性 微调的模型是靠「记忆」来回答的,就像闭卷考试,有可能记错或者记混。而且很多人有个误解,以为微调后模型就会严格按照训练数据来回答,其实不是的。微调更多是让模型学到了数据的「模式」和「风格」,对具体事实的准确性并不一定有保障。RAG 就不一样了,回答是基于检索到的真实文档的,可追溯、可验证,只要检索不出大问题,准确性通常比微调更高。 语言风格控制 这个维度反而是微调的强项。如果你希望模型用文言文回答、用特定的客服话术回答、模仿某个名人的说话方式,微调能做到。因为它在训练过程中就学会了这种风格。RAG 对输出风格的控制能力就比较有限了,检索到的内容只是给模型的「参考」,但模型最终怎么组织语言,还是取决于模型本身。 成本 两者的成本结构不一样。微调的初始成本高,你需要准备大量高质量训练数据、租 GPU 资源,但推理阶段的成本相对较低,因为不需要走检索流程。RAG 正好反过来,初始成本低,不需要训练模型,建个知识库就行,但每次查询都有检索开销,token 消耗也更多,因为你得把检索到的文档都塞进 Prompt 里。 什么时候用微调,什么时候用 RAG? 说了这么多对比,到底该怎么选?我直接说说我的看法。 img 大多数场景下,优先选 RAG。 尤其是需要回答的内容必须严格基于特定文档(比如法律条款、产品手册、公司制度),或者知识更新频繁(比如新闻问答、股票分析),或者涉及大量私有数据没法全部用来微调,再或者需要回答可追溯、有出处的场景,RAG 都是最合适的选择。 微调更适合这几类需求。 一是你需要模型输出特定的风格或格式,比如客服话术、法律文书格式,这种「风格」层面的需求微调更擅长。二是你需要模型学会某种「能力」而不仅仅是「知识」,比如学会用某种特定的编程语法,这种需要内化的能力微调效果更好。三是你的数据量不大且不经常更新,而且对推理速度有很高要求,不想每次查询都走检索流程。 不过话说回来,在实际生产中,最成熟的做法其实是 微调 + RAG 结合 。先用微调让模型适应你的领域和风格(比如让它学会你的行业术语和回答格式),再用 RAG 来提供实时、准确的知识支撑。两者互补,效果最好。 这就好比先送员工去培训(微调),让他学会这个行业的专业知识和做事方式;再给他配一个可随时查询的资料库(RAG),让他能随时查到最新的信息。 4、RAG 中的文档切割策略有哪些? 前面讲 RAG 工作流程的时候提到过,文档切割(Chunking)是索引阶段非常关键的一步。这一步做得好不好,直接决定了后面检索的质量,进而影响最终回答的准确性。 那文档切割到底有哪些策略?各有什么优劣?咱们来展开聊聊。 为什么文档切割这么重要? 先问一个基本的问题: 为什么不直接把整篇文档存进去,非要切成小块? 最根本的原因是大模型的 上下文窗口有限 。虽然现在大模型的上下文窗口越来越大,GPT 4 Turbo 已经支持 128K tokens,Claude 3 更是号称支持 200K tokens,但你不可能把知识库里的所有文档都塞进一次请求的 Prompt 里。所以必须先检索出最相关的部分,再把这部分内容喂给大模型。 而要检索,就得先把文档切成小块,这样才能精确匹配到和用户问题最相关的那个片段。如果你不切割,整篇文档作为一个检索单元,那用户问「公司年假多少天」,你可能会把整个 100 页的员工手册都检索出来,大模型的上下文窗口根本装不下。 但切割这个事有个两难: img 切得太小 :每个文本块信息太少,可能丢失上下文。比如把「公司全职员工入职满一年后享有 10 天带薪年假」切成「公司全职员工入职满一年后享有」和「10 天带薪年假」,第一块根本不知道在说什么。 切得太大 :每个文本块信息太多,检索精度下降,而且浪费大模型的上下文窗口。 所以, 怎么切、切多大、在哪切 ,就成了一门学问。 策略一:固定大小切割 最简单粗暴的方法,就是按照固定的字符数或 token 数来切。比如每 500 个字符切一块。 这个方法的好处是简单、可预测、容易实现。但缺点也很明显:它完全不考虑文本的语义和结构,很可能把一句话或一个段落从中间切开。 比如下面这段话: 「公司全职员工入职满一年后享有 10 天带薪年假。年假可以拆分使用,每次不少于半天。」 如果按固定 30 个字符来切,可能会切成: 「公司全职员工入职满一年后享有 10」 「天带薪年假。年假可以拆分使用,每次不」 「少于半天。」 这就完全破坏了语义。 img 为了缓解这个问题,通常会引入 重叠(Overlap) ,也就是相邻的两个文本块之间有一段重复的内容。比如每个块 500 字符,重叠 50 字符,这样即使句子被切开了,相邻块之间还有一部分重复信息可以保持连贯。 不过重叠也不能解决所有问题,只能算是一个「补丁」。 策略二:递归字符切割 这是目前 最常用的切割策略 ,也是 LangChain 框架中 的实现方式。 它的核心思想是: 按照文本的自然边界来切,而不是死板地按字符数切。 具体来说,它维护一个分隔符的优先级列表,比如 。它会先尝试用双换行符(段落分隔符)来切,如果切出来的块还是太大,就用单换行符来切,如果还是太大,就用句号来切……依次类推,直到块的大小符合要求。 img 这样做的好处是,它尽量 保持段落、句子、短语的自然完整性 ,不会把一句话从中间切开。 打个比方,这就像你整理一本书的时候,先按「章」来分,一章太大的话就按「节」来分,一节太大的话就按「段」来分。这样分出来的结果,每块内容都是相对完整和独立的。 策略三:基于文档结构的切割 这种方法是利用文档本身的格式结构来切割。 比如 Markdown 文档,可以按照标题层级来切:一级标题下面是一块,二级标题下面是一块。这样切出来的内容天然具有语义完整性。 img 再比如代码文件,可以按函数、类来切。HTML 可以按标签来切。PDF 可以按页面来切。 这种方法的好处是 充分尊重文档的结构 ,切出来的块语义完整。但缺点是只适用于格式规范的文档,如果文档本身结构混乱,或者没有明显的格式标记,就不太好用了。 策略四:语义切割 前面三种方法都是基于「规则」的,不管内容是什么,都按照预设的规则来切。语义切割则不一样,它是基于内容的 语义相似度 来决定在哪切。 核心思想是: 把语义相似的句子放在一起,语义发生转折的地方就是切割点。 具体怎么做呢?先把文档按句子切分,然后计算相邻句子之间的语义相似度(用 Embedding 模型把句子转成向量,然后计算余弦相似度)。如果相邻句子的相似度很高,说明它们在讨论同一个话题,应该放在同一个块里;如果相似度突然下降,说明话题发生了转变,这里就是一个切割点。 img 打个比方,一篇文章前半段在讲「TCP 三次握手的原理」,后半段在讲「UDP 协议的特点」。这两个话题虽然都属于网络协议,但语义上有明显的转变。语义切割就能识别出这个转变点,在前半段和后半段之间切一刀。 这种方法的切割质量最高,但计算成本也最大,因为需要对每个句子都做 Embedding 计算。 策略五:Agent 驱动的智能切割 这是最近出现的前沿方法。思路是用 LLM 本身来判断应该怎么切。 具体做法是:先用上述方法生成初始的文本块,然后用 LLM 来审视每个块,判断这个块的内容是否完整、是否需要和相邻的块合并或拆分。LLM 充当一个「智能编辑」的角色,根据对内容的理解来做出切割决策。 img 这种方法理论上效果最好,因为 LLM 能理解文本的深层语义。但成本也是最高的,因为需要大量调用 LLM。 实战中的建议 在实际项目中,不需要追求最复杂的方法。一个务实的策略是: 1. 起步阶段 :直接用递归字符切割( ),块大小 256 512 tokens,重叠 10% 20%。这个方案简单有效,能覆盖大多数场景。 2. 优化阶段 :如果你的文档有清晰的结构(Markdown、HTML),切换到基于文档结构的切割,通常能带来显著的提升。 3. 进阶阶段 :如果对检索质量有更高要求,尝试语义切割或者「父子块」策略(存储小块用于精准检索,但返回给大模型的是包含上下文的父块)。 img 5、Re rank 是什么? 前面讲 RAG 工作流程的时候,你可能注意到了一个问题: 向量检索返回的结果,顺序一定是最优的吗? 答案是: 不一定。 这就是 Re rank(重排序)要解决的问题。 先理解一个核心问题 在 RAG 系统中,检索阶段用的是 Bi Encoder(双编码器) ,也就是 Embedding 模型。它的工作方式是把查询和文档分别编码成向量,然后通过计算向量之间的余弦相似度来判断相关性。 这种方式有一个先天的不足: 它是把查询和文档「分别」处理的 。模型在编码一篇文档的时候,根本不知道用户会问什么问题。所以它只能生成一个「泛化的、平均化的」语义向量,无法针对具体的查询做优化。 img 打个比方。这就像一个图书管理员在给每本书写摘要的时候,不知道读者会问什么问题。他只能写一个通用的摘要,覆盖这本书的主要内容。但读者来问「这本书有没有讲到 XX」的时候,通用摘要可能不够精确。 更具体地说,Bi Encoder 有两个关键缺陷。 一是 信息压缩损失 。就好比你用一句话来总结一篇论文,再精彩的总结也不可能把每个细节都留住。Embedding 也是一样,一段几百字的文本被压缩成一串数字,那些细微但关键的信息可能就丢了。 二是 缺乏查询意图感知 。文档的向量是在索引阶段就预先计算好的,那时候根本不知道用户会问什么。所以同一篇文档的向量,不管用户是在问事实、做对比分析还是查步骤说明,都是完全一样的,没法根据不同的问题做出针对性的判断。 Cross Encoder:让查询和文档「面对面交流」 Re rank 使用的是 Cross Encoder(交叉编码器) 。它和 Bi Encoder 的根本区别在于: 它把查询和文档拼在一起,让模型同时看到两者,进行深度的交互分析。 img 具体来说,Cross Encoder 把查询和文档拼成这样一个输入: 然后把整个输入送进 Transformer 模型,通过自注意力机制(Self Attention),让查询中的每个词都能和文档中的每个词进行交互。模型能精确地分析查询的每个关键词在文档中是否有对应的回答,文档的内容是否真正满足了查询的意图。 打个比方。如果说 Bi Encoder 是「各自写好简历然后匹配」,Cross Encoder 就是「面对面面试」,面试官(查询)可以直接针对候选人(文档)的具体经历逐条追问,判断他是否真的适合这个岗位。 为什么不直接用 Cross Encoder? 你可能要问:既然 Cross Encoder 这么厉害,为什么不直接用它来检索? 答案是: 太慢了。 Bi Encoder 的检索之所以快,是因为文档的向量是预先计算好的,检索的时候只需要计算查询的向量,然后做向量相似度搜索就行,几毫秒就能搞定。 而 Cross Encoder 需要把查询和每一个候选文档都拼在一起,送进模型做一次完整的推理。如果你有 1000 万篇文档,就要做 1000 万次推理,这个速度完全不可接受。 所以实际的方案是 两阶段检索 。 img 第一阶段用 Bi Encoder(向量检索)快速从全部文档中筛出 Top 50 或 Top 100 候选文档,这一步追求的是速度和召回率,宁可多捞一些,不能漏掉相关的。 第二阶段再用 Cross Encoder(Re rank)对这 50 100 个候选文档做精细化重排序,因为数量已经很少了,所以即使是较慢的 Cross Encoder 也能在可接受的时间内完成。 主流的 Re rank 模型有哪些? 目前市面上的 Re rank 模型选择还挺多的,我聊聊几个主流的。 Cohere Rerank 是目前用得最多的商业方案之一,它是一个 SaaS API 服务,效果好、接入简单,基本上几行代码就能用起来。如果你的项目预算充足,不想自己部署模型,Cohere 是最省心的选择。 如果你更倾向开源方案, BGE Reranker 是目前开源模型里的标杆,由智源研究院出品,有 base 和 large 两个版本。它在中文场景下表现特别好,而且可以本地部署,数据安全有保障。很多国内企业在生产环境中用的就是它。 ms marco MiniLM 是微软基于 MiniLM 训练的一个轻量级 Cross Encoder,模型体积很小,推理速度快,适合资源有限的场景。比如你的服务器 GPU 不多,或者对延迟要求很高,这个模型就很合适。 另外还有 Jina Reranker ,Jina AI 出品的,支持多语言,如果你有英文之外的检索需求可以关注一下;以及 bce reranker ,网易有道开源的双语重排序模型,中英文混合场景下效果不错。 Re rank 带来了多大的提升? 光说原理你可能没什么感觉,咱们用数据说话。根据多个研究和实际测试的结果,加入 Re rank 后的效果提升是非常显著的。 在复杂查询场景下,比如那种需要多跳推理的问题(「A 公司收购了 B 公司后,B 公司的创始人去了哪里」这种需要串联多个文档的问题),准确率提升可以达到 40% 到 50% ,效果非常惊人。在简单的事实查询场景下,提升相对小一些,大约 18% 左右。在模糊查询场景下(用户的表述不太精确),提升约 30% 到 40% 。 另外 Databricks 的测试还表明,经过重排序后的检索结果,能让大模型的幻觉率降低约 35% 。这说明 Re rank 不只是让检索更准了,它还能间接提升最终回答的质量和可靠性。 实战中的建议 最后分享几个实战中的经验。首先是候选数量的设置, 先检索 50 到 100 个候选,再重排到 Top 5 或 Top 10 ,这个配置性价比最高。候选太多会增加 Re rank 的耗时,候选太少又可能把真正相关的文档漏掉。 其次,不需要所有查询都做 Re rank。对于简单的事实查询,Re rank 的提升有限,你可以设置一个条件触发机制,比如只在初排 Top 1 的分数低于某个阈值时才启动重排序。但对于复杂查询,Re rank 的收益非常大,建议始终开启。 6、Embedding 有哪几种算法你了解过吗? 前面讲 RAG 工作流程的时候,我们反复提到一个词「Embedding」:文档要 Embedding,用户提问也要 Embedding,然后才能做相似度检索。 但你有没有想过: Embedding 到底是怎么把文字变成数字的?不同的 Embedding 方法有什么区别?选哪种最适合我的场景? 这一节咱们就来把 Embedding 技术的前世今生聊清楚。 为什么要花这么多篇幅讲 Embedding 的演进?因为你只有理解了这个演进过程,才能明白为什么现在大家都推荐用 BGE M3 这种新一代模型,而不是随便选一个 Embedding 就完事了。 理解了「过去哪里不好」,才能明白「现在为什么好」。 从一个根本问题说起 计算机只能理解数字,不能理解文字。那怎么让计算机理解「今天天气很好」和「今天阳光明媚」这两句话意思差不多呢? 答案就是 Embedding: 把文本转换成高维空间中的数值向量,让语义相近的文本在向量空间中的距离也相近。 img 这个思想其实很朴素:如果能给每个词或每段话找到一个「坐标」,使得意思相近的东西在空间中离得近,意思不同的东西离得远,那计算机就能通过计算距离来判断语义相似度了。 第一代:静态词向量时代(2013 年) Word2Vec 是 Embedding 技术的奠基之作,由 Google 在 2013 年提出。 它的核心思想来自一个语言学假说: 「上下文相似的词,语义也相似」 。也就是说,如果两个词经常出现在相似的上下文中,那它们的意思可能差不多。 Word2Vec 有两种训练方式: CBOW(连续词袋模型) :用上下文来预测中间的词。比如给你「今天\ \ \ 很好」,让你猜空格处是什么词。 Skip Gram(跳字模型) :用一个词来预测它的上下文。比如给你「天气」,让你猜它周围可能出现哪些词。 Word2Vec 最有意思的一个特性是它能做「词语类比」。比如通过向量运算:「国王 男人 + 女人 ≈ 女王」。这说明它确实在某种程度上学到了词语之间的语义关系。 img 但 Word2Vec 有一个根本性的缺陷:它给每个词只生成一个固定的向量。 这意味着它无法处理多义词。比如「苹果」这个词,在「我吃了一个苹果」和「苹果发布了新 iPhone」中意思完全不同,但 Word2Vec 给它们的向量是一样的。而且在 Word2Vec 的世界里,「银行」不管是「河岸」还是「金融机构」都是同一个向量。 除了 Word2Vec,这个时代还有 GloVe (全局向量)和 FastText (支持子词级别的表示)等模型,思路都差不多,就不展开了。 第二代:上下文嵌入时代(2018 年) 那 Word2Vec 这个「一个词一个固定向量」的问题,有没有人解决呢?有,2018 年 Google 提出了一个革命性的模型,叫 BERT ,它直接把 Embedding 技术带入了一个全新的时代。 2018 年 Google 提出 BERT,它用 Transformer 的自注意力机制替代了传统的循环神经网络,实现了真正的 双向上下文理解 。 BERT 和 Word2Vec 最大的区别是: 同一个词在不同语境下会生成不同的向量。 比如「我去银行存钱」和「河岸边的风景很美」中都有「银行/岸」,BERT 能根据上下文给它们生成不同的向量,准确区分多义词。 BERT 的预训练方式也很有意思: MLM(遮盖语言模型) :随机遮盖 15% 的词,让模型通过上下文来预测被遮盖的词。这强迫模型学会理解上下文。 NSP(下一句预测) :给模型两句话,让它判断第二句是否是第一句的下一句。这帮助模型学会理解句子之间的关系。 在 RAG 场景中,通常取 BERT 输出的 token 的向量作为整段文本的向量表示。 img 但 BERT 也有局限 :早期版本的上下文窗口只有 512 tokens,对于长文档处理能力有限。而且 BERT 是一个通用的语言理解模型,并不是专门为「检索」这个任务设计的,所以在 RAG 场景下的检索效果还有提升空间。 第三代:融合与优化时代(2023 年至今) 既然 BERT 上下文窗口不够长、又不是专门为检索设计的,那能不能做一个「又长又专」的 Embedding 模型呢?这就是第三代要解决的问题。 到了 2023 年,Embedding 技术进入了第三代,代表性的模型是 智源研究院的 BGE 系列 和 OpenAI 的 text embedding 系列 。 BGE M3 是 2023 年发布的一个里程碑模型,它的「M3」代表三个多: Multi Granularity(多粒度) :能处理句子、段落、篇章、文档等不同粒度的输入,最大支持 8192 tokens。 Multi Functionality(多功能) :一站式集成稠密检索、稀疏检索和多向量检索三种能力,一次推理就能得到三种输出。 Multi Language(多语言) :支持 100 多种语言。 BGE M3 为什么能同时支持三种检索?因为它不仅能生成稠密向量(用于语义检索),还能通过线性变换生成稀疏向量(用于关键词匹配),还能生成多向量表示(用于更精细的匹配)。这在混合检索场景中非常有用。 OpenAI 的 text embedding 系列 也非常流行。从早期的 text embedding ada 002 到 2024 年发布的 text embedding 3 small 和 text embedding 3 large,OpenAI 的 Embedding API 以使用简单、效果好著称。其中 text embedding 3 large 的维度高达 3072,在 MTEB 榜单上表现优异。 img 第四代:基于大模型的 Embedding(2025 年) 你可能已经发现了,前面三代 Embedding 模型的「基座」都是 BERT 这种编码器模型。但 2025 年大模型(LLM)的理解能力已经远超 BERT 了,那能不能直接用大模型来做 Embedding 呢? 这就是第四代的核心思路。代表性的工作包括 LLM2Vec 、 Qwen3 Embedding 、 Seed1.5 Embedding (字节跳动)等。 核心思路是:大模型有远超传统编码器模型的语义理解能力,如果能把这种能力迁移到 Embedding 生成上,效果会有质的飞跃。不过大模型直接输出的向量质量并不好,所有向量都挤在一起,区分不开,需要经过专门的训练才能用于检索。 2025 年字节跳动发布的 Seed1.5 Embedding 在 MTEB 榜单上达到了中英文 SOTA 水平,证明了 LLM based Embedding 的巨大潜力。 怎么选 Embedding 模型? 面对这么多选择,实际项目中怎么选?给几个实用的建议: 1. 看榜单 :参考 MTEB 排行榜,这是目前最权威的 Embedding 模型评测榜单。 2. 中文场景优先选国产模型 :BGE 系列、M3E 系列、ACGE 系列在中文场景下表现通常优于 OpenAI 的模型。 3. 关注上下文窗口 :如果你的文档很长(比如法律合同、学术论文),一定要选支持长上下文的模型(如 BGE M3 的 8192 tokens)。 4. 考虑部署方式 :如果对数据安全有要求,需要私有化部署,就选开源模型(BGE、M3E);如果追求简单省事,就用 API 服务。 8、什么是向量数据库?有没有做过向量数据库的对比选型? 前面讲了 RAG 的检索过程,也讲了怎么把文本变成向量,那这些向量存在哪里呢?答案就是 向量数据库 。 向量数据库解决什么问题? 假设你有 100 万个文本块,每个文本块都被转换成了一个 1536 维的向量。当用户提问时,你需要快速找到和问题向量最相近的 Top 10 个文本块。 如果是暴力搜索,那每次查询都要和 100 万个向量逐一计算相似度,速度完全不可接受。 向量数据库就是为解决这个问题而生的。它使用特殊的索引结构(如 HNSW、IVF、PQ 等),能够在海量向量中实现 毫秒级的近似最近邻搜索(ANN) 。 img 向量数据库的核心原理 你可能会好奇:100 万个 1536 维的向量,暴力逐一比对肯定不行,那向量数据库是怎么做到毫秒级检索的? 核心思路是 用空间换时间 ,通过提前构建索引结构,让检索的时候不需要遍历所有向量。目前主流的索引思路有三种。 最常用的一种叫 HNSW ,你可以把它理解成「在一栋大楼里找人」。想象你要在一栋 50 层的大楼里找一个叫「张三」的人。如果一层一层、一间一间地找,得找到什么时候?但如果大楼有一个智能导航系统,先告诉你在第 30 层,再告诉你在 3012 房间,几步就找到了。HNSW 就是给所有向量建了这么一个「多层导航图」,从粗到细、层层缩小范围,几跳就能定位到目标。这种方式查询速度极快(毫秒级),召回率也高,是目前大多数向量数据库的默认选择。 img 第二种思路叫 IVF ,核心思想是「先分区域再搜索」。就好比快递分拣中心不会一个一个找包裹,而是先把包裹按地区分成几堆(华东堆、华南堆、华北堆),找到上海来的包裹就只去「华东堆」里翻就行了。IVF 也是这样,先把所有向量按相似度聚成若干个「桶」,查询的时候先判断目标最可能在哪几个桶里,然后只在这几个桶内搜索,不用遍历全部向量。它的好处是内存效率高,适合超大规模数据,但因为只搜索部分桶,所以会损失一点召回率。 第三种思路叫 PQ ,核心是「压缩存储」。你想象一下,如果每个向量的信息量很大,存起来特别占内存怎么办?PQ 的做法是把一个完整的向量切成几段,每段做一个「简化版」的表示,就像把一张高清照片压缩成缩略图,虽然细节丢了,但关键特征还在。这样每个向量只需要很少的字节就能存,在内存有限的场景下