日期:2026-08-14
我们的知识库问答上线初期,用户反馈最多的不是答错,是答得"太像"。一问产品问题,检索总把那几篇高频文档的前几段甩出来,稍微冷门一点的问题就拿不到真正相关的片段。我们拉了日志看,长尾查询(月提问量低于几次的那些)答非所问的比例明显高于头部,而这些长尾问题恰恰来自真实客户,沉默的大多数反而最影响口碑。这件事如果不治,RAG 用得越久,头部文档被喂得越肥,长尾越饿死,系统会陷入一种"越常用越准、越冷门越烂"的恶性循环。我们当时判断,多样性优化不是锦上添花,是 RAG 能不能长期用下去的底线。
系统是基于标准 RAG 流水线搭的:文档解析、切片、向量化、检索重排。我们在重排之后加了一层多样性处理,对召回的前 N 个片段做 MMR(最大边际相关)去冗余,把高度相似的片段打散,给不同角度的内容留位置。同时针对长尾查询,检索阶段扩窗,把候选集从默认的二十扩到五十,再用分桶重排保证低频文档也有机会进前排。每周跑一次覆盖率评估,把漏召的长尾问题挑出来复盘,反向补低频文档的权重,形成"发现漏召、补文档、再评估"的闭环。
第一个难点是高频文档霸屏。MMR 的 lambda 参数定低了去重不够,定高了又把相关信息也打散,我们在不同业务域分别调,客服域要准、知识域要全,不能一套参数通吃。第二个难点是长尾召回不足,扩窗能缓解但带来噪声,我们用分桶重排把候选按来源和置信度分层,低频但高置信的优先,高频但重复的降权。第三个难点是覆盖率怎么量化,不能靠人工抽查,我们建了长尾问题集和自动判定,每月看漏召率趋势。第四个难点是补文档后的效果验证,补完不能只看覆盖率高了,要看真实长尾查询的命中率有没有动,我们加了线上小流量验证。我后来觉得,多样性这词容易被误解成简单打散,其实真正要补的是长尾漏召,去重只是手段,本末倒置就会让冷门问题更冷,这个方向我们一开始也走过弯路。
还有一块是重排之后结果的可解释,我们给前排每个片段标了来源文档和匹配分,运营能看懂为什么推这条,而不是面对黑盒。早期没标,运营不信任自动结果,宁愿自己搜,多样性调得再好也没人用,标了来源之后接受度明显上来,系统才算真正被用起来。
另外,长尾问题集的构建也得靠真实日志,不能拍脑袋编,我们沉淀了三个月的真实长尾提问做评估集,覆盖面才可信。评估集本身也要更新,不然模型优化了旧长尾、新长尾又漏了,我们每月滚一次,保持评估集和业务同步,这套机制比参数本身更值钱。没有可信的评估,多样性调得再花哨也是盲人摸象,迟早被真实流量打脸,所以我们把评估集当成系统的一部分来养。
长尾查询的命中率(答案片段与问题相关)从约六成提升到约八成三,检索结果去重率(前排片段互相重复比例)从约三成降到约百分之八。整体覆盖率(长尾问题集可答比例)提升约两成。答非所问率从约一成八降到约百分之六。一个季度补了约三百篇低频但高价值的文档,长尾漏召复盘闭环率约九成。线上小流量验证显示,补文档后对应长尾查询的真实命中率提升约十五个百分点,不是只在测试集上好看。
更关键的是,长尾问题集现在成了新模型上线前的必过门槛,答不准的长尾问题直接卡发布,反过来倒逼检索和生成效果一起提升,形成正向循环。
RAG 做多样性,先想清楚要补的是长尾漏召还是头部冗余,这两件事的治法完全不一样。我们一开始只上 MMR,结果头部是干净了,冷门问题反而更答不上,那是把手段当目的了。分桶重排比单纯扩窗靠谱,高频重复降权、低频高置信提权,噪声和覆盖能同时管住。覆盖率必须可量化,长尾问题集和自动判定这套东西值得提前建,否则你永远不知道多样性调得到底有没有用,只能凭感觉。说到底,RAG 的价值在长尾不在头部,头部问题怎么调都差不到哪去,真正拉开体验差距的,是那些一个月只被问几次的冷门问题能不能答上来。
我们也踩过坑,有阵子为了覆盖率猛补文档,结果补了一堆低质转载,反而把信噪比拉低,后来加了文档质量门槛才收住。覆盖率高不等于答得准,这条我们是用一次翻车换来的教训,现在补文档前先过质量关,宁缺毋滥。
做 RAG 这一年,我们最大的体会是效果不是调出来的,是量出来的,没有可信的评估集,所有的优化都是在黑屋里开枪,迟早要还。
案例片段(已脱敏): MMR 去重与长尾扩窗配置:
yaml rerank: mmr_lambda: cs_domain: 0.7 # 客服域偏准 kb_domain: 0.5 # 知识域偏全 long_tail: recall_window: 50 # 常规 20, 长尾扩窗 bucket_rerank: low_freq_high_conf: boost high_freq_dup: demote覆盖率评估日志节选:[2026-07-25] long_tail_set=1280 问 命中率 0.83, 去重率 0.08 漏召 218 问 -> 复盘补文档 196 篇 闭环率 0.90