--- title: 万字详解 RAG 基础概念 description: 深入解析 RAG(检索增强生成)核心概念,涵盖 RAG 工作原理、Embedding、相似度度量、RAG vs 微调、RAG vs 长上下文、核心优势与局限性等高频面试考点。 category: AI 应用开发 head: - - meta - name: keywords content: RAG,检索增强生成,LLM,知识库,Embedding,语义检索,向量检索,微调,Fine-tuning,长上下文,企业知识库 --- 做企业知识库问答时,很多团队的第一反应都是:把文档全塞给大模型,让它自己读。 文档少的时候,这招确实能跑。一旦知识库涨到几十万字,问题很快就出来了:每次请求都可能撞 Token 上限,刚更新的内容模型也不一定知道。更现实一点,企业文档还要考虑权限、溯源、成本和延迟,不能靠“全塞进去”硬扛。 RAG 要做的事其实很直接:在让大模型回答之前,先从知识库里找出相关内容,再把这些内容交给模型,让它基于证据生成答案。 这篇文章接近 6200 字,主要讲清楚几件事: 1. RAG 是什么、为什么需要它; 2. 检索、增强、生成三个环节怎么配合; 3. Embedding 和相似度度量到底在做什么; 4. RAG 和传统搜索、微调、长上下文分别适合什么场景; 5. RAG 的优势和坑分别在哪里。 ## 什么是 RAG? **RAG(Retrieval-Augmented Generation,检索增强生成)** 就是把信息检索和大语言模型绑在一起用。系统先从知识库里检索出和当前问题相关的片段,知识库可以是数据库、文档集合,也可以是企业内部系统。然后把这些片段和原始问题一起喂给 LLM,让模型基于检索内容回答,而不是只靠训练时记住的知识。 ![RAG 示意图](https://oss.javaguide.cn/github/javaguide/ai/rag/rag-simplified-architecture-diagram.jpeg) ## 为什么需要 RAG? ![RAG(检索增强生成)如何解决 LLM 的核心挑战](https://oss.javaguide.cn/github/javaguide/ai/rag/rag-llm-challenges.png) LLM 训练数据再大,也绕不开几个问题。RAG 正好可以在这些地方进行弥补。 **第一是知识时效性。** 预训练模型的知识会停在训练数据截止时间点。训练后发生的新事件、新政策、新产品文档,模型默认是不知道的,除非通过联网、工具调用或外部知识注入来补。RAG 的做法是动态检索外部知识源,把最新的相关内容直接送给 LLM,让它不用只依赖参数里的旧知识。 **第二是私有数据访问。** 企业内部的产品文档、知识库、客户数据,不可能让公开 LLM 随便访问。RAG 在用户提问时只提取和问题相关的片段给 LLM,不需要暴露全部数据,模型也能基于企业自己的知识回答。 **第三是幻觉问题。** LLM 编造事实这件事大家都遇到过。RAG 通过提供明确参考文本,让模型尽量基于证据回答,确实能降低幻觉概率。但别指望它彻底消除幻觉。检索错误、上下文噪声、引用错配、模型不遵循指令,都可能导致错误答案。生产级 RAG 通常还要配引用校验、答案评估、拒答机制和人工反馈闭环。 ## RAG 的常见用途有哪些? RAG 最适合“答案依赖外部资料,并且资料会变化或很长”的场景。它先从知识库里检索相关内容,再让大模型基于检索结果生成回答,减少胡编,同时提高可追溯性。 常见场景包括这些: - 客服机器人:基于产品知识库做问答、排障、流程引导,比如“如何退换货”“某型号设备报错码怎么处理”。 - 研发 / 运维 Copilot:检索代码库、接口文档、告警手册,辅助定位问题和生成修复建议。 - 医疗助手:检索指南、药品说明、院内规范后生成辅助建议,但不做最终诊断,比如“某药禁忌是什么”“依据指南解释检查指标含义”。 - 法律咨询:基于法规条文、案例、合同模板检索,生成条款解释和风险提示。 - 教育辅导:从教材、讲义、题库中检索知识点,生成讲解和例题步骤。 - 企业内部助手:连接制度、SOP、会议纪要、技术文档,做检索、总结、对比。 - 投研、合规、审计、销售方案支持:处理报告、披露、内控、产品手册、标书模板等资料。 ## 为什么有些企业还是宁愿用传统搜索而不是 RAG? 不是所有问题都值得上 RAG。很多企业保留传统搜索,不是因为不知道 RAG 好用,而是用户需求本来就没到“生成答案”这一步。 如果用户只是想找一份制度原文、某个接口文档、一个合同模板,搜索框反而更直接。输入关键词,返回文档列表,用户自己点开确认,链路短、成本低、结果也更可控。RAG 则要先检索,再组织上下文,最后交给 LLM 生成答案。只要经过生成,就会多出延迟、Token 成本和总结偏差的风险。 所以选传统搜索还是 RAG,先看用户到底想要什么:是“帮我找到材料”,还是“帮我读完材料并给出结论”。 | 维度 | 传统搜索(搜索框) | RAG(检索 + 生成) | | --------------- | ------------------------------------------ | ------------------------------------------------ | | 用户目标 | 找到文档、页面、附件 | 直接得到可读答案、总结或对比结论 | | 延迟与成本 | 极低,容易扩展 | 更高,需要检索和 LLM 推理 | | 可控性 / 可审计 | 强,直接给原文链接 | 弱一些,可能误解或总结偏差,需要引用与评测 | | 风险 | 低,主要是召回排序问题 | 更高,包括幻觉、引用错误、越权泄露 | | 数据治理 | 相对成熟,ACL、字段过滤都好做 | 更复杂,需要检索过滤、上下文脱敏、日志治理 | | 适用场景 | 编号、标题、关键词检索,找模板、找制度原文 | 客服解答、技术排障、制度解读、跨文档总结对比 | | 最佳实践 | ES / BM25 + 权限过滤 | 混合检索 + 重排 + 引用溯源 + 权限过滤 + 评测闭环 | 实际落地时,很多企业会同时保留两套入口:**简单查找走搜索,复杂问答走 RAG**。这个组合通常比“所有问题都交给 RAG”更稳,也更省钱。 ## RAG 工作原理了解吗? RAG 的工程链路通常分两个阶段:离线索引和在线检索生成。索引阶段把原始文档处理成可检索的数据结构;在线阶段在用户提问时完成查询理解、检索召回、上下文构建和答案生成。 索引和检索阶段的简化流程图如下: ![索引和检索阶段的简化流程图](https://oss.javaguide.cn/github/javaguide/ai/rag/rag-rag-engineering-link.png) 索引阶段主要做这些事: 1. 输入文档:文本文件、PDF、网页、数据库记录都可以,只要有内容。 2. 清理文档:去掉 HTML 标签、特殊字符等噪声。 3. 增强文档:补充元数据,比如时间戳、分类标签,为后续检索提供过滤维度。 4. 文档拆分(Chunking):用文本分割器把文档切成较小片段。这一步要兼顾语义完整性、Embedding 模型输入长度、生成模型上下文窗口和召回粒度。Chunk 太大容易引入噪声,太小又可能丢上下文。拆分策略会直接影响召回质量,详细可以看 [RAG 文档处理篇](./rag-document-processing.md)。 5. 向量化表示(Embedding Generation):通过嵌入模型将文本片段映射为语义向量,也就是高维稠密向量。常见嵌入模型包括 OpenAI 的 `text-embedding-3-small` / `text-embedding-3-large`,以及 Hugging Face 上的开源模型。 6. 存储到向量存储或索引系统:把嵌入向量、原始内容和对应元数据存入向量存储或向量索引系统,比如 Milvus、pgvector、Elasticsearch / OpenSearch 向量检索,或基于 Faiss 构建本地向量索引。向量数据库选型、索引算法和 pgvector 实践可以看 [RAG 向量库篇](./rag-vector-store.md)。 索引过程通常离线完成。比如团队每周跑一次定时任务,把新增和变更的文档重新索引一遍。如果是用户上传文档这类动态场景,索引也可以在线完成,直接集成到主应用里。 检索是在线进行的。用户提问之后,系统通常会走下面这些步骤: 1. 接收请求:拿到用户的自然语言查询。有些系统会先做查询改写或扩充,让后续检索更容易命中。 2. 查询向量化:用嵌入模型把查询也转成向量,这样才能和文档向量在同一个空间里比较。 3. 信息检索(R):在向量库里做相似性搜索,把和查询向量最相关的文档片段捞出来。 4. 上下文增强(A):把检索片段、原始问题、系统指令和引用要求组织成 Prompt,交给 LLM。 5. 输出生成(G):LLM 输出自然语言回复,同时附上参考资料链接。 6. 结果反馈(可选):用户不满意时可以反馈,系统再调整 Prompt 或检索策略。有些实现也支持多轮对话来逐步完善回答。 检索效果不稳定时,问题往往出在查询改写、召回策略、排序或上下文质量上。优化方向可以看 [RAG 优化篇](./rag-optimization.md)。 ## Embedding 是什么? Embedding 就是把文本变成一串数字。更准确地说,它会把文本映射到一个高维稠密向量空间里,让语义接近的文本在向量空间中距离更近。 比如这三句话: - “如何申请退款?” - “退款流程是什么?” - “订单怎么取消并退钱?” 它们字面不一样,但语义接近。好的 Embedding 模型会把它们映射到相近位置,向量检索才能把相关 Chunk 找出来。 ![Embedding:把文本映射到语义空间](https://oss.javaguide.cn/github/javaguide/ai/rag/rag-2-embedding-map-text-to-semantic-space.png) Embedding 维度通常是 768、1024、1536、3072 等。维度越高,能表达的信息越丰富,但存储、索引和相似度计算成本也越高。以 OpenAI Embedding 为例,`text-embedding-3-small` 默认输出 1536 维,`text-embedding-3-large` 默认输出 3072 维,并支持通过 `dimensions` 参数降低输出维度。 常见 Embedding 模型可以分成两类: | 类型 | 代表模型 | 适合场景 | | -------- | --------------------------------------------------------------------------------------------- | -------------------------------------------- | | 闭源 API | OpenAI `text-embedding-3-small` / `text-embedding-3-large`、Cohere Embed、Jina Embeddings API | 追求开箱即用、多语言效果、少运维 | | 开源模型 | BGE 系列、GTE 系列、E5 系列、Jina Embeddings 开源模型 | 数据不能出内网、需要私有化部署、希望控制成本 | 选 Embedding 模型时,别只看榜单排名。MTEB(Massive Text Embedding Benchmark)可以作为参考,但最后还是要用自己的业务问题评测召回率、相关性和延迟。 Embedding 模型也不是“实时理解世界”的东西。它主要负责把文本映射到向量空间,能力重点是语义匹配。如果遇到非常新的术语、梗、产品名或领域缩写,仍然要通过业务语料评测确认召回效果。 ## 向量相似度怎么计算? 文本变成向量之后,检索系统还要判断哪个向量和查询最接近。常见相似度或距离度量有三种。 | 度量方式 | 含义 | 特点 | | ----------------------------------- | -------------------------- | ------------------------------------------------------------ | | 余弦相似度(Cosine Similarity) | 看两个向量方向是否一致 | 对向量长度不敏感,RAG 场景最常用 | | 内积(Inner Product / Dot Product) | 看两个向量对应维度乘积之和 | 如果向量已经 L2 归一化,内积和余弦相似度在排序结果上通常等价 | | 欧氏距离(L2 Distance) | 看两个点在空间中的绝对距离 | 对向量幅度更敏感,适合模型或索引明确按 L2 训练 / 优化的场景 | 面试里如果被问“为什么用余弦相似度”,可以这样答:RAG 关注的是语义方向是否接近,而不是向量长度本身;余弦相似度对长度不敏感,更适合文本语义检索。实际项目里还要和 Embedding 模型推荐的距离度量、向量库索引类型保持一致,否则可能导致索引无法命中或召回效果下降。 ## RAG 与传统搜索引擎的区别是什么? ![RAG 与传统搜索引擎的区别](https://oss.javaguide.cn/github/javaguide/ai/rag/rag-rag-vs-search-engine.png) RAG 和传统搜索都在“找信息”,但拿到信息之后做的事不一样。 传统搜索拿到候选文档后,按相关性排好序,直接把结果列表给用户。每个结果彼此独立,用户自己点开、自己判断。它更像一个排序器。 RAG 会把检索到的多个知识片段一起放进 LLM 上下文,让模型做跨文档归纳和信息整合,最后生成一个直接能读的答案。它更像一个信息综合器。 几个差异比较关键: 1. 检索机制:传统搜索主要靠倒排索引和关键词匹配,BM25 是经典算法;现代搜索系统也会加语义召回和重排。RAG 的检索方式更灵活,向量检索、BM25、混合检索、图检索、数据库查询都可以用,关键是检索结果要进入 LLM 上下文参与答案生成。 2. 结果形态:搜索给文档列表,用户还要二次阅读;RAG 给答案,并尽量标出引用来源。 3. 数据范围:传统搜索擅长全网爬虫和大规模索引;RAG 更常用于企业内部知识库和垂直领域,让 LLM 低成本获得特定领域知识补充。 4. 成本和延迟:搜索响应快,成本可控;RAG 多了 LLM 推理,延迟和成本都会上去。 ## RAG 和微调怎么选? “为什么不直接微调?”是 RAG 面试里很高频的问题。 可以这样区分:RAG 解决的是模型不知道新知识或私有知识的问题,微调更适合解决模型不会按你的方式说话或做事的问题。 打个比方。你有一本很厚的员工手册,经常要查里面的规定。RAG 的思路是随查随用,把手册放在外面,每次回答前先翻一下。微调的思路是把手册背下来,让模型把这些知识内化进去。手册三天两头改版时,RAG 换个索引就行;微调要重新准备数据、训练和评测,成本完全不一样。 | 维度 | RAG | 微调(Fine-tuning) | | -------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | | 知识更新 | 更新知识库或向量索引即可 | 通常需要重新准备数据并训练 | | 数据安全 | 知识保留在外部库,按需检索 | 训练样本中的模式和部分知识会固化到微调模型参数中,敏感数据进入训练流程前需要额外评估合规和数据治理要求 | | 幻觉控制 | 可引用原文,便于溯源和校验 | 模型仍可能编造,且引用来源不天然可见 | | 成本结构 | 检索成本 + 输入 Token 成本 + 向量库成本 | 数据标注、训练 GPU、评测和版本管理成本 | | 适合场景 | 知识密集型问答、企业知识库、法规制度、产品文档、实时信息 | 风格适配、格式控制、领域术语对齐、固定任务行为优化 | | 主要风险 | 检索不到、召回噪声、权限过滤复杂 | 数据过拟合、知识过期、训练和回滚成本高 | 二者也可以结合。先用微调让模型更懂领域术语、输出格式和任务边界,再用 RAG 提供实时知识和可追溯证据。这类组合在客服、法律、医疗、金融投研等场景里很常见。 面试时可以这样收尾:知识变动频繁、需要引用来源,优先 RAG;输出风格和任务行为不稳定,考虑微调;既要懂领域表达又要查实时知识,可以两者结合。 不过这里有个现实限制:两者结合意味着两套系统都要维护,成本不低。团队资源有限时,先把 RAG 做稳,再考虑是否引入微调,通常更务实。 ## 长上下文窗口会取代 RAG 吗? 不会。 长上下文窗口确实让很多任务变简单了。比如把一整份报告丢进去,让模型从头读到尾,这类单文档深度分析很适合用长上下文。但它不等于可以把全部知识库都塞给模型。上下文越长,输入 Token 成本、首字延迟和推理噪声都会上升,效果未必更好。 长上下文适合的场景很明确:单篇长文档深度分析,一个代码仓库或一个项目目录的集中理解,长对话历史总结,或者一次性材料不多但需要完整阅读的任务。 知识库规模一大,长上下文就不够用了。企业知识库、客服工单、日志、合同库动辄百万到亿级文档片段,不可能每次都全塞进去。就算塞得进去,成本和延迟也扛不住。更麻烦的是,上下文里塞太多无关片段,模型反而更容易被噪声干扰,生成看起来完整但事实不稳的答案。“Lost in the Middle”问题说的就是这个,关键信息放在长上下文中间位置时更容易被忽略。 企业知识库还绕不开权限隔离。哪些内容用户能看,哪些不能看,不能靠“全塞进去”解决。RAG 可以在检索阶段做权限过滤,只把用户有权访问的内容放进上下文。长上下文做不了这件事。 还有一点经常被忽视:可追溯性。RAG 可以明确返回引用片段,审计时能溯源。长上下文把大量内容混在一起交给模型,用户很难判断回答到底基于哪段材料。 ## RAG 有哪些演进阶段? RAG 这两年一直在迭代,大致可以分成三个阶段。 ![RAG 演进阶段](https://oss.javaguide.cn/github/javaguide/ai/rag/rag-2-evolution-stages.png) | 阶段 | 典型链路 | 特点 | | ------------ | ---------------------------------------------------------------- | -------------------------------------------- | | Naive RAG | 文档切块 → Embedding → Top-K 检索 → LLM 生成 | 最基础、最容易实现,适合 Demo 和简单知识库 | | Advanced RAG | Query Rewrite / HyDE → 混合检索 → Rerank → 上下文压缩 → LLM 生成 | 重点解决召回不准、上下文噪声和排序不稳 | | Modular RAG | 检索器、重排器、压缩器、路由器、生成器等模块可插拔组合 | 按业务场景动态路由,适合生产系统和复杂 Agent | Naive RAG 是起点,能跑通 Demo,但离生产通常还有距离。Advanced RAG 开始处理召回质量、噪声过滤和排序问题。Modular RAG 把各环节拆成可替换模块,更适合复杂场景。具体优化策略可以继续看 [RAG 优化篇](./rag-optimization.md)。 ## RAG 的核心优势和局限性是? 先说优势。 **RAG 最大的好处是知识更新成本低。** 微调要重新准备数据、训练模型、评测效果,RAG 通常只需要更新知识库和索引。新闻、法规、产品文档这类经常变化的数据,用 RAG 维护起来会轻很多。 **它也能减少幻觉,并且方便追溯来源。** RAG 让模型从“凭记忆回答”变成“基于检索证据回答”。每个回答都可以挂到具体文档片段上,这在金融合规、医疗辅助、法律检索这些对准确性要求高的场景里很重要。当然,这不代表 RAG 就不会出错,检索错了、引用错了,答案一样会翻车。 **数据隔离也更容易做。** 你可以在检索层实现多租户隔离和访问控制(ACL),确保用户只能看到自己权限范围内的数据。相比把敏感数据放进微调训练集,RAG 这套架构更适合做权限和合规治理。 **换领域的成本也低。** 不需要针对每个领域重新训练模型,把领域知识库建好、索引跑通,就能先用起来。 再看局限。RAG 不是银弹,坑也不少。 **检索质量决定上限。** GIGO 原则在这里特别明显:如果 Embedding 表达不准,或者分块策略把关键信息切丢了,召回内容和问题本身无关,下游 LLM 再强也救不回来。 **上下文也不是越长越好。** 虽然有些模型的 Context Window 已经扩展到百万级,但塞太多无关片段进去,模型注意力会被稀释,逻辑推理会被干扰,Token 开销也会跟着上升。 **延迟是另一个硬问题。** 完整链路要经过查询改写、向量化、相似度检索、重排序、上下文构建、LLM 生成,每一步都会增加耗时。对响应时间敏感的场景,不能只看答案质量,也要认真算延迟账。 **工程复杂度也不低。** 你要维护向量数据库,处理文档增量索引,持续优化检索策略,还要做权限过滤、引用溯源和评测闭环。相比直接调用 LLM API,RAG 的运维负担明显更重。 **Token 成本同样要算清楚。** RAG 省了训练成本,但每次请求都要带上下文,输入 Token 往往比普通对话高不少。文档片段塞得越多,账单和延迟都会一起涨。 ## 总结 RAG 说白了,就是先从知识库里找相关内容,再让 LLM 基于找到的内容回答。它的价值不是让模型“更神”,而是把回答拉回到可检索、可引用、可审计的证据上。 几个关键点可以重点留意下: 1. RAG 主要解决的是 LLM 知识过时、碰不到私有数据、容易幻觉这几个问题。传统搜索给的是文档列表,RAG 给的是直接可读的答案;一个更像排序器,一个更像信息综合器。 2. 知识变动频繁、需要引用来源时,优先考虑 RAG;如果要让模型按固定风格和格式输出,再考虑微调。 3. 长上下文适合少量材料的深度分析,但企业级海量知识库、权限隔离和成本控制,还是要靠 RAG 这类检索链路来兜底。 它的局限也要意识到。检索质量决定上限,上下文噪声会干扰生成,延迟、工程复杂度、Token 成本都是真实存在的。 Demo 跑通不代表生产可用,RAG 最难的部分往往不是“接一个向量库”,而是持续评估和优化召回质量。 面试里常问这些: - 什么是 RAG?为什么需要 RAG? - RAG 和传统搜索引擎有什么区别? - RAG 和微调怎么选?什么时候用 RAG,什么时候微调,什么时候两者结合? - RAG 系统中 Embedding 模型怎么选?为什么? - 余弦相似度、内积和欧氏距离有什么区别? - RAG 的幻觉问题怎么解决?RAG 一定不会产生幻觉吗? - 什么是 Lost in the Middle 问题?怎么应对? - 长上下文窗口是否会取代 RAG? - RAG 系统的评估指标有哪些? - RAG 的优势和局限性是什么? - 什么场景适合用 RAG?什么场景不适合?