RAG 全链路深度拆解:“大白”学习RAG的极简指南

内容有些长,耐心看完,对你应该有所帮助

一、向量(Embedding):AI 的"意念翻译官"

1、什么是 Embedding(嵌入、向量化)

在自然语言处理中,"Embedding" 通常翻译为嵌入,指将离散数据(如单词、图像)映射到连续向量空间的技术。

简单来说,Embedding 就是一个**从离散数据到高维连续向量空间的映射函数。**想象一下,我们将每一个词、每一段话映射到 <math xmlns="http://www.w3.org/1998/Math/MathML"> R n \mathbb{R}^n </math>Rn空间(比如 <math xmlns="http://www.w3.org/1998/Math/MathML"> n = 768 n=768 </math>n=768 或 <math xmlns="http://www.w3.org/1998/Math/MathML"> 1536 1536 </math>1536)。在这个空间里,语义相近的文本,其向量位置也会非常接近。


2、核心数学度量:相似度计算

当我们把文本变成向量后,如何判断"Pinia"和"Vuex"在语义上是相关的呢?主要靠这两个数学工具:

  • 余弦相似度 (Cosine Similarity)

    它衡量的是两个向量之间夹角的余弦值。公式如下:

    <math xmlns="http://www.w3.org/1998/Math/MathML"> S c ( A , B ) = cos ⁡ ( θ ) = A ⋅ B ∥ A ∥ ∥ B ∥ S_c(A, B) = \cos(\theta) = \frac{\mathbf{A} \cdot \mathbf{B}}{\|\mathbf{A}\| \|\mathbf{B}\|} </math>Sc(A,B)=cos(θ)=∥A∥∥B∥A⋅B

    特点:它只看方向,不看长度。在 NLP 中最常用,因为文档的长短(向量模的大小)不应影响它表达的主题语义。

  • 点积 (Dot Product)

    <math xmlns="http://www.w3.org/1998/Math/MathML"> A ⋅ B = ∑ i = 1 n A i B i \mathbf{A} \cdot \mathbf{B} = \sum_{i=1}^{n} A_i B_i </math>A⋅B=∑i=1nAiBi

    特点:如果向量已经经过了归一化(模为1),点积就等于余弦相似度。很多高性能向量数据库(如 Milvus)会通过归一化来把复杂的余弦计算简化为点积运算,以提升搜索速度。


总结:

  • 通俗定义:把一段话变成一串数字坐标。

  • 核心逻辑:在 AI 的世界里,相似的词会靠在一起。比如"西瓜"和"哈密瓜"在坐标系里的距离,肯定比"西瓜"和"波音747"要近。

  • 数学必记余弦相似度。它不看你话有多长,只看你们聊的是不是一个方向。

<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> S c = A ⋅ B ∥ A ∥ ∥ B ∥ S_c = \frac{\mathbf{A} \cdot \mathbf{B}}{\|\mathbf{A}\| \|\mathbf{B}\|} </math>Sc=∥A∥∥B∥A⋅B

二、 HNSW:AI 使用的"高速公路地图"

既然你已经掌握了相似度度量,我们要解决下一个现实问题:速度

如果你有 1 亿条文档向量,用户问一个问题,你用余弦相似度跟这 1 亿条数据逐一计算(暴力搜索),那用户可能要等半天。

为了实现毫秒级响应,我们需要 HNSW (Hierarchical Navigable Small World)

1、 核心结构: 分层图(Hierarchical Structure)

为什么使用分层存储的模式,是遇到什么困难了?

HNSW 的实现基础是多层图结构(Layered Graph):

  • 第 0 层(Layer 0): 包含数据集中所有的点,图最稠密,边最短。
  • 上层(Upper Layers): 随着层数增高,节点数量指数级减少,边变得更长。
  • 节点分布: 每个新节点在插入时,会根据概率函数随机分配到一个"最高层"。如果一个点在第 2 层,它必然也存在于第 1 层和第 0 层。

