在构建企业级 RAG 系统时,检索结果中频繁出现的近重复样本是一个容易被忽视但影响深远的问题。当用户向 AI 编码助手 ByteBot 提交查询时,如果返回的文档片段高度相似,不仅浪费了宝贵的上下文窗口容量,还可能导致语言模型产生重复性回答,严重降低用户体验。针对这一痛点,本文系统梳理近重复检测的核心度量方法,并给出阈值选择的工程化参数建议。

近重复检测的核心挑战在于 “近” 字。相比精确匹配,RAG 系统中处理的是经过向量化后的稠密浮点数序列,同一语义的不同表述可能在嵌入空间中距离极近。传统的编辑距离或 Jaccard 系数在原始文本层面尚可工作,但面对经过 BERT、Sentence-BERT 等模型编码后的高维向量,这些基于词符的度量方法往往失效。因此,工程实践中普遍采用向量空间的距离度量来判定样本是否构成近重复。

余弦相似度是最常用的度量指标,其优势在于对向量长度不敏感,仅关注方向一致性。在 RAG 场景下,文档长度的变化不会导致相似度剧烈波动,这使得阈值设定相对稳定。经验表明,当余弦相似度超过 0.92 时,两段文本在语义层面几乎完全等价,可以直接判定为近重复并丢弃;当相似度处于 0.85 至 0.92 区间时,需要结合其他特征进行二次判断,例如词序相似度或命名实体重叠率。低于 0.85 的样本通常被认为是独立的不同内容,予以保留。

然而,余弦相似度并非万能解决方案。对于使用稀疏向量(如 BM25 或 TF-IDF)的检索系统,余弦相似度容易被高频词误导。此时 Jaccard 相似系数表现出更好的鲁棒性,它直接基于词集合的交集与并集比率计算,对文档长度的敏感性更低。工程中常见的做法是先用 Jaccard 快速过滤掉明显不同的候选对,再用余弦相似度进行精细排序。两种方法的计算成本差异也值得关注:Jaccard 仅需集合操作,时间复杂度为 O (n),而余弦相似度需要遍历所有维度进行点乘运算,在嵌入维度达到 768 或 1024 时,这一差异会显著影响在线推理延迟。

阈值的选取不能孤立看待,必须结合具体业务场景进行调优。以代码检索为例,ByteBot 需要处理大量的函数签名和文档字符串,同一个函数的不同实现版本可能仅有微小差异,此时应将阈值调高至 0.95 以上,避免重复冗余。而在知识库问答场景中,用户问题可能存在多种等效表述,适当的近重复反而有助于提升召回率,此时阈值可以放宽至 0.80 附近。监控指标方面,除了传统的精确率和召回率,还应关注去重率曲线 —— 即每次检索请求中 被过滤掉样本的比例。如果该比例长期高于 30%,说明底层向量化模型可能存在聚类效应,需要考虑更换嵌入模型或引入层次化索引策略。

在工程实现层面,近重复检测通常作为检索后处理管道的一环。典型架构是在向量检索返回 Top-K 结果后,依次执行去重排序、优先级加权和上下文组装三个步骤。去重模块内部维护一个滑动窗口缓存,将已确认的近重复对写入 LRU 结构,避免对相同文档对重复计算相似度。超时参数设计上,建议单次相似度计算控制在 5 毫秒以内,整个去重管道的总耗时不超过 50 毫秒,否则会直接影响首字节响应时间。对于高并发场景,可以将去重计算 offload 到 GPU 或专用加速卡上,利用向量化指令并行处理批量候选对。

综合来看,RAG 系统的近重复检测需要根据嵌入模型特性、检索延迟要求和业务语义容忍度进行综合决策。余弦相似度配合 0.85 至 0.92 的阈值区间是工程落地的良好起点,辅以 Jaccard 系数的双层过滤机制可以在保证召回的同时显著提升精确率。持续监控去重率指标并根据实际效果微调阈值,是系统在生产环境中保持最优表现的关键。

资料来源:本文技术细节参考了向量检索领域的工程实践经验,具体阈值范围基于业界通用的 RAG 系统调优共识。