稠密检索 vs 稀疏检索:基于向量区分现代搜索技术Mike Hindle / Unsplash

Essay

稠密检索 vs 稀疏检索:基于向量区分现代搜索技术#

By Asuka

在构建 RAG(检索增强生成)系统或任何智能搜索应用时,检索策略的选择至关重要。目前主流的检索方法分为两大类:稀疏检索稠密检索

稀疏检索(Sparse Retrieval)#

稀疏检索基于关键词匹配,使用高维稀疏向量表示文档。

以查询"如何训练神经网络"为例,稀疏检索会将其转换为词袋表示:

Auto
[如何:1, 训练:1, 神经:1, 网络:1, 其他词:0, 0, 0, ...]

大量维度为 0,因此称为"稀疏"。

下面的伪代码展示了稀疏向量的构建过程:

TypeScript
// 假设词汇表包含 10000 个词
const vocabulary = ["的", "是", "在", ..., "如何", "训练", "神经", "网络", ...]; // 共 10000 词

function toSparseVector(text: string): number[] {
  // 初始化全零向量,维度 = 词汇表大小
  const vector = new Array(vocabulary.length).fill(0); // [0, 0, 0, ..., 0] 共 10000 维

  // 分词
  const tokens = tokenize(text); // ["如何", "训练", "神经", "网络"]

  // 统计词频,在对应位置填入非零值
  for (const token of tokens) {
    const index = vocabulary.indexOf(token);
    if (index !== -1) {
      vector[index] += 1; // 或使用 TF-IDF 权重
    }
  }

  return vector;
}

// 结果示意(假设 "如何" 在位置 4521,"训练" 在 7823...)
// [0, 0, 0, ..., 1, ..., 0, 0, 1, ..., 0]
//                ↑ 位置 4521    ↑ 位置 7823
// 10000 维中只有 4 个非零值,极度稀疏

典型算法:BM25(TF-IDF 的改进版,目前最常用)、TF-IDF(词频-逆文档频率)。

优缺点:优点是速度快、可解释、精确匹配效果好、不需要训练;缺点是无法理解语义,"汽车"和"轿车"匹配不上,依赖关键词重叠。

稠密检索(Dense Retrieval)#

稠密检索使用神经网络将文本编码为低维稠密向量(embedding),通过向量相似度匹配。

同样以"如何训练神经网络"为例,Embedding 模型会将其转换为稠密向量:

Auto
[0.23, -0.45, 0.67, 0.12, ...]  // 通常 384-1536 维

每个维度都有值,因此称为"稠密"。

典型模型:OpenAI text-embedding-3、BGE / M3E(中文优化)、Sentence-BERT。

优缺点:优点是理解语义相似性,"汽车"≈"轿车"能匹配,具备跨语言能力;缺点是需要 GPU 计算 embedding,向量存储成本高,对专业术语可能不敏感。

两种方法的对比#

TypeScript
// 查询
const query = "深度学习入门教程";

// 文档库
const doc1 = "神经网络基础教学";      // 语义相关,关键词不重叠
const doc2 = "深度学习的历史发展";    // 关键词重叠,但不是教程
  • 稀疏检索(BM25):doc_2 排名高,doc_1 排名低。
  • 稠密检索(Embedding):doc_1 排名高,doc_2 排名中。

稀疏检索会因为"深度学习"这个关键词匹配而将 doc_2 排在前面,而稠密检索能理解"神经网络基础教学"和"深度学习入门教程"在语义上更相关。

实际系统通常结合两者以获得最佳效果:

TypeScript
function hybridSearch(query: string, documents: string[]): SearchResult[] {
  // 稀疏检索 - 精确关键词匹配
  const sparseScores = bm25Search(query, documents);

  // 稠密检索 - 语义相似度
  const denseScores = embeddingSearch(query, documents);

  // 融合分数(常用 RRF - Reciprocal Rank Fusion)
  const finalScores = sparseScores.map((s, i) => alpha * s + (1 - alpha) * denseScores[i]);

  return rankByScore(documents, finalScores);
}

为什么要混合? 两种方法各有擅长的场景:稀疏检索擅长专有名词、精确匹配(如"iPhone 15 Pro Max");稠密检索擅长语义理解、同义词匹配(如"便宜的手机"≈"性价比高的手机")。两者互补,效果最佳。Perplexity、Google 等现代搜索系统普遍采用混合检索策略。

技术演进#

稠密检索的大规模应用经历了几个关键阶段:

  • 2017:FAISS 开源(高效向量搜索)。
  • 2019:BERT 应用于 Google 搜索。
  • 2019-2020:向量数据库生态兴起(Pinecone、Milvus、Weaviate)。
  • 2020:DPR 论文(Dense Passage Retrieval)的学术突破;RAG 论文(Facebook)带来检索 + 生成的范式。
  • 2021:向量数据库生态成熟。
  • 2022+:RAG 成为主流架构。

实现建议#

选择稀疏检索:资源有限无法运行 embedding 模型、查询主要是精确匹配(产品型号、专有名词)、需要高度可解释的结果。

选择稠密检索:用户查询多为自然语言问题、需要跨语言或同义词匹配、有足够的计算资源。

选择混合检索:生产级应用需要最佳检索质量、查询类型多样难以预测、可以承担额外的系统复杂度。