2、搜索逻辑:从"粗"到"精"

  1. 从顶层开始,先在一个很稀疏的图中找到离目标最近的点。
  2. 以这个点为入口,进入下一层,继续寻找更近的点。
  3. 不断下沉,直到最底层,精确定位邻居。

💡 类比理解: > 在宇宙的你要去太阳系地球取一个礼物。

  1. 你先坐飞船到星系(顶层,跨度大)。
  2. 找到了太阳系下有很多星球。
  3. 再到地球→某一个国家 → 地区。
  4. 最后步行到胡同,找到门牌号,可能还有邻居送的礼物(底层,跨度小,精度高)。

注意: 当你锁定了底层最相似的向量后,每个向量其实都对应着数据库里的一个指针,指向一段具体的文字(文本块)。

HNSW 输出: "离你最近的知识点是编号为 #1024, #2048, #512,#1314 ......的文本块。"

系统操作: 从数据库取出这几段话。


3、构建与插入实现 (Construction)

提问:结构与搜索都有了,那么如何存储?

插入一个新向量 <math xmlns="http://www.w3.org/1998/Math/MathML"> v v </math>v 的步骤如下:

A. 确定层数 使用指数概率分布确定新节点的最高层
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> L = ⌊ − ln ⁡ ( uniform ( 0 , 1 ) ) × m L ⌋ L = \lfloor -\ln(\text{uniform}(0,1)) \times m_L \rfloor </math>L=⌊−ln(uniform(0,1))×mL⌋

大部分点都只在第 0 层,极少数点能到达高层。

B. 寻找邻居 从顶层下降到第 <math xmlns="http://www.w3.org/1998/Math/MathML"> L + 1 L+1 </math>L+1层时,只进行简单的贪婪搜索,找到最接近 <math xmlns="http://www.w3.org/1998/Math/MathML"> v v </math>v 的进入点。 从第 <math xmlns="http://www.w3.org/1998/Math/MathML"> L L </math>L 层下降到第 0 层时,在每一层都会寻找与 <math xmlns="http://www.w3.org/1998/Math/MathML"> v v </math>v 最近的 <math xmlns="http://www.w3.org/1998/Math/MathML"> M M </math>M 个邻居并建立连接。

C. 启发式连接 (Heuristic Selection) 这是 HNSW 的精髓。在选择邻居时,它不只是简单选择最近的 <math xmlns="http://www.w3.org/1998/Math/MathML"> M M </math>M个点,而是采用多样化策略

如果候选邻居 <math xmlns="http://www.w3.org/1998/Math/MathML"> A A </math>A 虽然离 <math xmlns="http://www.w3.org/1998/Math/MathML"> v v </math>v很近,但 <math xmlns="http://www.w3.org/1998/Math/MathML"> A A </math>A 已经和 <math xmlns="http://www.w3.org/1998/Math/MathML"> v v </math>v 的另一个邻居 <math xmlns="http://www.w3.org/1998/Math/MathML"> B B </math>B 非常接近了,那么 HNSW 可能会放弃连接 <math xmlns="http://www.w3.org/1998/Math/MathML"> A A </math>A,转而连接稍微远一点但在不同方向上的 <math xmlns="http://www.w3.org/1998/Math/MathML"> C C </math>C(类似:发散思维)。 这样可以保证图的连通性更广,防止搜索陷入孤立的簇。

4、原生AI(LLM)在其中的作用

即使你不提供 HNSW 数据库(或任何外部知识库),AI 依然可以和你对答如流。

1. 核心差异:参数化内存 vs. 非参数化内存

  • 不带数据库(原生 AI): 依靠 参数化内存 (Parametric Memory)

    • AI 在"出厂"前,阅读了互联网上几万亿字的内容(预训练阶段)。这些知识并没有以"文件"形式存着,而是转化为了模型内部数千亿个权重(Weights/Parameters)
    • 这就好比一个博览群书的教授,你问他问题,他凭记忆直接回答。
  • 带数据库(HNSW/RAG): 依靠 非参数化内存 (Non-parametric Memory)

    • AI 除了脑子里的记忆,手边还放了一本《百科全书》(你的 HNSW 数据库)。
    • 这就好比教授考试时允许"开卷",他先去书里翻出相关的段落,看一眼,再回答你。

