Hotdry.
ai-systems

PGlite + pgvector:浏览器端 WASM Postgres 向量索引,实现无服务器实时 RAG

PGlite 结合 pgvector 在浏览器中实现客户端向量索引与相似搜索,支持低延迟本地 RAG。提供完整参数配置、索引优化与监控清单。

在 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。

数据摄入流程

  1. 嵌入生成:客户端调用开源模型(如 Transformers.js)或 API(OpenAI)。

    async function embed(text) {
      // 示例:使用 WebLLM 或 ONNX
      return await embeddingModel.encode(text);  // [0.1, -0.2, ...]
    }
    
  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 助手。

资料来源

查看归档