pgvector新版本向量检索评测

RAG 系统里,向量库不是越"专用"越好。

如果你的数据本来就在 PostgreSQL,pgvector 的新版本已经足够支撑相当一部分生产级向量检索场景 。

真正需要判断的是:你的规模、召回要求、过滤条件和运维能力,是否已经超出 PostgreSQL 的边界。

问题背景:为什么数据库开始承载向量检索

向量检索解决的是"语义相似"问题:把文本、图片、代码片段转换成向量,再通过近似最近邻搜索(Approximate Nearest Neighbor Search,ANN)找到语义接近的数据。

典型场景包括:

  • RAG(Retrieval-Augmented Generation,检索增强生成):从企业知识库中召回上下文,再交给大模型回答;
  • 智能客服:按语义匹配 FAQ、工单、产品文档;
  • 代码搜索:用自然语言查找函数、模块、提交记录;
  • 推荐与去重:查找相似商品、相似文章、相似用户行为。

传统数据库擅长结构化查询,向量数据库擅长相似度搜索。问题在于,AI 应用往往同时需要两者:

text 复制代码
找到"语义相似"的文档
同时要求:
- tenant_id = 当前租户
- status = published
- created_at 在某个范围
- 权限可见
- 按业务字段二次排序

这正是 PostgreSQL + pgvector 的价值:把向量检索和关系型过滤放在同一个事务与查询模型里。

pgvector 是 PostgreSQL 的向量扩展。较新的 pgvector 版本已经支持 HNSW、IVFFlat、vector、halfvec、bit、sparsevec 等类型,并能通过 SQL 完成索引创建、过滤、排序与召回。

核心概念:向量、距离函数与索引不是一回事

先把几个容易混淆的概念拆开。

向量类型:存什么

向量(Embedding)是模型输出的浮点数组。例如 OpenAI 兼容接口中常见的 embedding 模型会返回固定维度向量:

  • text-embedding-3-small:1536 维;
  • text-embedding-3-large:3072 维;
  • BGE、GTE、E5 等开源模型也有各自固定维度。

在 pgvector 中可以这样建表:

sql 复制代码
CREATE EXTENSION IF NOT EXISTS vector;

CREATE TABLE documents (
  id bigserial PRIMARY KEY,
  tenant_id text NOT NULL,
  title text NOT NULL,
  content text NOT NULL,
  embedding vector(1536), -- 维度必须和 embedding 模型输出一致
  created_at timestamptz DEFAULT now()
);

结论:向量维度是数据契约,不是可随便变更的字段。

机制上,索引构建、距离计算都依赖固定维度;如果你从 1536 维模型切到 3072 维模型,就不能直接复用旧字段和旧索引。

例证是 OpenAI 兼容 embedding 接口中,不同模型返回维度不同,混写到同一 vector(1536) 字段会直接失败。

距离函数:怎么判断"相似"

pgvector 常用距离操作符包括:

操作符 含义 常见用途
<-> L2 distance,欧氏距离 通用相似度
<#> negative inner product,负内积 内积越大越相似
<=> cosine distance,余弦距离 文本语义检索最常见
<+> L1 distance,曼哈顿距离 特定数值特征场景

文本 RAG 中通常优先使用余弦距离:

sql 复制代码
SELECT id, title, content
FROM documents
WHERE tenant_id = 'acme'
ORDER BY embedding <=> $1
LIMIT 5;

结论:距离函数要和 embedding 模型训练方式匹配。

机制上,模型训练时优化的相似性目标不同,检索阶段如果换了距离函数,排序会偏移。

例证是多数文本 embedding 模型会建议使用 cosine similarity 或 dot product;如果随意改成 L2,召回结果可能看似"能跑",但相关性下降。

索引:怎么让它快

没有索引时,数据库需要对候选行逐条计算距离,这是全表扫描。向量数据量上去后,查询延迟会迅速失控。

pgvector 主流 ANN 索引有两类:

索引 原理简述 优点 代价
HNSW 分层小世界图搜索 召回高、查询快、无需训练 建索引慢、内存占用高
IVFFlat 聚类后在部分簇中搜索 索引较轻、适合批量加载后构建 需要训练,参数敏感

HNSW 示例:

sql 复制代码
CREATE INDEX documents_embedding_hnsw_idx
ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (
  m = 16,
  ef_construction = 64
);

查询时可以调整搜索广度:

sql 复制代码
SET hnsw.ef_search = 80;

SELECT id, title
FROM documents
WHERE tenant_id = 'acme'
ORDER BY embedding <=> $1
LIMIT 5;

m 控制图中连接数,ef_construction 影响建索引质量,hnsw.ef_search 影响查询时探索候选数量。pgvector 文档中 hnsw.ef_search 默认值为 40,这是一个可验证的参数基线。

