跳转到主内容
返回博客列表

一文搞懂 RAG:从索引构建到检索生成的完整技术原理

前言

你有没有发现,大模型很像一个”闭卷考试”的学霸,什么都能聊两句,但一旦问到它没学过的东西,就开始编。

问你公司去年的营收数据,它编。问你们产品的售后政策,它编。问它三天前刚发布的行业新规,它还是编。

不是它故意骗你,而是它的知识在训练结束那一刻就”冻结”了。它不知道的,只能靠猜。

那有没有办法让它从”闭卷”变成”开卷”,允许它翻资料再作答?

有,这个方案就是 RAG。


RAG 是什么?一句话说清

RAG = 先检索,再生成。

用户提了一个问题,系统不急着让大模型回答,而是先去知识库里翻一翻,把跟问题相关的内容找出来,连同问题一起丢给大模型。大模型拿到参考资料,再组织语言给出回答。

打个不太恰当的比方:你让一个律师帮你分析合同,他不会光凭记忆就给你结论,而是先翻出相关法条和过往判例,对着条文跟你讲。RAG 就是给大模型配了这个”翻资料”的能力。

这样做的好处很明显:

  • 回答有依据,不瞎编
  • 知识可以随时更新,追加新文档就行,不用重新训练模型
  • 能覆盖私有数据,比如公司内部知识库、产品文档、运维手册

哪些场景特别需要 RAG?

不是所有场景都需要 RAG。让大模型写首诗、做个翻译、帮你润色文案,它本身就够用了。但当你的场景涉及以下特点时,RAG 就非常关键:

知识是私有的。 企业内部的产品文档、运维手册、客户服务记录,这些内容从来没有出现在大模型的训练集里。没有 RAG,大模型对这些东西一无所知。

知识是会变的。 法律法规在修订、金融政策在调整、安全漏洞在不断暴露。大模型的训练数据有截止日期,之后发生的事它不知道。

错误的代价很高。 在医疗、法律、金融领域,一个错误的回答可能导致严重后果。单纯依赖大模型的”记忆”风险太高,必须有可靠的知识来源做支撑。


RAG 的两条主线

理解 RAG,最关键的是分清两条时间线:

离线阶段:建库。 在用户还没提问之前,你把各种文档整理好,建成一个可检索的知识库。这个过程叫索引构建

在线阶段:问答。 用户提了问题之后,系统实时去知识库里找相关内容,喂给大模型,让它生成回答。这个过程叫检索生成

两条线,一前一后,配合工作。下面挨个拆解。


离线阶段:索引构建,怎么把文档变成可检索的知识库

你有一堆 PDF、Word、网页、Markdown 文档,直接丢给大模型行不行?理论上可以,但实际上不行。文档太大、太杂、格式不统一,大模型根本吃不消。

所以需要一套”加工流水线”,把原始文档变成知识库。这条流水线通常分四步:

第一步:清洗和标准化

原始文档五花八门,PDF 里有乱码,Word 里有隐藏格式,网页里有广告和导航栏。这一步就是把这些脏数据清理干净,去掉无用字符、统一编码格式、把不同来源的文档转成统一结构。

就像准备考试前先把乱七八糟的课件、笔记、截图整理成一份干净的复习提纲。提纲整理得好不好,直接决定了后面复习的效率。

这也是 RAG 系统里最容易被忽视、却最致命的一环。数据质量不过关,后面做再多优化都白搭。

第二步:分片(Chunking)

一个文档动辄几万字,不可能整篇丢给大模型。一来上下文窗口有限,装不下;二来整篇文档里大部分内容和用户问题无关,塞进去只会干扰回答。

所以要把文档切成小块(chunk),检索的时候只拿出最相关的几块,精准投喂。

分片听着简单,其实很有讲究。切太大,一块里塞了好几个主题,检索时鱼龙混杂;切太小,一句话被拦腰截断,上半句在 A 块,下半句在 B 块,检索出来后上下文不完整。

实际操作中,常用的策略有:

  • 按固定长度切分
  • 按段落或章节边界切分
  • 用语义模型判断在哪里切更合理

没有放之四海皆准的最优解,需要根据你的文档结构来调。

第三步:向量化(Embedding)

这是 RAG 里最核心的”魔法”环节。

分片完成后,每一块文本都要通过 Embedding 模型,转换成一个长长的数字数组,也就是向量。你不用深究模型内部,只需要理解一件事:语义相近的文本,转换出来的向量在数学空间里也相近。

