相似度、索引与版本迁移
本节目标
你将把向量空间当成不可混用的版本化数据产品:理解 exact 与 ANN 的不同误差,验证 metadata 过滤,校准空间专属阈值,并用双索引完成模型/维度/角色/归一化迁移。
空间兼容由完整契约决定
建议把以下字段规范化后生成 contract signature:
两个向量只有在明确兼容的同一空间里才比较。以下任一变化都应触发新候选空间或至少强制兼容性评审:
- 模型或不可变 revision;
- query/document role、任务指令或前缀;
- pooling、tokenizer 或截断策略;
- 输出维度;
- dtype/量化;
- normalization;
- metric;
- 多模态输入组织。
维度相同只是数组形状相同,不代表坐标轴含义相同。不同模型 A、B 的第一个分量没有共同基,A-query · B-document通常没有检索语义。
Exact search 是评测基线
给定一个 query vector,exact search 与所有授权 documents 逐一算同一 metric,并确定排序。它适合:
- 小语料或离线 gold;
- 验证分数和 tie-breaking;
- 作为 ANN 近似误差的 ground truth;
- 排查过滤、量化和索引参数。
复杂度随候选数增长,不适合所有大规模在线场景。
ANN 解决速度,不证明相关性
Approximate Nearest Neighbor(ANN)用索引结构减少比较,通常以更多内存/构建时间或少量近邻遗漏换取低延迟。Faiss 等库提供多种 exact/ANN 结构;具体参数必须用官方文档和本地压测选择。
要分开两个问题:
ANN recall
先冻结同一数据快照、embedding 空间、可信身份派生的安全 filter、query 与 tie-breaking。令 为过滤后可搜索的候选集合,;再比较 ANN 与 exact 的 top-:
它测“近似索引有没有找回 exact 邻居”,不需要业务 relevance。 时应单列为 empty_eligible/不适用,而不是把安全的空结果记成 0 分;ANN 实际少返回的结果仍要保留为低 recall 或服务失败信号。
Business Recall@k
比较结果与人工/行为 gold。这里的 gold 必须是冻结测试主体、时间和策略 revision 下本应可访问的相关项,记为 :
它同时受模型、chunking、过滤、查询角色与索引影响。若 为空,应作为无答案/越权不得返回的安全 case 单独验收,而不是把正确拒绝汇入 0 recall。ANN recall 很高但 embedding 模型不懂领域,业务 Recall 仍可能很差;反过来,少量 exact 邻居差异也可能不影响 relevant documents。
Metadata filter 必须实测
Tenant、ACL、发布状态、语言、时间和文档类型应在候选返回前 fail-closed 生效。但不同向量库、索引和查询模式可能使用:
- pre-filter;
- ANN 过程中集成过滤;
- post-filter;
- pre/post 的混合或回填策略。
Post-filter 可能让 top-k 数量不足,pre-filter 可能在高选择性场景改变性能和 ANN recall。不能只看 API 名称猜执行语义。
验收测试至少包含:
- 未授权 document 与 query 向量完全相同;
- 授权 document 相似度较低;
- 未授权项绝不能出现在候选、分数日志或 parent 展开;
- 返回数量不足时系统行为明确;
- tenant/ACL 缺失时拒绝,而不是全局可见。
这部分将在 [[Knowledge/AI Agent Engineer/docs-CN/向量数据库/00-目录|向量数据库]]与 [[Knowledge/AI Agent Engineer/docs-CN/语义搜索/00-目录|语义搜索]]继续深化。
阈值不是通用常数
最近邻搜索通常总能返回某些项,即使全部不相关。若系统用 score threshold 拒绝低分,需要:
- 每个空间分别校准;
- 使用有答案与无答案开发集;
- 定义误报/漏报成本;
- 按语言、领域、query 类型检查;
- 模型、角色、metric、归一化、量化或维度变化后重做;
- 在独立测试集只评一次最终策略。
Cosine 0.8 在两个模型中不代表相同相关概率。也不要在测试集上不断调阈值再报告“最终测试成绩”。
为什么不能就地混写升级
假设索引里已有模型 A documents。如果开始把模型 B 的新文档直接写入:
- A query 只能正确比较 A documents;
- B query 只能正确比较 B documents;
- 同一个 top-k 混合两种不可比 score;
- 阈值、metric 和 dimension 可能冲突;
- 出问题无法只回滚一半。
即使向量数据库允许同维写入,这仍是语义数据损坏。
双索引迁移流程
1. 冻结旧空间
记录 contract signature、published alias、canonical source revision、item count、删除水位、gold/test 集和当前指标。停止修改旧契约默认值。
2. 创建新空间
新 collection/index/namespace 使用独立 space_id,固定 dimension、dtype、metric、normalization、role 与 metadata schema。不要复用旧 alias 直接覆盖。
3. 从 canonical 输入重建
从同一版 chunks 和 query fixtures 重新编码,不从旧向量做未经支持的变换。写入时逐项校验并保留 source/input hash。
4. 做机械对账
- item ID 集合一致;
- document/query/tenant/ACL/source revision 一致;
- 无零向量、NaN/Inf、错维;
- norm 分布符合新契约;
- 删除/tombstone 已传播;
- 新向量数量与缓存命中/失败差集闭合。
机械对账通过只说明数据完整,不说明质量足够。
5. 离线质量与系统评测
固定 query/gold,分别用 A-query 查 A-index、B-query 查 B-index。比较:
- Recall@k、MRR、nDCG 和 per-query delta;
- 关键语言/领域/权限子组;
- top-k Jaccard/新旧结果变更;
- exact 与 ANN 差异;
- P50/P95、吞吐、内存、重建时长和费用;
- 阈值下无答案误报/漏报。
不能用一条 query vector 同时查两个空间。
6. 影子与灰度
在线请求在不影响用户结果的情况下生成两套 query vectors、独立检索并记录脱敏差异。确认流量、成本和隐私授权后,再让小比例用户读取新 alias。
7. 原子切换
切换应用的 published pointer/alias,而不是逐实例手改配置。记录切换 revision、时间、操作者和回滚条件。
8. 保留回滚并治理删除
旧空间在明确窗口内只读保留;验证稳定后,按保留/删除政策移除索引、缓存和备份。数据主体删除和 ACL 撤销不能等迁移结束才处理,必须同步传播到所有活动空间。
迁移门禁示例
| 类型 | 门禁 | 失败动作 |
|---|---|---|
| Inventory | canonical item/ACL/revision 对账为零差异 | 阻止发布,重跑缺失项 |
| Numeric | dimension、finite、norm、dtype 全部合规 | 隔离异常向量 |
| Quality | 关键子组不低于预设下限 | 分析 query,不用总均值掩盖 |
| Security | 越权测试 0 泄露 | 立即阻断 |
| System | P95、错误率、容量在预算内 | 调参或扩容后重测 |
| Operations | alias 切换、监控和回滚演练通过 | 不进入灰度 |
| Governance | 删除/保留/许可/数据处理获批 | 暂停迁移 |
“新模型平均 Recall 更高”不能覆盖关键 ACL 或语言子组退化。
维度、量化和 ANN 的分层实验
迁移可能同时涉及模型、维度、量化和索引参数。为可归因,建议:
- 新模型 full-dimension float exact;
- 同模型 reduced-dimension float exact;
- 同维度 quantized exact/近似;
- 同表示上的 ANN 参数;
- 最后组合并做端到端 RAG。
每层与前一层比较 per-query top-k agreement 和业务指标。否则出现退化时不知道该回退模型、维度、量化还是 ANN 配置。
运行期漂移与完整性
Embedding 模型通常对固定输入产生稳定表示,但系统仍可能因 alias、SDK 默认、预处理、模型部署或数据分布改变而漂移。监控:
- contract signature 与 deployment revision;
- canary 输入的 dimension、norm、hash/容差和 top-k;
- 输入语言/长度/领域分布;
- 查询无结果或低分比例;
- top-k 多样性、重复 parent;
- gold replay 与关键 query;
- 索引数量、tombstone 和缓存对账。
不要把随机抽样线上正文写入普通监控;使用授权 canary 与聚合统计。
常见错误与排查
- 新旧模型写同一 collection:立即停止写入,按 space ID 清点,不能靠分数修复。
- ANN recall 降低就换模型:先区分索引近似误差与业务相关性。
- 过滤后 top-k 不足:查 pre/post-filter 语义与回填配置。
- 阈值迁移后误报增多:分数刻度变了,重新用开发集校准。
- 灰度无法回滚:读 alias、写任务和缓存没有统一版本开关。
- 旧空间删除太早:没有稳定观察窗或回滚演练。
- 旧空间永不删除:成本和数据删除义务持续累积。
练习
- 画出 A(768d cosine)迁移到 B(1024d normalized dot)的双索引数据流,标出 query 必须编码两次的位置。
- 构造“未授权向量最相似”的过滤测试,并说明为什么只检查最终 UI 不够。
- 给出 ANN recall 与 business Recall 一高一低的两个反例。
- 写 8 个切换门禁,分别覆盖机械、质量、安全、系统和治理。
- 设计模型不变、只改量化与 ANN 的分层实验。
- 为 ACL 撤销定义旧/新索引、缓存和备份的传播与对账。
掌握检查
- 我用完整 contract signature 判断空间兼容,而不是只看维度。
- 我区分 exact ground truth、ANN recall 与业务 relevance。
- 我会验证过滤实际执行语义和越权边界。
- Score threshold 每个空间单独校准。
- 新旧向量不混写,query 对两个空间分别编码。
- 迁移包含 canonical 重建、机械对账、离线评测、影子/灰度、原子切换、回滚和治理删除。
- 模型、维度、量化与 ANN 分层实验,结果可归因。
小结与下一步
空间隔离和双索引让迁移在工程上可控;是否值得切换仍要由固定 query/gold、子组和系统成本共同决定。下一步运行完整离线项目:[[Knowledge/AI Agent Engineer/docs-CN/Embedding/05-评测与迁移项目|评测与迁移项目]]。
参考资料
- Sentence Transformers: Semantic Search
- Faiss official repository
- OpenAI: Vector embeddings
- Gemini API: Embeddings
- Cohere: Introduction to Embeddings
来源获取日期:2026-07-14。具体向量库的过滤与 ANN 行为需查所选产品当前官方文档并做越权/召回测试。返回 [[Knowledge/AI Agent Engineer/docs-CN/Embedding/00-目录|Embedding 目录]]。