深入理解 RAG 技术:从语义张量到向量数据库,Milvus 与 FAISS 全面对比

🍊一篇面向工程师的技术深度文章,带你从原理到实践,彻底搞懂检索增强生成(RAG)的技术栈。


目录

  1. [什么是 RAG?](#什么是 RAG?)
  2. [Embedding 模型与语义张量](#Embedding 模型与语义张量)
  3. 向量数据库全景
  4. 主流向量数据库工具一览
  5. [Milvus vs FAISS:深度对比](#Milvus vs FAISS:深度对比)
  6. 选型建议与实践
  7. 总结

1. 什么是 RAG?

1.1 背景:大语言模型的局限

大语言模型(LLM)虽然强大,但存在三个核心短板:

  • 知识截止日期:模型训练数据有固定的时间窗口,无法感知训练之后发生的事件。
  • 幻觉问题:当模型被问到它不掌握的事实,它可能"编造"一个听起来合理但完全错误的答案。
  • 私有知识盲区:企业内部文档、专有数据、个人知识库,模型从未见过。

1.2 RAG 的核心思想

RAG(Retrieval-Augmented Generation,检索增强生成) 正是为了解决上述问题而生的架构范式。它的工作流程可以概括为三步:

复制代码
用户提问 → 检索相关知识 → 将知识注入 Prompt → LLM 生成回答

具体来说:

  1. 离线阶段(索引构建):将你的文档库切分成小块(Chunk),通过 Embedding 模型将每个 Chunk 转换为高维向量,存入向量数据库。

  2. 在线阶段(检索 + 生成):用户提问后,同样用 Embedding 模型将问题转为向量,在向量数据库中做近似最近邻(ANN)搜索,召回最相关的 Top-K 个文档片段。

  3. 增强生成:将这些片段作为上下文拼接到 Prompt 中,让 LLM 基于"外部检索到的知识"来回答问题,而非仅凭模型参数中记忆的知识。

    ┌─────────────────────────────────────────────────────────────────┐
    │ RAG 架构全景 │
    ├─────────────────────────────────────────────────────────────────┤
    │ │
    │ ┌──────────┐ ┌──────────────┐ ┌──────────────────────┐ │
    │ │ 文档库 │───▶│ Chunk 拆分 │───▶│ Embedding 模型编码 │ │
    │ └──────────┘ └──────────────┘ └────────┬─────────────┘ │
    │ │ │
    │ ┌───────▼──────────┐ │
    │ │ 向量数据库 │ │
    │ │ (Milvus/FAISS) │ │
    │ └───────┬──────────┘ │
    │ │ │
    │ 用户提问 ──▶ Embedding 编码 ──▶ ANN 检索 ───┘ │
    │ │ │
    │ ┌───────▼──────────┐ │
    │ │ Top-K 文档片段 │ │
    │ └───────┬──────────┘ │
    │ │ │
    │ ┌─────────────────────────┘ │
    │ ▼ │
    │ ┌────────────────┐ │
    │ │ 拼接 Prompt │ │
    │ │ + LLM 生成回答 │ │
    │ └────────────────┘ │
    └─────────────────────────────────────────────────────────────────┘

1.3 RAG 相比微调的优势

维度 RAG 微调(Fine-tuning)
知识更新 实时,更新数据库即可 需要重新训练
可解释性 可追溯引用来源 黑盒,难以溯源
幻觉控制 显著降低 可能学会"更好的编造"
实施成本 低,无需 GPU 训练 高,需要大量标注数据和算力
适用场景 知识库问答、文档检索 风格迁移、特定格式输出

2. Embedding 模型与语义张量

2.1 什么是 Embedding?

Embedding 是将非结构化数据(文本、图片、音频)映射到一个固定维度稠密向量空间的技术。这个向量空间的魔力在于:语义相近的内容,在向量空间中的距离也近

比如:

  • "苹果很好吃" → [0.12, -0.34, 0.87, ..., 0.05](768 维)
  • "这个水果很甜" → [0.11, -0.32, 0.85, ..., 0.07](768 维)

两句含义相近的话,它们的向量在高维空间中彼此靠近(余弦相似度接近 1)。

2.2 语义张量的本质

"语义张量"(Semantic Tensor)这个表述强调的是 Embedding 的数学本质------它是一个 N 维实数张量,每一维都没有可解释的具体含义,但整体编码了输入内容的语义特征。

复制代码
文本: "What is vector search?"
Embedding 模型: text-embedding-3-large (OpenAI)
输出张量: [0.014, -0.023, 0.041, ..., -0.008]  ← 3072 维
           ↑
           每一维都是 float32,整体构成一个语义"指纹"

常见的 Embedding 维度与模型:

模型 维度 提供商
text-embedding-3-small 512 / 1536 OpenAI
text-embedding-3-large 256 / 1024 / 3072 OpenAI
bge-large-zh-v1.5 1024 BAAI(开源)
all-MiniLM-L6-v2 384 Sentence-Transformers
multilingual-e5-large 1024 Microsoft

2.3 相似度度量

向量检索的核心是计算向量之间的"距离"或"相似度"。三种主流度量方式:

  • 余弦相似度(Cosine Similarity)cos(θ) = (A·B) / (||A|| × ||B||),值域 -1, 1,越接近 1 越相似。最常用的文本相似度度量。
  • 欧氏距离(Euclidean Distance / L2)||A - B||₂,值域 [0, ∞),越小越相似。适合低维且归一化的向量。
  • 内积(Inner Product / IP)A·B,值越大越相似。在推荐系统中广泛使用。

3. 向量数据库全景

3.1 为什么需要专门的向量数据库?

你可能会问:传统数据库不能存向量吗?可以------但无法高效检索。

向量检索的核心操作是 ANN(Approximate Nearest Neighbor,近似最近邻搜索) :在百万、亿级向量中,以毫秒级找到与查询向量最相似的 K 个向量。这是在传统数据库中用 SQL ORDER BY distance LIMIT 10 无法做到的------对百万行做全表扫描计算余弦相似度,延迟会高到不可接受。

向量数据库通过 索引算法(如 HNSW、IVF、PQ)在精度与速度之间取得平衡,实现亚秒级检索。

3.2 核心索引算法

算法 原理 特点
Flat(暴力搜索) 遍历所有向量逐一计算距离 100% 精度,速度最慢
IVF(倒排文件) K-Means 聚类后只在最近几个簇中搜索 速度快,精度可调
HNSW(分层可导航小世界图) 多层图结构,逐层跳跃逼近目标 速度快、精度高,内存占用大
PQ(乘积量化) 将高维向量压缩为短编码 极大节省内存,精度略降
DiskANN 基于图的磁盘索引 适合超大规模、内存受限场景

4. 主流向量数据库工具一览

4.1 专用向量数据库

工具 定位 核心特点 适用规模
Milvus 云原生分布式向量数据库 存算分离、水平扩展、多索引支持 亿级~百亿级
Pinecone 全托管云服务 零运维、Serverless 任意规模
Weaviate 开源向量搜索引擎 GraphQL 接口、内置模块化 Pipeline 百万~亿级
Qdrant 高性能 Rust 向量数据库 丰富的过滤、分组、推荐 API 百万~十亿级
Chroma 轻量级 AI 原生数据库 极简 API、适合原型开发 十万~百万级

4.2 向量检索库

工具 定位 核心特点
FAISS Meta 开源的向量相似度搜索库 C++ 核心、GPU 加速、极致性能、纯库非数据库
Annoy Spotify 开源的 ANN 库 内存映射、只读索引、轻量
ScaNN Google 开源的 ANN 库 针对内积搜索优化、高召回率
HNSWlib 纯 HNSW 算法实现 极简标头库、速度极快

4.3 传统数据库的向量扩展

工具 向量能力
PostgreSQL + pgvector 在 SQL 中直接做向量检索,适合已有 PG 技术栈的团队
Elasticsearch 8.x 起支持向量检索,适合混合搜索(关键词 + 语义)
Redis Redis Stack 提供向量搜索模块
MongoDB Atlas Atlas Vector Search,托管方案

5. Milvus vs FAISS:深度对比

这是很多工程师在做技术选型时最关心的问题。先说结论:Milvus 是完整的数据库系统,FAISS 是高性能向量检索库------它们不是同一层面的竞品,而是解决不同层次的问题。

5.1 本质差异

复制代码
FAISS:  一个 C++ 库,提供向量索引构建和检索算法
         └── 类比:一个超高性能的"向量搜索引擎内核"

Milvus: 一个分布式云原生数据库系统
         └── 类比:一个完整的"向量数据管理平台"
对比维度 FAISS Milvus
类型 向量检索 (Library) 向量 数据库(Database)
开发者 Meta(Facebook AI Research) Zilliz(开源社区驱动)
首次发布 2017 2019
语言 C++(Python/Java 绑定) Go(核心)+ C++(索引引擎)
开源协议 MIT Apache 2.0

5.2 架构对比

FAISS 架构

FAISS 是典型的 库级架构------你在自己的进程里加载它,索引数据存于内存或本地磁盘。没有服务端、没有网络协议、没有持久化机制(需自己实现)。

复制代码
┌──────────────────────────────────┐
│          你的 Python 进程         │
│  ┌────────────────────────────┐  │
│  │        FAISS 库            │  │
│  │  ┌──────────────────────┐  │  │
│  │  │  Index (HNSW/IVF/...) │  │  │
│  │  │  全部在进程内存中      │  │  │
│  │  └──────────────────────┘  │  │
│  └────────────────────────────┘  │
└──────────────────────────────────┘

优点 :零网络开销,极致低延迟,GPU 加速直接可用。

缺点:单机内存瓶颈,索引需手动序列化/反序列化,无数据管理能力。

Milvus 架构

Milvus 是 存算分离的云原生架构,由多个微服务组成:

复制代码
┌─────────────────────────────────────────────────────────────────┐
│                        Milvus 架构                              │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐        │
│  │  Proxy   │  │  Query   │  │  Data    │  │  Index   │        │
│  │  (接入层) │  │  Node    │  │  Node    │  │  Node    │        │
│  └────┬─────┘  └────┬─────┘  └────┬─────┘  └────┬─────┘        │
│       │              │              │              │              │
│  ┌────┴──────────────┴──────────────┴──────────────┴────┐       │
│  │                  Message Queue (Pulsar/Kafka)         │       │
│  └──────────────────────────────────────────────────────┘       │
│       │              │              │              │              │
│  ┌────┴────┐    ┌────┴────┐   ┌────┴────┐    ┌────┴────┐       │
│  │  Etcd   │    │  MinIO  │   │  MinIO  │    │  MinIO  │       │
│  │ (元数据) │    │ (日志)   │   │ (数据)   │    │ (索引)   │       │
│  └─────────┘    └─────────┘   └─────────┘    └─────────┘       │
└─────────────────────────────────────────────────────────────────┘

优点 :水平扩展、高可用、数据持久化、多租户、SDK 丰富。

缺点:部署复杂度高,资源开销大,延迟比 FAISS 略高(网络 + 序列化开销)。

5.3 功能对比

功能 FAISS Milvus
向量索引 ✅ 极其丰富(30+ 种索引) ✅ 丰富(支持 HNSW、IVF、DiskANN 等)
GPU 加速 ✅ 原生支持,CUDA 实现 ⚠️ 有限支持,依赖底层 FAISS/Knowhere
数据持久化 ❌ 需手动实现 ✅ 自动持久化到 MinIO/S3
水平扩展 ❌ 单机 ✅ 分布式,支持动态扩缩容
CRUD 操作 ❌ 需重建索引 ✅ 支持插入、删除、更新
标量过滤 ⚠️ 需自行实现(如结合 IDSelector) ✅ 原生支持,可结合向量 + 标量条件
多租户 ✅ Partition Key / RBAC
数据一致性 ❌ 无保证 ✅ 可配置一致性级别
监控与运维 ❌ 无 ✅ Prometheus + Grafana 集成
SDK 语言 Python, C++ Python, Java, Go, Node.js, C#
云服务 ✅ Zilliz Cloud 全托管
社区生态 学术界 + 工业界广泛使用 快速增长,CNCF 毕业项目

5.4 性能对比

这里给出典型场景下的性能参考数据(基于公开 Benchmark):

场景 FAISS (HNSW) Milvus (HNSW)
Top-10 检索延迟 ~0.5 ms ~2-5 ms
QPS(单机) 10,000+ 5,000-8,000
QPS(分布式) N/A(单机) 100,000+(水平扩展)
最大向量数 受单机内存限制(通常 <1 亿) 百亿级(存算分离)
索引构建速度 快(纯内存) 中等(涉及 I/O)
召回率@10 95-99%(可调) 95-99%(可调)

关键洞察:FAISS 在单机场景下的原始性能无敌;但当你需要管理超过单机内存容量的数据、需要高可用、需要多用户访问时,Milvus 的优势就显现出来了。

5.5 代码示例对比

FAISS:构建索引与检索
python 复制代码
import faiss
import numpy as np

# 准备数据
dim = 768
data = np.random.random((100000, dim)).astype('float32')

# 构建 HNSW 索引
index = faiss.IndexHNSWFlat(dim, 32)    # 32 是 M 参数(连接数)
index.add(data)

# 检索
query = np.random.random((1, dim)).astype('float32')
distances, indices = index.search(query, k=10)

# 持久化(手动)
faiss.write_index(index, "index.faiss")
index = faiss.read_index("index.faiss")  # 加载
Milvus:构建索引与检索
python 复制代码
from pymilvus import MilvusClient, DataType

# 连接(支持集群)
client = MilvusClient(uri="http://localhost:19530")

# 创建 Collection(相当于表)
client.create_collection(
    collection_name="my_docs",
    dimension=768,
    metric_type="COSINE",
    auto_id=True,
)

# 插入数据
client.insert(
    collection_name="my_docs",
    data=[{"vector": vec.tolist(), "text": "..."} for vec in vectors],
)

# 创建索引
client.create_index(
    collection_name="my_docs",
    index_type="HNSW",
    metric_type="COSINE",
    params={"M": 16, "efConstruction": 200},
)

# 检索(支持标量过滤)
results = client.search(
    collection_name="my_docs",
    data=[query.tolist()],
    limit=10,
    filter='category == "tech"',     # Milvus 独有:标量过滤
    output_fields=["text", "url"],
)

5.6 何时选择 FAISS?

  • ✅ 研究、实验、原型阶段
  • ✅ 数据量在单机内存容量以内(百万~数千万级)
  • ✅ 对检索延迟要求极高(亚毫秒级)
  • ✅ 需要在 GPU 上做大规模向量检索
  • ✅ 你的应用是单进程、无需多租户
  • ✅ 你愿意自己实现持久化、CRUD、服务化等周边逻辑

5.7 何时选择 Milvus?

  • ✅ 生产环境的 RAG 系统
  • ✅ 数据量超单机内存(亿级以上)
  • ✅ 需要多用户、多团队共享
  • ✅ 需要数据持久化、高可用、灾难恢复
  • ✅ 需要混合搜索(向量相似度 + 标量过滤)
  • ✅ 不想自己造轮子,需要开箱即用的数据库功能
  • ✅ 团队更习惯 SQL/NoSQL 数据库的使用体验

6. 选型建议与实践

6.1 决策树

复制代码
数据量 < 500 万?
├── 是 → 直接用 FAISS 或 Chroma,简单高效
└── 否 → 是否需要持久化/多用户/高可用?
        ├── 否 → FAISS + 自定义服务化,或 Qdrant(轻量数据库)
        └── 是 → 需要分布式?
                ├── 否 → Milvus Standalone 或 Qdrant
                └── 是 → Milvus Cluster 或 Pinecone(全托管)

6.2 混合方案:Milvus + FAISS

有趣的是,Milvus 底层依赖 Knowhere------一个对 FAISS、HNSWlib、Annoy 等库的统一抽象层。也就是说,Milvus 在索引执行引擎层面实际上可以用 FAISS 的算法。所以你可以把 Milvus 理解为"加了数据库皮肤的 FAISS 生态"。

在某些极致性能要求的场景,还有一种混合架构:

复制代码
写入路径:Milvus(数据管理、持久化、高可用)
检索路径:FAISS(将热数据加载到 GPU FAISS 索引,亚毫秒检索)

6.3 从 RAG 原型到生产的最佳实践

  1. 原型阶段:Chroma + LangChain/LlamaIndex,快速跑通 RAG 链路。
  2. 小规模生产(<100 万向量):PostgreSQL + pgvector,复用现有数据库基础设施。
  3. 中大规模生产(100 万 ~ 10 亿向量):Milvus Standalone / Qdrant。
  4. 超大规模生产(10 亿+):Milvus Cluster / Zilliz Cloud / Pinecone。
  5. 极致性能场景:FAISS GPU + 自定义服务化封装。

7. 总结

RAG 正在成为大模型落地的标准范式,而向量数据库是这个范式中的关键基础设施。理解 Embedding 的语义张量本质、掌握 ANN 索引算法的取舍、选对向量数据库工具,是每个 AI 工程师的必修课。

最后用一句话总结 FAISS 与 Milvus 的关系:

FAISS 是你造车时的引擎,而 Milvus 是一辆可以直接上路的汽车。 如果你只需要一个高性能引擎嵌入到自己的系统中,选 FAISS;如果你需要一辆能载客、能上高速、有安全气囊的整车,选 Milvus。


如果这篇文章对你有帮助,欢迎分享给更多做 AI 应用的同学。也欢迎在评论区交流你的技术选型经验和踩坑记录!

相关推荐
爱吃羊的老虎1 小时前
【数据库】模块二:SQL 语句、高级特性与优化
数据库·oracle
Rain5091 小时前
2.4. PostgreSQL 数据库连接与实战指南
前端·数据库·人工智能·后端·postgresql·数据分析
爱喝水的鱼丶1 小时前
SAP-ABAP:SAP表与视图权限管控方案:表维护权限、视图访问权限配置实操
运维·数据库·性能优化·sap·abap·权限·表和视图
tomcoding1 小时前
深入解析Oracle数据块的内部结构
数据库·oracle
pixcarp11 小时前
知识库系统的内容资产闭环怎么设计
服务器·数据库·后端·golang
JosieBook11 小时前
【数据库】时序预测能力的分级进化:TimechoAI如何让每一类用户都能精准预见未来
java·开发语言·数据库
吴声子夜歌13 小时前
SQL经典实例——使用多张表
数据库·sql
倔强的石头_14 小时前
《Kingbase护城河》——深度解密数据库行锁冲突与等待事件架构
数据库
IT策士14 小时前
Redis 从入门到精通:性能调优与多语言客户端对比
数据库·redis·缓存