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 基本没负担,建议加上。