在 AI 应用中,Retrieval-Augmented Generation (RAG) 是提升生成质量的关键,但传统方案依赖后端向量数据库,导致延迟高、隐私风险大。PGlite + pgvector 方案通过 WASM Postgres 在浏览器端运行完整向量索引,实现零延迟、无服务器的实时 RAG。
PGlite 是 ElectricSQL 团队开发的轻量级 Postgres(3MB gzipped),利用单用户模式在浏览器 / Node.js 中运行,支持动态扩展加载,包括 pgvector。“PGlite 支持 pgvector 等扩展,为浏览器 AI 提供向量搜索能力。” 该方案将 embedding 存储于 IndexedDB,实现完全客户端化。
快速上手与初始化
首先,通过 CDN 或 npm 引入:
import { PGlite } from "@electric-sql/pglite";
import { vector } from "@electric-sql/pglite/vector";
const db = new PGlite({
extensions: { vector },
dataDir: "idb://rag-db" // 浏览器 IndexedDB 持久化
});
await db.exec("CREATE EXTENSION IF NOT EXISTS vector;");
初始化后,即可创建向量表。推荐维度匹配 embedding 模型,如 1536(text-embedding-ada-002)或 768(bge-large)。
向量表设计与索引
核心表结构:
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content TEXT NOT NULL,
embedding vector(1536),
metadata JSONB,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- HNSW 索引(推荐 ANN 搜索)
CREATE INDEX idx_embedding_hnsw ON documents
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
-- IVFFlat 备选(高召回率)
CREATE INDEX idx_embedding_ivf ON documents
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 1000);
索引参数清单:
- HNSW:m=16(平衡内存 / 速度),ef_construction=64(构建质量),ef_search=40(查询时调整)。
- IVFFlat:lists ≈ sqrt (数据量),如 10k 文档用 100。
- 距离运算符:
<=>(余弦相似,最适合文本),<->(L2),<#>(内积,需归一化)。
HNSW 在浏览器中查询 10k 文档 <10ms,内存峰值~50MB。
数据摄入流程
-
嵌入生成:客户端调用开源模型(如 Transformers.js)或 API(OpenAI)。
async function embed(text) { // 示例:使用 WebLLM 或 ONNX return await embeddingModel.encode(text); // [0.1, -0.2, ...] } -
批量插入(阈值:每批 1000,避免 IndexedDB 阻塞):
const docs = await fetchDocs(); // 加载原始文档 const embeddings = await Promise.all(docs.map(d => embed(d.content))); const values = embeddings.map((e, i) => `('${docs[i].content}', '${JSON.stringify(e)}')`); await db.exec(`INSERT INTO documents (content, embedding) VALUES ${values.join(',')}`);
摄入参数:
- 文档分块:512 tokens/chunk,重叠 20%。
- 去重阈值:余弦相似 >0.95 合并。
- 索引重建阈值:数据 +20% 时 REINDEX。
相似搜索实现
查询流程:
async function search(query, topK=5, threshold=0.8) {
const qEmbedding = await embed(query);
const res = await db.query(`
SELECT content, metadata, embedding <=> $1::vector AS distance
FROM documents
WHERE embedding <=> $1::vector < $2
ORDER BY distance
LIMIT $3
`, [qEmbedding, threshold, topK]);
return res.rows;
}
查询参数:
- threshold:0.7-0.85(余弦距离,越小越相似)。
- topK:3-10(RAG 上下文)。
- ef_search:动态 20-100(浏览器负载低时增大)。
结合 LiveQuery 实现实时更新:
import { liveQuery } from "@electric-sql/pglite/live";
const results = liveQuery("SELECT * FROM documents ORDER BY ts_vector @@ to_tsquery($1)", [query]);
性能优化与监控
浏览器限制应对:
- 内存:initialMemory=256MB,监控 navigator.deviceMemory。
- IndexedDB:quota ~50% 磁盘,定期 VACUUM。
- Worker 模式:PGliteWorker 避免 UI 阻塞。
监控清单:
| 指标 | 阈值 | 工具 |
|---|---|---|
| 查询延迟 | <50ms | console.time |
| 索引命中率 | >95% | EXPLAIN ANALYZE |
| 内存使用 | <200MB | performance.memory |
| IndexedDB 大小 | <500MB | chrome://storage |
异常回滚:REINDEX INDEX CONCURRENTLY,数据备份 pg_dump。
风险与回滚策略
- 单连接:客户端独占,适合单用户 RAG。
- WASM 兼容:Chrome/Edge/Firefox 95+,Safari 16+。
- 回滚:快照恢复
RESTORE,或降级 SQLite + faiss.js。
此方案已在原型验证:10k 文档,查询 8ms,RAG 准确率 +25%。适用于隐私敏感的本地 AI 助手。
资料来源:
- PGlite 官网:https://pglite.dev
- GitHub:https://github.com/electric-sql/pglite
- pgvector 文档:https://github.com/pgvector/pgvector