先记住这个答案
先收集代表查询的相似度样本并看分布,用分位数(比如5%低位)或验证集选阈值。阈值只负责滤除明显不相关项,不能替代top-k;应保留k个候选后再做分数过滤,否则难查询被空召回。还需注意余弦与点积数值范围不一,固定常数无法跨库使用,并要区分绝对阈值与相对阈值。
- 阈值必须基于分数分布校准,不能拍脑袋。
- 用top-k保证召回数量,用分数过滤去噪。
- 不同相似度度量分数不可直接比较。
校准阈值:基于分布而非常数
相似度分数的绝对值由嵌入模型、L2归一化因子和向量库实现共同决定,不具有跨库可比性。同一个查询在不同向量库中平均分数可能从0.7跌到0.4,但两者都可能正确检索。若照搬其他项目的“0.5阈值”,在低分库会过滤掉所有结果,导致空召回。正确做法是先收集本库上一批典型查询的命中分数,看它落在哪个区间,再决定切割点。
校准的具体方法是,取一批代表性查询,记录每个查询的最相似候选分数,形成直方图。若目标是剔除明显噪声,可取下分位数(如10%)作为下限;若想平衡精确与召回,则在验证集上测试不同阈值对应的recall与精确率。对于线上每个查询,也可动态计算其候选分数均值与标准差,用均值减数倍标准差作为线,以适应该查询自身的分布形态。
客服问答库中不同主题的分数分布漂移
假设库中有产品FAQ和操作指南两类文本。查询“如何重置密码”相关片段分数通常在0.65到0.75,查询“密码重置后收不到验证码可能因为什么”则因语义复杂,相关片段分数只有0.45到0.55。如果硬性过滤阈值为0.5,后者会全部被滤掉,导致RAG只能依赖无关提示,回答质量下降。可改为先取每查询top-30,计算这30个分数的平均值和标准差,以“均值减1.5倍标准差”作为动态下限,并额外设绝对下限0.3,防止极端低分混入。
这种处理把复杂查询中的相关低分保留,同时抛弃同批次内相对孤立的低分项。对于常见查询,因高分密集,动态线自动抬升,避免噪声进入。动态线只对同一查询的候选内部有意义,跨查询比较分数含义不同;由于top-30已保证候选数量,后过滤不会造成空召回,这是与纯固定阈值的关键差别。
阈值在近重复语料与模糊查询下失效
当知识库中存在大量近重复或语义高相似的文本,例如不同版本的产品公告或同一技术问题的多种表述,这些片段与查询的相似度可能都很高,分数过滤无法排除无关项。即使把阈值调到很高,相关片段也可能被挤出,因为它们的分数可能略低于那些表述冗长的近重复项。此时需引入re-ranker或元数据过滤辅助,而不是单纯依赖相似度阈值。
另一种情况是用户问题极其模糊,或经过LLM重写后语义空间偏移,导致所有文档相似度整体被压到低位。按语料全局分位数设定的阈值会误杀全部候选,必须改为每查询的相对截断,例如只用top-k或保留本次候选中前N个,避开绝对下限。代价是可能放大检索噪声,因此需配合生成阶段的置信度检查来兜底。
容易答错的地方
- 固定阈值0.5就能通用
- 0.5只对特定模型和归一化设置有效。余弦相似度名义范围为[-1,1],但实际分布可能集中在0.3到0.8且受语料领域影响,直接用固定0.5会在低分库漏掉相关文档,在高分库混入噪声。阈值必须基于自己的真实数据进行校准。
- 过滤低分越多答案越准
- 误以为调高阈值能净化上下文提升准确率,但会截断长尾查询,让模型在信息不足时强行生成。答案质量与阈值并非单调关系,应该用带相关性标注的验证集同时观察召回率和精确率,而不是凭直觉调高过滤线。
面试官还会怎么问?
如何判断设定的阈值是否合理?
离线抽样一批查询,人工标注每个候选项是否相关,画出阈值-召回率/精确率曲线,选择业务可接受的平衡点;线上监控过滤后的平均返回条数和零结果率,若零结果率明显偏高,说明阈值过紧。
top-k与阈值谁应该先执行?
通常先取top-k(如50)建立候选池,再做阈值后过滤。若先按全局阈值过滤,可能因当前查询本身分数普遍偏低而全部被滤除,之后无法补救。后过滤保留了动态调整空间,当剩余不足k个时可放宽或直接返回。
不同向量数据库的分数比较有什么陷阱?
有些库返回余弦相似度,有些返回点积,还可能做了L2归一化,数值范围完全不一致。跨库直接复用固定阈值没有意义。比较前应先确认底层相似度类型和归一化设置,并在目标库中重新校准。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。