005.RAG与向量数据库
向量是什么
向量是具有大小和方向的量,在数据科学中表现为有序的数字列表,列表中每一个数字都是向量的一 个”分量”或者是”维度”。[1,2,5] 表示三维空间中的一个点或方向。
如何理解多维向量
在现代人工智能和机器学习领域,多维度向量是核心中的核心。 这里的“维度”不再仅仅是物理空间中的 X、Y、Z 轴,而是抽象的“特征”或“属性”的表示。
举两个案例
文本的向量(词嵌入或句子嵌入): 假设我们有一个词“苹果”。
- **低维抽象(方便理解):**
- 维度 1:好吃程度 (0.8)
- 维度 2:电子产品相关性 (0.9)
- 维度 3:水果相关性 (0.7)
- 维度 4:颜色鲜艳度 (0.6)
- ...
- 实际情况: 文本嵌入模型(如 Word 2 Vec, BERT, GPT 等)会把“苹果”这个词映射成一个几百维(比如 768 维或 1024 维)的向量。这些维度本身并没有人类可解释的明确含义,但整个向量编码了这个词的语义信息。
- 如果“苹果”和“香蕉”的向量在这些维度上非常接近,就表示它们在语义上是相似的(都是水果)。
- 如果“苹果”和“iPhone”的向量在某些维度上(例如电子产品相关维度)也比较接近,表示它们有跨领域的相似性。
图片的向量(图像嵌入): 一张图片,例如一张猫的照片。
- 低维抽象(方便理解):
- 维度 1:是否有动物 (1.0)
- 维度 2:是否有猫 (0.95)
- 维度 3:背景是室内还是室外 (0.7)
- 维度 4:图片颜色暖色调 (0.8)
- ..
- 实际情况: 图像嵌入模型(如 ResNet, CLIP 等)会将一张图片转化为一个几百维到几千维(比如 512 维或 2048 维)的向量。这个向量就“浓缩”了图片的所有视觉和语义特征。
- 两张猫的图片,它们的向量会非常接近。
- 一张猫的图片和一个描述“可爱的猫”的文本,如果它们被映射到同一个语义空间,它们的向量也会接近。
多维度向量有什么好处
- 表达复杂信息: 现实世界的信息是极其复杂和多样的。单一的数字或几个数字不足以完全表达其含义。多维度向量能够捕捉更丰富、更细粒度的特征。
- 捕捉语义: 深度学习模型通过在大规模数据上训练,学习到如何将非结构化数据映射到高维空间中,使得具有相似语义(含义)的数据点在向量空间中彼此接近,不相似的则远离
- 进行数学运算: 一旦信息被转化为数值向量,我们就可以利用高效的数学和线性代数运算(如距离计算、点积)来衡量它们之间的相似性、关系或进行其他分析,这是传统字符串匹配或简单标签匹配无法实现的。
总结
在 AI 时代,向量是神经网络的基本数据结构,也是大模型理解和表示世界数据的核心格式。
如何将文本转为向量

