跳到主要内容

向量检索中的流行度偏见:为什么相同的五个文本块总是主导每个查询

· 阅读需 13 分钟
Tian Pan
Software Engineer

从任何成熟的 RAG 系统中提取一周的检索日志,并按分块(chunks)被返回的频率进行排序。其分布形态几乎总是相同的:一小部分分块出现在数千次查询中,而语料库中的绝大多数内容仅出现几次,甚至从未出现过。系统没有故障。它正在精准地执行索引构建时的预期功能 —— 而这恰恰是问题所在。

这就是向量检索中的流行度偏差(popularity bias),而且随着语料库的增长,这种情况会变得更加严重。少数分块变成了“引力井”,在互不相关的查询中频频胜出,而长尾内容则悄然消失在 top-k 截断值之下。你的 RAG 系统开始让人感觉“平庸” —— 用户提出具体问题,得到的回答听起来却像是为别人写的一样。等到产品部门开始投诉时,这种分布不均的情况往往已经持续数周了。

机制分析:枢纽点是数学必然,而非 Bug

根本原因是高维几何的一个特性,被称为枢纽点现象(hubness phenomenon)。Radovanović、Nanopoulos 和 Ivanović 在 2010 年记录了这一现象:随着嵌入维度的增加,k-出现(k-occurrences,即一个点出现在其他点的最近邻列表中的次数)的分布会呈现强烈的右偏。一些点 —— 枢纽点(hubs) —— 作为最近邻出现在语料库不成比例的份额中。其他点 —— 反枢纽点(antihubs) —— 几乎不出现在任何邻居列表中。

这并不是糟糕的嵌入模型或粗糙的索引造成的产物。它是在数百或数千个维度中运行的必然结果。靠近嵌入分布的局部或全局质心的点具有不对称的几何优势:它们与许多查询都“相当接近”,甚至是那些彼此并不接近的查询。在检索中,一旦降到 top-k 截断值以下,余弦度量下的“相当接近”通常会击败“极其精准但在稀疏区域”的分块。

现代 ANN 索引放大了这种效应。HNSW(目前向量搜索的事实标准)建立在可导航小世界图之上,其中枢纽节点充当贪婪路由的高速公路入口。这种结构性角色正是 HNSW 速度快的原因 —— 但正是这些保持图可导航性的枢纽点,成了你的搜索不断返回的分块。索引并不是在随机偏袒它们;它在架构上就是为了将查询路由向它们而优化的。

流行度偏差的实际表现

其症状很少表现为“错误答案”,而是一种缓慢渗透的同质化(sameness)

  • 同样的三个排障分块出现在关于网络、认证和计费问题的回答中。
  • 一个通用的公司概览段落在深度技术问题中不断被引用。
  • 两年前写得很好的一条 FAQ 条目,在关于当时甚至还不存在的功能的查询中占据主导地位。
  • 本该召回最新文档的查询,反而提取了一个深受欢迎的、泛泛谈论该话题的“常青树”解释器。

如果你只看离线评估集,你可能会完全忽略这一点。评估集通常是手工挑选的,覆盖特定主题,而枢纽分块对于这些精心策划的查询通常“足够好”。偏差体现在真实用户流量的长尾部分 —— 而这恰恰是你缺乏地面真理(ground truth)的地方。

还需要注意反馈循环。许多 RAG 系统会记录哪些分块对点赞回复有贡献,并利用该信号增加未来检索的权重。枢纽分块本就容易胜出;一旦再加上流行度加成,它们会赢得更彻底,有效的语料库会进一步萎缩。如果没有多样化压力,一个拥有 100,000 个分块的健康语料库可能会塌缩成仅剩几百个分块的有效语料库。

诊断信号

你可以直接测量这一点,在讨论修复方案之前,这很值得一做。

分块检索频率直方图。 对于每个分块,统计它在一段时间的真实查询中出现在 top-k 中的频率。在 log y 轴上绘制直方图。健康的分布应该是平滑衰减的。不健康的分布则会出现超级枢纽点的峰值(比中位数高出几个数量级),以及一个长长的、频率为零的平坦尾部。