结论:HNSW 的核心不是"有索引就快",而是在召回率、延迟、内存之间做交换。

机制上,ef_search 越大,搜索图时访问的候选越多,召回通常越好,但延迟也会上升。

例证是在 RAG 场景中,LIMIT 5 不代表只检查 5 条,而是先探索候选,再返回最相似的 5 条。

关键机制:pgvector 新版本值得关注什么

pgvector 的价值不只在"PostgreSQL 能存向量",而在它逐渐补齐了向量检索工程化所需的机制。

机制一:关系过滤与向量排序可以合并

AI 应用很少只做纯向量检索。企业知识库必须按租户、权限、状态过滤,否则会出现数据越权。

sql 复制代码
SELECT id, title, content
FROM documents
WHERE tenant_id = $1
  AND status = 'published'
ORDER BY embedding <=> $2
LIMIT 8;

结论:pgvector 适合过滤条件强、数据治理要求高的 RAG 系统。

机制上,PostgreSQL 查询优化器可以把普通 B-tree 索引、条件过滤与向量排序组合执行。

例证是多租户知识库中,tenant_id、status、created_at 通常已经在 PostgreSQL 中维护,pgvector 不需要额外同步一套权限模型。

但边界也很明确:如果过滤后候选集太小,ANN 索引未必能稳定返回足够结果;如果过滤条件太复杂,也可能导致执行计划不如预期,需要通过 EXPLAIN ANALYZE 验证。

机制二:向量检索需要召回评测,而不是只看延迟

很多团队做 RAG 只测接口耗时,不测召回质量,这是常见失败原因。

推荐建立一个小型评测集:

text 复制代码
query: "如何重置管理员密码"
expected_doc_ids: [12, 38, 41]

query: "发票抬头在哪里修改"
expected_doc_ids: [77, 81]

然后比较不同参数下的 Recall@K:

配置 示例延迟 Recall@5 示例 适用判断
无索引精确搜索 高 1.00 小数据、离线评测
HNSW ef_search=40 低 0.88 示例 默认起点
HNSW ef_search=100 中 0.94 示例 质量优先
IVFFlat lists=100 低 依赖数据分布 大批量静态数据

表中的延迟和召回是"示例",真实结果取决于数据量、维度、硬件、过滤条件和模型。

结论:向量检索调参的目标是业务召回,不是单点 QPS。

机制上,ANN 本质是近似搜索,会牺牲一部分精确性换取速度。

例证是客服 RAG 中,如果 top 5 没召回正确文档,后面的大模型再强也只能基于错误上下文生成答案。

机制三:LangChain 集成降低接入成本,但不能替代数据建模

下面是一个 LangChain + OpenAI 兼容接口 + pgvector 的示例。依赖可按以下版本口径安装:

bash 复制代码
pip install langchain==0.3.7 \
  langchain-openai==0.2.8 \
  langchain-postgres==0.0.12 \
  psycopg[binary]==3.2.3

示例代码:

python 复制代码
from langchain_openai import OpenAIEmbeddings
from langchain_postgres import PGVector
from langchain_core.documents import Document

# OpenAI 兼容接口:可替换为支持 /v1/embeddings 的网关或私有模型服务
embeddings = OpenAIEmbeddings(
    model="text-embedding-3-small",
    base_url="https://api.example.com/v1",
    api_key="YOUR_API_KEY",
)

connection = "postgresql+psycopg://app:password@localhost:5432/rag"

vector_store = PGVector(
    embeddings=embeddings,
    collection_name="kb_docs",
    connection=connection,
    use_jsonb=True,  # 元数据使用 JSONB,便于 PostgreSQL 过滤
)

docs = [
    Document(
        page_content="管理员可以在安全设置中重置密码。",
        metadata={"tenant_id": "acme", "status": "published"},
    )
]

vector_store.add_documents(docs)

retriever = vector_store.as_retriever(
    search_kwargs={
        "k": 5,
        "filter": {"tenant_id": "acme", "status": "published"},
    }
)

results = retriever.invoke("管理员密码忘了怎么办")

结论:LangChain 适合快速打通链路,但生产系统仍要理解底层表结构、索引和过滤语义。

机制上,框架只是把 embedding、入库、查询封装起来,真正影响召回和延迟的是 PostgreSQL 的执行计划与 pgvector 索引参数。

例证是同样的 k=5,如果没有为向量列创建 HNSW 索引,数据量增加后查询可能退化为顺序扫描。

工程实践与选型:pgvector、Milvus、Elasticsearch 怎么选