用户 Query 转化为与数据库中向量相同维度的单一向量的流程:
- 用户 Query 原始文本: "机器学习分词技术"
- 分词器 (Tokenizer) 处理 Query:
- 使用与生成数据库中文档 Embedding 相同的 BERT 模型的分词器(这是关键!)。
- 分词器会为 Query 添加特殊的 Token:[CLS] 和 [SEP]。
- Tokens: [CLS], "机器", "学习", "分词", "技术", [SEP] (假设 BERT 分词器这样分)
- Tokens 转化为 Token ID 序列:
- [CLS] → 101 (BERT 模型的 [CLS] ID)
- "机器" → XXXX (某个 ID)
- "学习" → YYYY
- "分词" → ZZZZ
- "技术" → AAAA
- [SEP] → 102 (BERT 模型的 [SEP] ID)
- Token ID 序列: [101, XXXX, YYYY, ZZZZ, AAAA, 102]
- Token ID 序列送入预训练模型(如 BERT)获取 Embedding:
- 模型会处理这个序列,并通过其内部的 Embedding 层和多层 Transformer 编码器。
- 输出: 模型会为序列中的每个 Token ID 输出一个上下文相关的 Embedding 向量。
- Vector_[CLS]
- Vector_机器
- Vector_学习
- Vector_分词
- Vector_技术
- Vector_[SEP]
- 所有这些输出向量的维度都与 BERT 模型的输出维度相同(例如 768 维)。
- 聚合为单一的 Query Embedding 向量:
- 由于向量数据库中的文档 Embedding 是通过提取 [CLS] Token 的输出向量得到的。
- 因此,对于用户 Query,我们也需要采用相同的聚合策略:提取 [CLS] Token 对应的最终输出向量 (Vector_[CLS])。
Final_Embedding_vec_[CLS] (Output Embedding):
- 初始的 [CLS] Embedding 向量,连同序列中其他 Token 的初始 Embedding 向量,一起被送入 BERT 模型的多层 Transformer 编码器。
- 在每个编码器层中,核心是自注意力机制 (Self-Attention)。这个机制允许每个 Token 的表示在处理过程中,动态地关注(分配权重给)序列中的所有其他 Token。这意味着信息可以在整个序列中流动和融合。
- 经过多层自注意力机制的层层处理,[CLS] Token 的向量会不断地吸收和整合来自序列中所有其他 Token 的上下文信息。它不再仅仅是自己的初始表示,而是融合了整个句子的语义和语境。
BERT 模型在处理完一个完整的输入序列后,在最后一层输出的、专门用于捕获整个序列全局语义信息的那个高维数值向量。它不是简单的初始映射,而是经过多层复杂神经网络运算,融合了所有上下文信息,并被预训练任务赋予了代表序列语义功能的“精华”向量。
向量数据库与传统数据库的区别
| 维度 | 传统数据库 | 向量数据库 |
|---|---|---|
| 存储的数据 | 结构化数据(如字符串、整数、时间等) | 高维向量(如128维、768维float数组) |
| 查询的目标 | 精确匹配、范围匹配 | 近似匹配(查找“最相似”的向量) |
| 常见的数据来源 | 用户、订单、商品等业务实体的数据 | 文本、图片、音频、视频的embedding向量 |
| 索引技术 | B+树、Hash索引、全文索引(Inverted Index) | ANN索引(HNSW、IVF、PQ、Flat等) |
对于 MySQL 来说
SELECT * FROM users WHERE username = 'forrest';
对于 Vector DB 来说
vector := embedding("请推荐和我兴趣相似的文章")
results := vectorDB.SearchTopK(vector, topK=10)
向量中的相似度是如何计算的
余弦相似度

