跳到主要内容

一次向量库参数调整带来的召回变化

· 阅读需 4 分钟
一介布衣
全栈开发者 / 技术写作者

补档说明:本文属于「AI 工程落地周记」系列,计划发布时间为 2025-10-22 09:10。当前先保留为草稿,后续补充真实案例、代码片段和复盘细节后再发布。

有一次我们为了把检索时延压下来,动了向量库的一组参数。改动本身不大,甚至可以说很“合理”:

  • 降一点搜索深度
  • 控一点候选数
  • 让查询更快一点

结果上线后最先变化的不是延迟,而是答案味道。
用户不会告诉你“召回率下降了”,他们只会说:

  • 怎么最近更容易答偏了
  • 怎么有些问题又像没看文档一样

后来追回去才发现,这次参数调整表面上节省了一点查询成本,实际上悄悄改掉了检索质量的下限。

问题为什么不容易第一时间被看见

因为大多数线上监控只看到了:

  • 查询快了一点
  • 错误率没有暴涨
  • 系统也没明显报错

但真正受影响的是:

  • 被召回的文档集合
  • top-k 结果里的排序稳定性
  • 长尾问题的覆盖率

这些东西如果没有专门评测,很容易在业务反馈里才慢慢浮出来。

当时改的是哪类参数

这次我们动的不是 embedding,也不是 chunk,而是检索阶段的搜索参数。
以 HNSW 为例,类似这样的改动:

index:
efSearch: 64 -> 24
topK: 8 -> 6

单看数字都不算夸张,但它们会共同影响一个关键结果:
系统在有限时间里愿意探索多少候选邻居。

探索少了,速度可能更快,但召回的稳健性也会下去。

变化后来是怎么确认的

我们没有一开始就猜是向量库参数,而是先看到两个业务信号:

含专有术语的问题更容易答偏
长尾知识点命中变差

再去做离线对比时,才看到这种模式:

  • 常规样本变化不大
  • 边界样本和长尾样本下降明显
  • top1 文档看起来还“像那么回事”,但真正关键文档更容易掉出 topK

这类变化特别容易欺骗人,因为它不会把系统直接打挂,只会让答案慢慢“没那么准”。

一个很重要的经验:检索参数不是纯性能参数

这次之后我基本不再把向量库参数当成单纯的性能旋钮。

因为它们同时在影响:

  • 查询延迟
  • 召回候选多样性
  • 长尾覆盖
  • 后续重排的可发挥空间

换句话说,检索参数调优本质上是在做质量和成本的联合取舍。

我后来怎么做得更稳

后面我们不再直接在线上“感觉着调”,而是先补了两层东西:

1. 检索级评测集

专门收一批对召回敏感的样本,例如:

  • 专有名词
  • 别名问题
  • 低频知识点
  • 需要跨段理解的问题

2. 文档命中对比

不是只看最终答案,而是直接比较:

  • topK 文档是否包含关键文档
  • 关键文档排名有没有明显下降

只有这样,调参数时你才知道自己到底是在拿什么换什么。

一个更稳的判断顺序

现在如果要调这类参数,我会按这个顺序来:

  1. 先确认目标是降时延还是降成本
  2. 再选少量候选参数组合
  3. 先跑检索级离线集
  4. 再观察在线时延和业务反馈

而不是先在线上压参数,再等用户反馈告诉你答偏了。

总结

这次向量库参数调整带来的召回变化,让我更确定了一件事:
检索参数不是“无害的小优化”,而是会直接动到知识命中质量的核心杠杆。

在 RAG 系统里,快一点和准一点经常不是同时免费的。每次调参,最好都把它当成一次质量变更,而不是一次单纯性能优化。