分块频率的基尼系数。 借用衡量经济不平等的指标。计算检索频率的基尼系数。接近 0 的值表示检索分布均匀;接近 1 的值表示极少数子集占据主导地位。随时间跟踪此指标 —— 它会随着语料库的增长以及嵌入模型相对于内容分布的老化而上升。语料库更新后的急剧跳升通常预示着一批新文档落在了稀疏区域,实际上是不可见的。

查询多样性与分块多样性之比。 对查询进行聚类(按意图、主题或嵌入),并测量任何给定分块响应了多少个不同的聚类。出现在许多无关查询聚类中的分块几乎肯定是一个枢纽点,而不是精准相关的结果。覆盖的查询聚类与使用的分块之比是一个综合健康得分。

K-出现偏度(K-occurrence skew)。 直接测量枢纽性:对于每个分块,统计有多少其他分块将其列入其 top-k 最近邻。这是高维 NN 文献中经典的枢纽性指标。如果少数分块出现在数千个其他分块的邻域中,检索将不顾查询的具体性而路由到它们。

反枢纽点清单。 另一面是那些从未被检索到的分块。抽样一些,并使用分块本身的精确文本重新查询。如果连自查询(self-query)都不能将它们返回到 top-k 中,那么你的索引在任何合理的查询方向上都无法“看到”它们。

切实有效的缓解措施

没有单一的解决方案。以下工具可以叠加使用,每种工具都针对不同的失效模式。

最大边际相关性(MMR)及其变体

MMR 是经典的搜索多样化重排序方法。在初始检索后,迭代地筛选前 k 个结果:每个候选分数的计算是其与查询的相关性以及与已选结果的“差异性”的加权融合。λ 参数控制两者之间的权衡——λ 接近 1 是纯相关性,λ 接近 0 是纯多样性。大多数生产系统取值在 0.5 到 0.7 之间。

MMR 成本低廉,不需要更改索引,并且能化解最常见的枢纽(hub)失效模式:即 Top-k 结果坍缩为某个主导分块的近乎重复项。Qdrant 和 OpenSearch 都提供了原生的 MMR 重排序功能,而 Azure AI Search 则将其作为一种集成路径提供。2025 年的一个变体——采样 MMR(SMMR),在筛选中注入受控的随机性,以便在不放弃相关性的情况下进一步扩大覆盖范围。这在确定性 MMR 仍会过度集中在相同枢纽的高流量系统中非常有用。

MMR 本身并非万灵丹。它的“差异性”概念是在产生枢纽的同一个嵌入空间中测量的,因此它可以减少近乎重复项的碰撞,但并不总能逃脱一个主导集群。请将其视为底线,而非上限。

基于查询条件的重排序

交叉编码器(cross-encoder)重排序会同时读取查询和每个候选分块,产生一个不属于枢纽几何空间的关联性得分。这与 MMR 不同——它不是在做多样化,而是用具体的查询特定判断取代了几何代理指标。枢纽失去了它们的不对称优势,因为重排序器是根据特定查询而非针对质心来评估每个分块。

其代价是延迟和 Token 预算,因此通常仅用于初始检索后的前 50–100 个候选结果。当你的语料库有明确的主题边界,而嵌入模型又使其变得模糊时,这种投入的回报是极高的。

单文档检索上限

如果你的语料库具有文档级结构(一个文档被切分为多个分块),请为单个文档出现在 Top-k 中的分块数量设定一个明确的上限。大多数枢纽都集中在少数源文档中——例如热门讲解、核心词汇表或被广泛链接的概述。将每个文档的分块上限设为 2–3 个,既能保留每个来源的覆盖面,又能防止单个文档垄断上下文。

对于许多团队来说,这是成本最低、投资回报率(ROI)最高的修复方案。它不需要更改模型,不需要新服务,而且用户体验(UX)的提升通常立竿见影。

索引时的枢纽性削减

