Skip to content

RAG 检索优化:pgvector 双层检索加 Rerank

日期

2026-04-15

概述

和飞哥聊了他们的 RAG 知识库架构,用的是 pgvector 加 SQL 双层检索。聊了元数据提取策略、混合检索、以及 Rerank 的必要性。记录一下关键技术点。

双层检索架构

pgvector 加 SQL 混合检索是生产级 RAG 的常见做法,架构如下:

用户 Query

┌─────────────────┐
│ SQL 结构化过滤  │  先用风格/预算/元素筛候选集
│ WHERE metadata->>'风格' = '现代简约'
└────────┬────────┘
         ↕ (候选集)
┌─────────────────┐
│ PGVector 向量检索 │  在候选集内做向量相似度 Top-K
│ ORDER BY embedding <=> $vec
└────────┬────────┘

       返回结果

这种先过滤再检索的方式可以避免全表向量扫描,性能好很多。

PGVector 实现

sql
-- 先过滤再向量检索(推荐)
SELECT id, content, metadata,
       1 - (embedding <=> $query_vector) as similarity
FROM documents
WHERE metadata->>'风格' = '现代简约'
  AND metadata->>'预算' = '舒适型'
ORDER BY embedding <=> $query_vector
LIMIT 10;

HNSW 索引要建在候选集范围内,否则过滤条件带不动。

元数据提取

元数据分两个层面:

文档级:文件名、文件类型、页数、来源路径,入库时直接提取。

内容级:分块时附加章节标题、页码、业务字段。飞哥特别关注三个字段:风格、预算、元素。提取策略是用关键词匹配:

python
style_keywords = {
    "现代简约": ["现代简约", "简约", "北欧", "muji"],
    "中式": ["中式", "新中式", "传统中式"],
    "欧式": ["欧式", "法式", "地中海"],
}

这套策略在分块时自动给每个 chunk 打标,后续检索直接用 SQL 过滤就行。

Rerank 要不要做

需要,但可以简化。 Top-10 做 Rerank 开销很小(几十ms),收益明显。

模型特点
BGE-Reranker(推荐)阿里开源,中文效果好
Cohere Rerank商业 API,效果好但有成本

两阶段检索流程:Query → 向量检索(Top 20-50)→ Rerank → Top-K → LLM 生成。

10条做 Rerank 基本没负担,建议加上。