Ch30: 向量库适配器——接口、多租户 filter 与换模重建
Part 8 · 前置:Ch29 docparser · 后续:Ch31 Wiki 对比:Ch19 AnythingLLM 适配器
结论先行:WeKnora 支持多向量后端(Milvus/Qdrant/pgvector/…)靠 VectorStore 接口 + 配置 driver——加库 = 新 adapter,不改 RRF/Rerank。大师必会:kb_id 隔离 filter、换 embedding 维度必须全量 re-embed、ANN 参数对延迟/Recall 的 trade-off。
一、日常类比
向量库像不同品牌的仓库货架:货(chunk 向量)规格(维度)必须和货架层间距匹配。换 embedding 模型等于换箱子尺寸——必须 整库重摆,不能混放 768 维与 1536 维。
二、接口心智模型
type VectorStore interface {
Upsert(ctx context.Context, vectors []VectorRecord) error
Delete(ctx context.Context, ids []string) error
Search(ctx context.Context, query []float32, topK int, filter Filter) ([]Hit, error)
}
| 方法 | 失败模式 |
|---|---|
| Upsert | 维度不匹配 → 写入失败或 silent truncate |
| Delete | doc 更新未删旧向量 → 双份召回 |
| Search | filter 漏 kb_id → 跨库泄漏 |
三、读代码三步
rg -n "type VectorStore interface" --glob '*.go'
rg -n "Milvus|Qdrant|pgvector|chroma" internal/ pkg/ -g '*.go'
rg -n "kb_id|KnowledgeBaseID" internal/ -g '*vector*'
- 找 interface 定义与
NewVectorStore(config)工厂 - 选一个 driver(如 qdrant)读
Search如何拼 filter - 看 config/env 如何选择 driver name(Helm values)
四、与检索栈关系
向量路只是 Ch24 三路 之一:
五、换 embedding runbook(竞赛常问)
| 步骤 | 动作 |
|---|---|
| 1 | 冻结写入,记录旧 model 名与维度 |
| 2 | 新 collection 或新 index prefix |
| 3 | 全量 re-embed(成本 ≈ chunk 数 × API 单价) |
| 4 | 双读验证 smoke-10 |
| 5 | 切换读路径,删旧 index |
见 lab/corpus/faq-version-conflict.md「8 vs 10 库」— 向量库 个数 与 embedding 维度 是不同问题。
六、贡献方向
- 新 backend adapter(跟官方 issue)
- filter 回归测试(kb A 不应检出 kb B)
- 同 corpus 对比两 ANN 后端 P99 延迟表
章末自检
- 解释 kb_id filter 对多租户的意义
- 说清换 embedding 为何必须重建索引
- 在仓库报出 VectorStore 实现文件名 ≥1 个