两种模式的优缺点对比

特性 原生 AI(不带数据库) AI + HNSW 数据库(RAG 模式)
知识来源 训练时的陈旧数据(有截止日期) 实时、私有、最新的外部数据
准确性 容易幻觉(一本正经胡说八道) 极高(有据可查,不乱编)
隐私性 无法访问你的本地私有文档 可以检索并处理你的私有文档
响应速度 极快(直接输出) 稍慢(需要多出一步检索时间)
可追溯性 无法告诉你答案在哪看到的 可以告诉你"根据文档 A 第 3 页显示..."

AI为什么还需要数据库?

既然 AI 自己懂这么多,为什么我们还要费劲搞 HNSW 数据库?

  1. 打破时间限制: 原生 AI 不知道 2026 年今天发生的新闻,但你可以把今天的新闻塞进数据库。
  2. 私域知识: 原生 AI 不认识你的公司代码库或财务报表,但你可以通过 HNSW 让它变成你的"公司小助手"。
  3. 消灭幻觉: 问原生 AI 一个偏僻的法律条文,它可能记混;但让它去数据库里"搜出原条文再解释",它就绝不会出错。

所以,当你直接和 AI 交互时,你是在用它的"脑子";当你给它配上 HNSW 数据库时,你是给了它一套"无穷无尽的书架"。

总结:

  • 通俗定义:你有 100 万条数据,挨个去比对相似度会慢死。HNSW 就是给这些数据建了一个"六度分隔"的导航图。
  • 工作原理:用户提问一个问题(比如:"植物为什么需要阳光"),先被embedding模型进行向量化,再向量索引HNSW的内容:在大范围找(比如"与植物相关的内容"),再进小范围找("阳光对植物的作用"),最后精准定位(比如:"线粒体、叶绿素、光合作用是植物将光能转化为化学能的过程......")。这让你能在几毫秒内从百万数据中抓出答案。

💡笔记要点:

HNSW 不负责生产答案,它只负责在几毫秒内从亿级数据中,把那几本"对的参考书"找出来给 AI 读。


三、切块(Chunking):把书拆成"便利贴"

1、数据切分(Chunking):寻找语义的"原子"

简单来说:递归字符切分是"看长相"来切(物理结构),语义切分是"看意思"来切(逻辑内容)。


递归字符切分 (Recursive Character Splitting)

这是最常用的方式,它会先按段落分,段落太长再按句子分,句子太长再按空格分。

这是目前最常用、性价比最高的方案(比如 LangChain 里的 RecursiveCharacterTextSplitter)。

工作原理:

它并不是暴力地每 500 字一刀,而是拿着一组分隔符清单去递归尝试。典型的顺序是:

  1. 一级分隔符: \n\n(双换行,通常是章节/段落)。
  2. 二级分隔符: \n(单换行)。
  3. 三级分隔符: .(句号)。
  4. 四级分隔符: ``(空格,词组)。
  5. 五级分隔符: ""(实在分不开了,就按单个字符切)。

它的逻辑:

  • 它先试着用 \n\n 切。如果切出来的块还是超过了你设定的 chunk_size,它就在这个块内部改用 \n 切,以此类推。
  • 目的: 尽可能保证一段话一句话是完整的,而不是被生硬地劈成两半。

语义切分 (Semantic Chunking)

这种方法不看回车或句号,它看的是内容的意思

工作原理:

  1. 打散: 先把整篇文章拆成一根根"独苗"句子。
  2. 测量距离: 把每个句子都变成向量(Embedding),计算句子 A 和句子 B 之间的语义相似度
  3. 寻找断层: 如果句子 A 和句子 B 的意思很接近,就把它们合并;如果到句子 C 时,发现它的意思跟前面突然"断层"了(相似度大幅下降),就在这里切一刀。

它的逻辑:

  • 它认为:只要意思还没变,我就不切开。
  • 例子: 如果你写了 1000 字都在讨论"番茄的种植",哪怕中间有 10 个段落,它也可能把它们切成一个巨大的块;而如果你下一句突然聊到了"拖拉机维修",它会立刻在这里起一个新块。