余弦相似度衡量的是两个向量在多维空间中的方向一致性。它不关心向量的长度(即“大小”或“强度”),只关心它们所指的方向是否相同或相似。
值范围: 余弦相似度结果在 −1 到 1 之间。
- 1 表示两个向量指向完全相同的方向(完美相似)。
- 0 表示两个向量相互垂直,方向完全不相关。
- −1 表示两个向量指向完全相反的方向(完全不相似)。
主要的向量索引技术
在高维数据应用(如推荐系统、图像检索、自然语言处理)中,快速查找与给定查询最相似的数据点(即向量)是核心挑战。传统上,暴力搜索(Brute Force Search)通过遍历所有数据点来保证精确度,但在面对海量数据时效率极低。
不同的向量索引技术在召回率、查询速度、索引构建时间、内存占用和可扩展性等方面有不同的优势和劣势。选择哪种技术通常取决于具体的应用场景需求。
暴力搜索 (Brute Force Search)
- 定义: 对数据集中所有向量逐一计算与查询向量的距离,然后排序找出最近的 K 个向量。
- 特性:
- 精度: 100% 精确。
- 效率: 在大数据集上效率极低,查询时间与数据量呈线性关系。
- 适用场景: 数据量极小或对精确度有绝对要求但效率非优先考虑的场景。
乘积量化 (Product Quantization, PQ)
- 核心思想: 高维向量压缩编码。通过将高维向量分解为多个低维子向量,并对每个子向量进行独立量化(即用聚类中心的 ID 来表示),从而大幅度压缩向量存储空间并加速距离计算。
- 工作原理:
- 子向量分解: 一个高维向量被分解成多个独立的、低维的子向量。例如,一个 128 维的向量可以分解成 8 个 16 维的子向量。
- 子空间聚类: 对每个子向量空间独立进行 K-means 聚类,为每个子空间生成一个“码本”(Codebook),其中包含若干个聚类中心。
- 编码: 原始向量的每个子向量会被其所属子空间中最近的聚类中心的 ID(一个整数)所替代。因此,一个高维向量就被编码成一串整数 ID。
- 距离近似: 在查询时,不需要计算原始高维向量的欧氏距离,而是通过查找预先计算好的距离表,或者利用量化码间的距离来近似计算查询向量与数据库中向量的距离。这大大减少了计算量。
- 特点:
- 优点: 极高的压缩比(显著减少内存占用),查询速度极快。
- 缺点: 存在精度损失;需要进行码本训练。
倒排文件索引 (Inverted File Index, IVF)
- 核心思想: 数据分组与局部搜索。通过聚类将海量向量数据预先分成多个簇(桶),查询时只在与查询向量最相关的少数几个簇中进行搜索。
- 工作原理:
- 数据聚类: 在索引构建时,使用 K-means 等算法将所有向量划分为 N 个簇,每个簇有一个中心点。
- 倒排列表构建: 为每个簇中心建立一个“倒排列表”,记录所有属于该簇的向量 ID。
- 查询过滤: 查询向量到来时,首先计算其与所有 N 个簇中心的距离,选择最近的 nprobe (用户定义参数) 个簇。
- 局部搜索: 仅对这 nprobe 个簇中的向量进行精确或进一步近似搜索。
- 特点:
- 优点: 显著加速查询(缩小搜索范围),可灵活配置召回率与速度的平衡。
- 缺点: 召回率受 nprobe 和聚类效果影响;不适用于维度极高的场景。
局部敏感哈希 (Locality-Sensitive Hashing, LSH)

- 核心思想: 相似向量哈希归桶。通过设计特殊的哈希函数,使得原始空间中相近的向量经过哈希映射后,有高概率落入相同的“哈希桶”中。
- 工作原理:
- 哈希函数族: 定义一组具有“局部敏感性”的哈希函数,将高维向量映射为低维或离散的哈希值。
- 多哈希表构建: 通常使用多组哈希函数构建多个独立的哈希表,以提高召回率。
- 查询搜索: 查询向量通过所有哈希函数计算出多个哈希桶 ID,然后只在这些(可能还有相邻的)哈希桶内的向量中进行搜索。
- 特点:
- 优点: 原理相对简单,易于并行化。
- 缺点: 内存开销大(需大量哈希表),在召回率与查询速度之间需较大权衡,对高维数据性能受限。
分层可导航小世界图 (Hierarchical Navigable Small World, HNSW)