“今天天气真好”和”外面阳光明媚”字面上没什么重叠,但语义接近,所以它们对应的向量会挨得很近。而”今天天气真好”和”如何安装 Docker”的向量则会离得很远。

这就是向量化的意义。它把人类的”语义理解”,翻译成机器可以计算的”数学距离”。

至于怎么衡量两个向量近不近,最常用的是余弦相似度,也就是看两个向量夹角的方向是否接近。除此之外,也有人用欧几里得距离或点积,不同场景各有适用。

第四步:存入向量数据库

向量化完成后,每个文本块都有了对应向量。这些向量需要一个专门的存储引擎,也就是向量数据库

为什么不用 MySQL?因为传统数据库擅长的是精确匹配,比如查名字叫”张三”的记录;而向量数据库擅长的是相似搜索,比如找和这段话语义最接近的 5 段文本。

存储时,每个条目通常包含三部分:

  • 向量本身:用于相似度计算
  • 原始文本:检索出来后给大模型参考的实际内容
  • 元数据:比如来源文件名、时间、章节、权限范围等,方便过滤和追溯

常见方案包括 Milvus、Pinecone、Qdrant;如果你本来就在用 PostgreSQL,也可以直接使用 pgvector。

到这一步,离线阶段的索引构建就完成了。知识库已经准备好,接下来就进入在线问答阶段。


在线阶段:检索生成,用户提问后发生了什么

用户输入一个问题,系统通常需要在几百毫秒到几秒内完成”找资料 + 写回答”的全过程。常见流程可以拆成五步:

1. 问题向量化

用户的问题本身也是一段文本,先用和离线阶段相同的 Embedding 模型把它转成向量。这里必须用同一个模型,不然两个向量不在同一个”坐标系”里,没法比较。

2. 相似度检索

拿着问题向量,去向量数据库里找最接近的几条记录,通常先取 Top 3 到 Top 5。这一步叫粗召回,目标是先把可能相关的内容尽量捞出来,宁可多一点,也别漏掉关键线索。

但纯向量检索有个弱点:它擅长语义匹配,却可能在关键词上翻车。比如用户问”CVE-2024-1234 的修复方案”,向量检索可能找出很多和漏洞修复相关的内容,却没有一条精确提到这个编号。

所以很多系统会采用混合检索,把向量检索和 BM25 这类关键词检索结合起来,兼顾语义相关性和关键词精确度。

3. 重排序(Re-ranking)

粗召回拿到的结果往往有好有坏。这一步会用一个更精确、但也更慢的模型重新打分排序,把最相关的内容推到前面,不相关的往后放。

你可以把粗召回理解成海选,重排序就是决赛。两轮筛选下来,最终交给大模型的上下文质量会高很多。

4. 组装 Prompt

把筛选后的文本块和用户原始问题拼在一起,组成一个增强版 Prompt,大致长这样:

请根据以下参考资料回答问题:

参考资料 1:......
参考资料 2:......

用户问题:CVE-2024-1234 的修复方案是什么?

Prompt 怎么写,也会直接影响回答质量。同样的检索结果,不同的指令写法,最终输出可能差很多。

5. 大模型生成回答

最后,把组装好的 Prompt 发给大模型。模型基于参考资料组织回答,大幅降低凭空编造的概率,让回答更有据可依。

当然,如果检索本身就找偏了,模型仍然可能答错。所以一个好用的 RAG 系统,不只是选个模型就完事,而是要持续调数据、调分片、调检索策略。

如果索引阶段存了来源链接、文件名、章节等元数据,这一步还可以在回答里带上引用来源,进一步增强可信度。


总结

用一张表回顾 RAG 的两条主线:

阶段时机做了什么
索引构建离线(用户提问前)文档清洗 → 分片 → 向量化 → 存入向量数据库
检索生成在线(用户提问时)问题向量化 → 相似度检索 → 重排序 → 组装 Prompt → 大模型生成

核心思想就一句话:别让大模型裸考,给它开卷。

当然,RAG 不是万能药。检索召回不准、分片粒度不对、重排序模型效果差,都可能导致最终回答质量不理想。在实际落地里,真正拉开差距的,往往是数据质量、分片策略和检索参数调优。

另外,RAG 本身也在继续进化。2025 年以来,Agentic RAG、GraphRAG 等新架构不断出现,但底层逻辑万变不离其宗。只要你先吃透索引构建和检索生成这两条核心链路,后面再看任何 RAG 变体,理解成本都会低很多。


欢迎关注公众号 FishTech Notes,一块交流使用心得!