若要进行更深层次的修复,关于枢纽性削减(hubness reduction)的学术文献提供了重塑距离分布本身的技术。互邻近度(Mutual proximity)、局部缩放(local scaling)和共享邻居(shared-neighbors)方法会重新计算距离权重,使枢纽在最近邻计算过程中失去其不对称优势。实证对比显示,这些方法可以显著提高许多领域高维数据的分类和检索准确率。

权衡之处在于,大多数枢纽性削减方法比普通的余弦距离更耗费算力,而且很少有向量数据库将其作为原生选项提供。如果你拥有自己的索引,这是一条可行之路。如果你使用的是托管服务,你可能只能在上述其他选项中做出选择。

检索前的查询路由

最后一个工具不是重排序,而是路由。在进入向量索引之前,先将查询分类为意图或主题,并利用分类来限定检索范围(通过元数据过滤、路由到特定主题的子索引,或利用学到的意图向量偏置查询嵌入)。枢纽在无差别的全局搜索中危害最大;限定范围缩小了它们参与竞争的几何空间。

为什么随着语料库的增长,情况会变得更糟

直觉告诉我们,更多的数据应该给检索提供更多素材。但流行度偏见逆转了这一直觉。随着语料库规模的增长:

  • 嵌入空间填充不均匀。 新内容倾向于聚集在现有内容附近。稀疏区域保持稀疏,而密集区域变得更加密集——最接近这些密集质心的分块会变成更强大的枢纽。
  • Top-k 保持不变,而长尾部分在增长。 如果你从 1 万个分块的语料库中检索前 5 个,长尾部分占内容的 99.95%。在 10 万个分块时,这一比例变为 99.995%。截断阈值并不关心它排除了多少内容。
  • 枢纽增强循环不断复合。 每一个将检索推向枢纽的隐式或显式反馈信号(点击、点赞、回答中的引用)都会进一步加强它们。
  • 嵌入模型老化。 嵌入模型是在一个与你当前内容不再匹配的分布上训练的。偏移(Drift)在累积;在旧分布下添加的分块最终会掉入反枢纽(antihub)区域。

实际后果是:如果你每季度测量一次检索多样性,你会发现即使你没有做错任何事,基尼系数(Gini coefficient)也会攀升。多样化不是一次性的干预;它是针对索引自然动态的持续对抗压力。

为长期健康度进行监测

有三个习惯值得建立,而且都不需要推倒重来:

记录每一次检索和每一个排名位置,而不只是到达 LLM 的分块。 具备排名感知能力的日志记录是实现频率直方图和基尼系数计算的基础。没有它,你只能看到发送了什么,而看不到差一点就能发送的内容。

对检索多样性的下降报警,而不只是针对准确率下降。 基尼系数上升 5 个点就是一个真实的事故,即使离线评估分数保持稳定。这意味着用户的差异化需求不再得到满足——只是你在精心挑选的测试集中看不出来。

在每次语料库更新时审计反枢纽。 在一批新文档上线之前,对每个分块进行自查询,并确认它能在其自身文本的 Top-k 检索中出现。未通过此测试的分块从第一天起就是不可见的,并且会一直保持这种状态。

核心要点

流行度偏差(Popularity bias)并非评估失败、模型失败或数据失败。它是高维空间中进行最近邻搜索(nearest-neighbor search)的结构性后果,并受到使现代向量搜索更高效的图结构的加速影响。如果任其发展,它会悄无声息地瓦解你语料库的有效规模,并将具体的问题转化为泛泛而谈的回答。

解决办法并非调节单一的开关。而是一套技术组合:通过设置单文档上限来打破最明显的碰撞、使用 MMR 或交叉编码(cross-encoder)重排序器来施加特定于查询的压力、在监控中引入多样性指标使性能退化可见,以及针对最棘手的情况采用意图感知路由(intent-aware routing)。这些方法并不罕见。罕见的是,竟然有如此多的生产级 RAG 系统在没有任何此类措施的情况下上线,并纳闷为什么总是那五个相同的文本块(chunks)反复出现。

References:Let's stay in touch and Follow me for more thoughts and updates