- 核心思想: 多层图结构导航。通过构建一个分层的图结构,利用上层图进行快速粗略导航,下层图进行精细搜索,以实现高效的最近邻查找。
- 工作原理:
- 分层图构建: 算法为每个数据点分配随机层数,从顶层(最稀疏,远距离连接)到最底层(最密集,所有数据点,近距离连接)逐层构建图。
- 导航式搜索: 搜索从顶层某个起始点开始,在当前层通过贪婪策略向距离查询向量最近的邻居“游走”,找到局部最优解后,以该点作为下一层搜索的入口,直至最底层。
- 精细搜索: 在最底层执行 K 最近邻搜索。
- 特点:
- 优点: 通常能在高召回率的同时保持极快的查询速度,是目前 ANN 领域的高性能算法。
- 缺点: 索引构建过程复杂且耗时;动态更新数据不便。
五种算法对比总结
| 特性 | 暴力搜索 (Brute Force) | 乘积量化 (PQ) | 倒排文件索引 (IVF) | 局部敏感哈希 (LSH) | 分层可导航小世界图 (HNSW) |
|---|---|---|---|---|---|
| 精确度/召回率 | 100% (精确) | 低 (近似) | 中 (近似,取决于 nprobe) | 中 (近似,取决于哈希表数量) | 高 (近似,通常接近精确) |
| 查询速度 | 最慢 (线性扫描) | 快 | 中等偏快 | 快 | 最快 (通常) |
| 内存占用 | 高 (需存储所有向量) | 极低 (高压缩比) | 中等 | 极高 (多哈希表) | 中等偏高 (存储图结构) |
| 索引构建时间 | 无需构建 | 中等 (码本训练) | 中等 (聚类训练) | 快 (哈希函数生成) | 慢 (复杂图构建) |
| 更新难度 | 极易 | 中等 | 中等 | 易 | 难 |
| 高维适用性 | 适用,但速度慢 | 适用 | 中等 | 效果差,内存占用高 | 非常适用,性能优秀 |
| 主要应用 | 小数据集,需要绝对精确 | 内存受限,大规模数据集 | 中大规模数据集,需要速度 | 小规模验证性实验,概念验证 | 大规模数据集,对速度和召回率要求高 |
向量数据库常用的评价指标
- 准确率:检索相关的向量/检索出的向量总数
- 召回率:检索相关的向量/向量数据库中相关的向量总数
- 每秒平均吞吐:每秒向量数据库能够处理的查询请求次数
- 平均响应延迟:每个查询的平均请求时间
RAG 是什么
RAG (检索增强生成,Retrieval Augmented Generation)是一种结合信息检索(Retrival)和文本生成(Generation)的技术,旨在提升大模型的准确性和实用性。
为什么需要 RAG
- 解决知识滞后性(Knowledge Staleness):LLM 的训练数据是有限的,无法包含所有实时或最新的信息。召回机制可以弥补这一不足,让模型能够获取到最新的知识。
- 减少幻觉(Reducing Hallucinations):如果模型在没有足够事实依据的情况下“凭空”生成信息,就会产生幻觉。通过召回外部证据,模型可以基于更可靠的事实进行生成,从而减少错误或不准确的回答。
- 处理特定领域知识(Domain-Specific Knowledge):对于医疗、法律、金融等专业领域,LLM 可能缺乏足够的训练数据。召回机制允许模型利用这些领域的专业文档来回答问题。
- 处理长文本(Long Contexts):有些任务需要理解非常长的文本。通过召回,可以将长文本中最相关的部分提取出来,作为 LLM 的输入,避免超出模型的上下文窗口限制。
- 提高可解释性(Improving Explainability):当模型利用召回的信息生成回答时,通常可以指出这些信息的来源,从而提高回答的可信度和可解释性。
RAG 的构建流程

- 用户输入一个查询
- 检索模块从知识库种找出与查询相关度最高的文档片段
- 将检索片段结果连同查询一起当作 prompt 传递给模型
- 模型基于上下文生成内容
数据收集与预处理
- 收集来自各种数据源的各种类型的数据,例如文档(PDF、Word、MarkDown、HTML)、数据库数据、知识库等
- 清理不相关或者是重复的内容,处理缺失值,标准化格式
- 从非结构化数据中提取可读文本
文档分块
将大型的文档分割为更小、更易于管理和理解的“块”,这是因为大模型的上下文有限,小块更利于精确检索。
有多种分块的策略,块的大小需要权衡,太小可能丢失上下文,太大可能超出 LLM 的上下文窗口,或者是引入不相关的信息,导致检索效果变差。
- 固定大小分块: 按字符数或 Token 数固定长度切割。
- 基于语义的分块: 依据文档的结构(如段落、章节、标题)或语义相关性进行切割。
- 重叠分块: 在相邻块之间保留一定重叠,以确保上下文的连贯性。
- 递归分块: 尝试多种分块策略,直到块大小合适。
向量化
向量化就是将文本转化为数值向量(embendings),以便进行语义相似性搜索。这时需要选择一个合适的 embeding 模型,将每个文本转化为一个高维的向量。

