当 top-k=10 召回仍不足 85% 时,如何采用查询扩展(Query Expansion)提升?

解读

面试官给出的是一个生产级召回链路的典型瓶颈:在百亿/千亿参数大模型落地场景下,即使把 top-k 拉到 10,召回率仍低于业务红线 85%。
该问题隐含三层考核:

  1. 能否快速定位“召回不足”根因(语义鸿沟、词表差异、领域同义词、口语化表达);
  2. 能否在不增加太多在线延迟的前提下,用查询扩展手段把 10 条槽位充分利用;
  3. 能否把扩展策略无缝接入LLMOps闭环,保证后续可监控、可回滚、可灰度。

知识点

  1. 召回率(Recall@K):衡量真实相关结果在 top-k 中的占比,国内业务通常要求≥85%。
  2. 查询扩展(Query Expansion, QE):在不改变用户原始意图的前提下,自动补充同义词、上下位词、相关实体、句式变换,从而扩大检索面。
  3. 大模型即扩展器:利用百亿/千亿参数生成式模型的隐式知识,一次性生成多条扩展 query,替代传统基于词典或统计共现的方法。
  4. LLMOps 三板斧离线评测→小流量灰度→实时指标回写,确保扩展质量可量化、可回滚。
  5. 延迟红线:国内线上系统一般要求p99 延迟≤200 ms,因此扩展必须在召回前同步完成,且单次调用 token 数≤128

答案

我采用“三阶扩展+两级过滤”方案,把召回率从 82% 提升到 90%,同时 p99 延迟仅增加 18 ms,步骤如下:

  1. 意图锚点抽取
    轻量级 1.3B 小模型在 10 ms 内抽取出 query 的核心实体+意图动词,例如“小孩发烧怎么办”→{实体:小孩、发烧;意图:治疗}。该步骤保证后续扩展不跑偏。

  2. 大模型同步扩展
    把锚点组装成 prompt:“请用同一场景的 5 种不同说法表达,每条 8~15 字,保留‘小孩发烧’关键词。”
    调用本地部署的 10B 参数大模型,temperature=0.3,top-p=0.85,单次返回 5 条扩展 query,平均延迟 35 ms。
    为降低延迟,采用连续批处理(continuous batching) + KV-Cache 复用,QPS 3000 时 p99 仍低于 50 ms。

  3. 相关性过滤
    交叉编码器(cross-encoder)轻量版对 5 条扩展 query 与原 query 做语义相似度打分,阈值 0.78,过滤掉跑偏表达,平均保留 3.2 条。

  4. 并行检索与合并
    将原 query + 3.2 条扩展 query 并行走向量检索(inner-product)BM25 倒排,各取 top-10,再用**RRF(Reciprocal Rank Fusion)**重排,最终输出 10 条结果。
    实验显示,该策略把 Recall@10 从 82% 提升到 90%,**精确率(Precision@10)**仅下降 1.4%,在业务可接受范围。

  5. LLMOps 闭环
    扩展 query、召回结果、用户点击日志实时写入 Kafka,次日自动触发离线评测任务

    • 若召回率<85%,自动回滚扩展模型到上一版本;
    • 若出现敏感词或歧义扩展,立即触发人工审核并冻结该模板。
      整个流程通过GitOps + Flagr 灰度开关实现分钟级回滚。

拓展思考

  1. 多语言场景:方言 query(如“娃儿发热咋个办”)可先用方言转普通话模型做标准化,再进入扩展链路,避免大模型对方言理解不足。
  2. 动态扩展权重:把扩展 query 的点击反馈建模成 bandit 问题,在线调整每条扩展 query 的检索权重,实现“越点越准”。
  3. 边缘部署:若业务方对延迟极其敏感,可把 10B 模型蒸馏成 0.8B的小模型,量化到 INT8,在华为昇腾 310P上单卡 QPS 500,延迟 12 ms,召回损失仅 0.7%。
  4. 合规风险:扩展不能引入医疗承诺、违规广告等内容,需在 prompt 层加**“禁止出现未经验证的疗效描述”红线,并用敏感词过滤+大模型自检**双保险。