深度对比:你应该怎么选?

特性 递归字符切分 (推荐入门) 语义切分 (进阶首选)
判断标准 物理符号(换行、标点) 语义相似度(Embedding)
计算开销 极低。只是简单的字符串处理。 。每一句都要调一次模型算向量。
准确度 较好,能保留段落完整性。 极佳。每个块都是一个独立的"知识主题"。
缺点 依然可能把一个跨段落的长逻辑切断。 慢,且依赖 Embedding 模型的质量。
适用场景 通用文档、格式规整的代码、说明书。 逻辑复杂、跳跃性大的专业论文或对话记录。

开发建议

在实际做项目时,建议是:

  1. 先从"递归字符切分"开始:

    设定 chunk_size: 500chunk_overlap: 50(后面会说)。这能解决 80% 的问题,而且运行飞快,不需要花钱调模型。

  2. 遇到疑难杂症再用"语义切分":

    如果你发现 AI 总是"断章取义",或者你的文档逻辑特别碎片化,再考虑引入语义切分。


💡笔记要点:

  • 物理切分 (递归字符)是按照作者的写作习惯在猜重点。
  • 语义切分 是按照读者的理解逻辑在找重点。

2、块的大小有什么区别

问题:如果你设置 Chunk Size(切块大小)太小(比如只有 20 个字符),或者太大(比如 20000 个字符),分别会导致什么后果?

1. 如果切得太小(例如:每句一词)

  • 后果语义碎片化(Context Loss)
  • 检索质量变差。向量模型很难理解一个孤立的词。比如"它"这个词,切得太小就失去了指代对象。
  • 生成效果变差。模型拿到的是一堆零散的成语或短句,拼凑不出完整的逻辑,容易产生"幻觉"。
  • 速度:由于索引条数激增,检索压力确实会增大(虽然 HNSW 能抗,但 K-V 查询变多了)。

2. 如果切得太大(例如:整章切分)

  • 后果语义稀释(Noise Injection)
  • 检索质量中等偏下。一个 5000 字的文档,其向量是所有内容的"平均值",重点不突出。
  • 生成效果受限。LLM 的上下文窗口会被大量无关信息塞满,不仅费钱(Token 贵),还会导致模型"注意力涣散",找不到真正的答案。

解决方案:滑动窗口(Overlap)

为了解决"切太小丢上下文"的问题,工业界标准做法是设置 Overlap(重叠度)

例子:Chunk Size 500, Overlap 50。 这样每个块都会包含上一个块的末尾内容,确保语义的连续性。

关于"Overlap 10%"的精妙之处

  • 没有 Overlap: 假设你的文档是"张三喜欢吃苹果。李四喜欢吃香蕉。"如果你正好从中间切开,向量 1 只知道张三,向量 2 只知道李四。
  • 有了 10% Overlap: 两个切块都会包含中间的衔接部分。这样当用户问"谁喜欢吃水果"时,两个向量都能被搜到,AI 拿到的信息更完整。

💡笔记要点:

  • 通俗定义:书太厚,AI 读不完,得把它拆成一段一段的。
  • 金律良言 :不能切太碎(会断章取义),不能切太长(会废话太多)。通常还要让前后两块有 10% 的内容重叠(Overlap) ,确保逻辑不断线。

四. RAG 的全过程:这就是场"开卷考试"

1、知识连网

运行这个AI前,我们将历史数据切块向量化,本体存储在 向量库(文件切片部分+文件切片overlap10%),向量坐标在向量库(HNSW部分),

用户提问→ 转化为向量 → 去HNSW找到最近的向量获取地址 →根据地址去获取向量库的存储数据内容 → 再根据内容去一起写成prompt交给AI → AI处理发送答案