向量数据存储
向量生成后,需要进行存储,以便于后续的持久化,以支持高效的相似性搜索。
- 选择向量数据库: 选择合适的向量数据库
- 索引构建: 将所有文本块的向量数据以及其对应的元数据(如文档 ID、页码、标题等)存储到向量数据库中,并构建索引以加快检索速度。
查询处理与检索
当用户提出问题时,需要从向量数据库检索出最相关的文本块。
- 将用户的问题(Query)也使用与文档分块时相同的 Embedding 模型进行向量化。
- 在向量数据库中执行向量的相似性搜索(余弦相似性、内积),找到与用户问题最接近的 K 个(top-k)文档块
- 按照一些元数据(文档类型、日期)进行过滤,重排序,确保返回的信息是最相关的
响应生成
- 将检索到的相关文档块(作为上下文)与用户的原始问题一起,构造一个包含指令和上下文的完整 Prompt
- 将构建好的 Prompt 发送给预训练的 LLM(如 GPT 系列、Claude、Llama 等)
- LLM 根据其自身的知识以及提供的上下文信息,生成自然语言的回答
RAG 的分类
https://milvus.io/docs/how_to_enhance_your_rag.md
-
基础 RAG (Naive/Basic RAG):
- 特点: 最简单的 RAG 实现。将原始文档分块、嵌入并存储在向量数据库中。查询时,直接检索 top-K 相似块,然后拼接到 LLM 的 Prompt 中进行生成。
- 局限性: 可能会遇到检索不精确、上下文丢失、长文本无法有效处理、幻觉仍存等问题。
- 适用场景: 对准确性要求不是特别高、文档内容相对简单、数据量不大的初期验证或个人项目。
-
高级 RAG (Advanced RAG):
- 特点: 在基础 RAG 的基础上,引入各种优化技术,以提高检索的精确度、上下文利用率和生成质量。
- 常见技术:
- 查询转换/重写 (Query Transformation/Rewriting): 利用 LLM 对用户查询进行改写、扩展或分解,使其更利于检索。例如,将模糊查询转换为具体关键词、生成子问题。
- 检索增强 (Improved Retrieval):
- 混合检索 (Hybrid Search): 结合向量搜索(语义相似性)和关键词搜索(BM 25、TF-IDF),弥补单一检索方式的不足。
- 重排序 (Re-ranking): 在检索出初步结果后,使用更精细的模型(如 Cross-Encoder)对结果进行二次排序,进一步提升相关性。
- 多粒度检索 (Multi-granularity Retrieval): 存储不同粒度的信息(如文档摘要、章节、段落、句子),根据查询类型检索不同粒度的内容。
- 子文档检索 (Sub-document Retrieval): 检索更小的块,但在生成时提供更大范围的上下文。
- 知识图谱增强检索 (Knowledge Graph Enhanced Retrieval): 将非结构化文本转化为结构化的知识图谱,通过图谱推理来获取更精确的上下文。
- 生成增强 (Improved Generation):
- 上下文压缩/填充 (Context Compression/Padding): 优化 LLM 输入的上下文,去除冗余,或通过 LLM 本身提取更精炼的上下文。
- 指令微调 (Instruction Tuning): 对 LLM 进行微调,使其更好地理解和利用检索到的上下文。
- 多跳推理 (Multi-hop Reasoning): 通过链式检索和生成,逐步解决复杂问题。
-
适用场景: 对准确性、效率、鲁棒性有更高要求的生产环境应用,如企业知识问答、智能客服、金融风控等。