Skip to content

RAG 技术详解:向量检索与混合搜索

本文是高级 Prompting 与推理增强的延伸阅读,详细讲解 RAG 背后的技术原理。

向量嵌入(Vector Embedding)

向量嵌入是 RAG 的基础。它的作用是把文本转换成一组数字(向量),使得语义相近的文本在向量空间中距离也近。

比如:

  • "怎么退货" → [0.23, -0.45, 0.87, ...]
  • "退款流程是什么" → [0.21, -0.42, 0.85, ...]
  • "今天天气真好" → [-0.67, 0.12, -0.33, ...]

前两个句子在向量空间里很接近(因为语义相似),第三个句子距离很远(因为语义不同)。

常见的 Embedding 模型:

  • OpenAI text-embedding-3-small / 3-large:商业模型,效果好,按 Token 计费。
  • Cohere embed-v3:支持多语言,中文效果好。
  • BGE 系列(BAAI):开源模型,中文效果优秀,可以本地部署。
  • Jina Embeddings:开源,支持超长文本。

选择 Embedding 模型时要考虑:维度大小(影响存储和检索速度)、多语言支持、最大文本长度。

文档分块(Chunking)

把长文档直接转换成一个向量,效果通常不好。更好的做法是切成小块,每块独立转换。

常见的分块策略:

  • 固定长度分块:每 500 个字一块,重叠 50 个字。简单但粗暴。
  • 按段落分块:每个段落一块。保留了自然边界,但块大小不均匀。
  • 按语义分块:用模型判断文本的语义边界,在合适的位置切分。效果最好,但计算成本高。
  • 递归分块:先按大块切,如果某块太长,再按更小的单位切。LangChain 的 RecursiveCharacterTextSplitter 就是这个思路。

重叠(Overlap)很重要。如果两个块之间没有重叠,一个完整的概念可能被切成两半,每半都不完整。通常重叠 10-20% 的块长度。

向量索引:HNSW

当向量数据库里有几百万甚至几亿个向量时,逐一比较相似度太慢。HNSW(Hierarchical Navigable Small World)是最常用的近似最近邻(ANN)索引算法。

HNSW 的核心思想是"多层跳表":

  • 最底层包含所有向量。
  • 往上每一层包含越来越少的向量,但连接跨度越来越大。
  • 检索时从最顶层开始,快速定位到大致区域,然后逐层往下精确查找。

这就像找人:先在世界地图上定位到国家,再定位到城市,再定位到街道,最后找到门牌号。比从头到尾遍历所有地址快得多。

HNSW 的参数:

  • M:每个节点的连接数。M 越大,检索越精确,但占用内存越多。
  • ef_construction:构建索引时的搜索范围。越大索引质量越高,但构建越慢。
  • ef_search:查询时的搜索范围。越大检索越精确,但查询越慢。

常见的向量数据库:

  • Chroma:轻量级,适合本地开发和小规模应用。
  • FAISS(Meta):高性能,适合大规模向量检索,但需要自己管理持久化。
  • Pinecone:云服务,开箱即用,适合不想自己运维的场景。
  • Weaviate:支持混合搜索(向量 + 关键词),功能丰富。
  • Qdrant:Rust 实现,性能好,支持过滤和多向量。

稠密索引 vs 稀疏索引

向量检索有两种主要方式:

稠密索引(Dense Index)

就是上面讲的 Embedding + 向量相似度搜索。每个文档块被压缩成一个固定维度的向量,检索时计算向量之间的余弦相似度。

优点:能捕捉语义,"退货"和"退款"能互相找到。

缺点:对精确匹配不擅长。如果用户搜索一个具体的型号"iPhone 15 Pro Max",稠密检索可能返回"手机推荐"这种泛泛的结果。

稀疏索引(Sparse Index)

传统的关键词搜索,比如 BM25 算法。每个文档被表示为一个高维稀疏向量(大部分维度是 0),每个维度对应一个词。

优点:精确匹配效果好。搜索"iPhone 15 Pro Max"就是会找到包含这个词的文档。

缺点:不理解语义。"退货"找不到"退款",因为它们是不同的词。

为什么需要两种?

实际场景中,用户的查询有时需要语义理解("怎么把东西退回去"),有时需要精确匹配("订单号 12345 的状态")。单一索引很难同时满足。

混合搜索与 RRF

混合搜索(Hybrid Search)把稠密检索和稀疏检索的结果合并起来,取长补短。

最常用的合并策略是 RRF(Reciprocal Rank Fusion)。它的原理很简单:

  1. 分别用稠密检索和稀疏检索,各返回一个排序列表。
  2. 对每个文档,计算它在两个列表中的排名。
  3. 用一个公式合并排名:RRF_score = 1/(k + rank_dense) + 1/(k + rank_sparse),其中 k 通常取 60。
  4. 按合并后的分数重新排序。

举个例子:

文档稠密排名稀疏排名RRF 分数
文档 A151/61 + 1/65 = 0.0318
文档 B311/63 + 1/61 = 0.0323
文档 C281/62 + 1/68 = 0.0309

文档 B 虽然在稠密检索中排名不高,但因为在稀疏检索中排名第一,合并后总分最高。

RRF 的好处是不需要调权重。它只看排名,不看具体的相似度分数,所以两种检索的分数尺度不同也不影响结果。

RAG 的实际部署考量

检索数量(Top-K)

检索多少个文档块给模型?太少可能遗漏关键信息,太多会浪费 Token 且引入噪声。通常 3-10 个是常见范围,具体取决于文档块的大小和模型的上下文窗口。

重排序(Reranking)

先用向量检索拿到 Top-20 个候选,再用一个更精确的模型(比如 Cohere Reranker、BGE Reranker)重新排序,取 Top-5 给模型。这一步能显著提升检索质量。

上下文拼接

检索到的文档块怎么拼到 Prompt 里?常见做法:

  • 按相关度排序,最相关的放在最前面。
  • 每个块加上来源标注(文档名、页码),方便引用和追溯。
  • 如果总长度超出限制,优先保留相关度最高的。

评估指标

怎么衡量 RAG 系统的效果?

  • 检索精度(Precision@K):Top-K 个结果中有多少是真正相关的。
  • 检索召回(Recall@K):所有相关文档中有多少被检索到了。
  • 回答质量:最终回答是否准确、完整、有依据。可以用人工评估或 LLM-as-Judge。

小结

  • 向量嵌入把文本变成数字,让语义相似的文本在向量空间中距离近。
  • 文档分块是 RAG 的关键预处理步骤,分块策略直接影响检索质量。
  • HNSW 是最常用的向量索引算法,用"多层跳表"加速检索。
  • 稠密索引擅长语义理解,稀疏索引擅长精确匹配,两者互补。
  • RRF 是最常用的混合搜索合并策略,简单且不需要调权重。
  • 实际部署时,重排序、检索数量、上下文拼接都会影响最终效果。

CC-BY 4.0 Licensed