方案 适合场景 优势 不适合场景
PostgreSQL + pgvector 数据已在 PostgreSQL,中小规模 RAG,强过滤,多租户 事务一致、SQL 统一、运维简单 超大规模向量、极致吞吐、复杂向量集群
Milvus 2.x 大规模向量检索,独立向量平台 索引类型多、分布式能力强 需要额外运维与数据同步
Elasticsearch 8.x 文本检索 + 向量混合检索 BM25、过滤、聚合成熟 事务模型弱于关系库,向量能力不是唯一核心
Redis Stack 低延迟、小规模在线检索 内存速度快,接入简单 成本随内存增长明显,持久化与复杂查询有限

明确结论:

  • 优先选 pgvector:业务主数据在 PostgreSQL,向量规模在百万到千万级以内,过滤条件强,团队不想维护独立向量集群。
  • 优先选 Milvus:向量规模持续扩大,检索是核心业务,召回延迟和吞吐需要独立扩展。
  • 考虑 Elasticsearch:你需要 BM25、关键词、高亮、聚合和向量混合检索。
  • 谨慎用内存型方案承载长期知识库:除非数据规模和成本都可控。

常见误区:只建向量索引,不建业务过滤索引

一个真实常见的坑是:团队只给 embedding 建了 HNSW 索引,却没有给 tenant_id、status、created_at 建普通索引。

触发条件:

sql 复制代码
WHERE tenant_id = 'acme'
  AND status = 'published'
ORDER BY embedding <=> $1
LIMIT 5;

现象:

  • 单租户测试很快,上多租户后变慢;
  • EXPLAIN ANALYZE 显示过滤掉大量行;
  • topK 偶尔不足,需要增大 ef_search 才能缓解。

规避方式:

sql 复制代码
CREATE INDEX documents_tenant_status_idx
ON documents (tenant_id, status);

CREATE INDEX documents_created_at_idx
ON documents (created_at);

同时把召回逻辑拆成两层评估:

  1. 过滤后候选集是否足够大;
  2. ANN 参数是否能在候选集中稳定返回相关文档。

结论:向量索引解决相似度搜索,不自动解决业务过滤。

机制上,ANN 索引和 B-tree 索引服务于不同访问路径。

例证是权限过滤越复杂,越需要用执行计划验证,而不是假设数据库一定会"智能优化"。

知识地图:如何系统掌握 pgvector 向量检索

建议按这个顺序学习和实践:

  1. 先学 embedding 基础

    理解维度、归一化、余弦距离、内积、chunk 粒度。动手比较 text-embedding-3-small 与一个开源 embedding 模型的召回差异。

  2. 再学 PostgreSQL 查询与索引

    掌握 EXPLAIN ANALYZE、B-tree、GIN、JSONB、事务隔离。pgvector 的工程效果很大程度取决于 PostgreSQL 基础。

  3. 然后学 pgvector 索引参数

    对比 HNSW 与 IVFFlat,记录 ef_search、m、ef_construction、lists、probes 对延迟和召回的影响。

  4. 最后搭建 RAG 评测闭环

    用 LangChain 接入 OpenAI 兼容接口,但不要停在 demo。至少建立 50 到 200 条人工标注 query-doc 对,用 Recall@K 和答案准确率评估。

进阶资料可以重点看三类:

  • pgvector 官方文档:类型、操作符、索引参数;
  • PostgreSQL 查询优化资料:执行计划、统计信息、索引选择;
  • RAG 评测资料:Recall@K、MRR、上下文压缩、混合检索。

总结

pgvector 的新版本让 PostgreSQL 不再只是"能存向量",而是能在不少 RAG 场景中承担完整的向量检索链路。

它的最佳位置不是替代所有专业向量数据库,而是在强过滤、强一致、低运维复杂度的工程场景中提供更简单的落地路径。

如果你的知识库已经在 PostgreSQL,你会优先把向量检索放进数据库,还是一开始就拆出独立向量库?

相关推荐
梦里寻码2 小时前
从 0 到 1 用 NestJS + LangChain 搭一套可售卖的 SaaS AI 客服:挂件一行代码接入,知识库秒变 SEO 帮助中心
前端·后端·github
mmsx2 小时前
Android 流式对话实现:分层门面与 SSE 手工解析
android·github·sse
lpfasd1233 小时前
2026年第41周GitHub趋势周报:Agent进入技能化与记忆工程阶段
github
怕浪猫3 小时前
给AI配一台电脑,开源版Muse来了,OpenMuse赶紧去二次开发吧
javascript·面试·github
miofly4 小时前
GitHub 日榜趋势速报 | 2026-10-14
开源·github
高频因子挖掘机4 小时前
量化回测为什么不能随便选前复权?从收益率计算到成交价格的三个误区
后端·github·api
高频因子挖掘机6 小时前
回测收益为什么可能不真实?从时间戳、数据可用性到未来函数检查
后端·github·api
风娜8 小时前
IT 疑难杂症诊疗室:从现象到根因的系统排查方法论
人工智能·github