描述 技术术语 核心要点
切块并留 10% Overlap Text Chunking 10% 的重叠是为了防止"语义断裂"(比如一句话被切成两半,通过重叠可以保留上下文)。
本体存储在向量库 Document Store 这部分通常是磁盘上的 KV 数据库,负责存"沉甸甸"的文字。
向量坐标在 HNSW 部分 Vector Index 这部分是内存里的"路标",专门负责算数学距离。
根据地址获取内容 Metadata Fetching 通过向量 ID(你说的地址)秒杀回传对应的原始文本。
写成 prompt 交给 AI Context Injection 把搜到的"知识"塞进 AI 的输入框,这叫"上下文注入"。

2、一个完整的"查询"路径(开发者视角)

假设你是个前端开发者,你在写一个 AI 助手,整个链路是这样的:

  1. 用户输入"植物为什么需要阳光"
  2. 前端/后端 :调用 Embedding API,把这句话转成向量 <math xmlns="http://www.w3.org/1998/Math/MathML"> V V </math>V。
  3. 向量库(HNSW 部分) :计算 <math xmlns="http://www.w3.org/1998/Math/MathML"> V V </math>V 在内存图中的位置,返回 Top 1 ID: 9527
  4. 向量库(存储部分) :根据 9527 迅速从磁盘/缓存中抓取文本:"光合作用是植物..."
  5. LLM 拼接:把文本和问题发给 LLM。
  6. 用户:看到答案。

疑问?:Prompt 是怎么"拼"的?

提到的"一起写成 Prompt",在代码底层通常长这样:

System Prompt: 你是一个知识库助手。请根据以下参考资料回答用户问题。如果资料里没有,请说不知道。

参考资料(由 HNSW 检索得来):

  1. 切块内容 A...

  2. 切块内容 B...

用户问题: 植物为什么需要阳光?

AI 回答: (开始处理...)

五、 总结:你的架构图

  1. 离线阶段(预处理)

    <math xmlns="http://www.w3.org/1998/Math/MathML"> 文档 → 切块 ( O v e r l a p ) → 向量化 → H N S W ( 存坐标 ) + 数据库 ( 存文本 ) 。 文档 \rightarrow 切块(Overlap) \rightarrow 向量化 \rightarrow HNSW(存坐标) + 数据库(存文本)。 </math>文档→切块(Overlap)→向量化→HNSW(存坐标)+数据库(存文本)。

  2. 在线阶段(查询)

    <math xmlns="http://www.w3.org/1998/Math/MathML"> 问题 → 向量化 → H N S W 搜索 I D → 数据库取文本 → 拼凑 P r o m p t → A I 生成。 问题 \rightarrow 向量化 \rightarrow HNSW 搜索 ID \rightarrow 数据库取文本 \rightarrow 拼凑 Prompt \rightarrow AI 生成。 </math>问题→向量化→HNSW搜索ID→数据库取文本→拼凑Prompt→AI生成。


😁希望能帮到你🐱

相关推荐
njsgcs1 小时前
我要让ai理解3d模型,什么孔面是装轴承,什么面是攻牙孔,什么面是轴面,区分从动轮主动轮
人工智能
灰化肥发挥2 小时前
韩国草药制剂数据查询:如何获取MFDS注册数据与韩国药典标准?
大数据·人工智能·医药数据库
小王毕业啦2 小时前
2010-2023年 地级市-破产法庭设立数据(+文献)
大数据·人工智能·数据挖掘·数据分析·社科数据·经管数据·破产法庭
一只川页2 小时前
从“对话”到“实干”:大模型应用架构演进全景解析
人工智能·架构
雷焰财经2 小时前
从系统承建到生态赋能:宇信科技全球化战略的纵深与逻辑
大数据·人工智能·科技
阿_旭2 小时前
基于YOLO26深度学习的风力机缺陷检测与语音提示系统【python源码+Pyqt5界面+数据集+训练代码】
人工智能·python·深度学习·风力机缺陷检测
共绩算力2 小时前
海贼王 Pop-Up Book 风格AI生图提示词指南
人工智能·共绩算力
沪漂阿龙2 小时前
大模型最后一步关键训练:偏好调优,让AI更懂人心
人工智能
Tzarevich2 小时前
别再信它“一本正经地胡说”了!用 RAG终结大模型“幻觉”
后端·langchain·llm