logo
03

Context Selection — 为什么 RAG 召回 ≠ 答对

⏱️ 25 分钟

Context Selection — 为什么 RAG 召回 ≠ 答对

写过 RAG 都见过这个数:召回率 90%(top-k 里 90% 含正确答案),端到端答对率只有 60%。30% gap 在哪?

不是 retrieval,是 selection 没做。

Lost in the Middle — 30% 的实证缺口

2023 年 7 月 Stanford 的 Liu 等人发表 Lost in the Middle(arXiv:2307.03172),用一个实验暴露所有长 context LLM 的隐疾:

实验设计

  1. multi-document QA task(20 文档 + 1 问题)
  2. 只有 1 个含答案,其他 19 个是 distractor(话题相关但不含答案)
  3. 把含答案那篇放 context 不同位置(第 1 / 5 / 10 / 15 / 20)
  4. 测每个位置答对率

结果:所有测试模型(GPT-3.5、Claude、LLaMA)呈 U 形曲线——答案放开头或结尾时答对率最高,放中间掉 30%+

[Lost in the Middle 论文图] — 图见原 paper 第 3 页。

召回的 10 段,第 4 到第 7 段模型基本看不见。retrieval 100% recall,模型也用不到位置不对的部分。

不是 bug,是 transformer 注意力 + 训练数据分布——开头/结尾在训练数据里更重要(摘要、结论)。Anthropic 在 200K 模型复现,Long context tips 明确建议关键信息放结尾。

三个 root cause — 不只是位置问题

Position bias 最显眼,但 RAG 召回 ≠ 答对有三层原因:

1. Position bias — 中段失明

10 段召回 5 段相关按相关度排序——相关度第 1 不等于 attention 第 1。要主动把最关键那段塞到结尾。

2. Distractor pollution — 干扰段污染

2024 Found in the Middle(He et al.)证明:context 里 distractor 越多(话题相似但不含答案),hallucination 越高——模型把 distractor 的相关名词「拼装」成假答案。

澳洲税务 RAG 召回 10 段:3 段 GST、7 段 income tax。用户问 GST,7 段是 distractor。模型会说「GST 是 ...,还有 income tax 的 ...」——把 income tax 细节当 GST 事实。召回正确也召回相似但错的,等于污染

3. Instruction-following degradation — 长 context 下指令服从下降

Anthropic 200K context 评估文档:context 越长,模型对 system prompt 硬规则服从率越低。50K 下要求 JSON 偶尔漏字段;200K 下漏字段率显著增加。

RAG 多召回的隐藏成本——你以为「多召回更安全」,实际是 system instruction 被冲淡。

Selection ≠ Retrieval

retrieval 找候选,selection 从候选挑真正进 context 的。

阶段任务优化目标工具
Retrieval全量 corpus 找 top-N 候选Recallbi-encoder / BM25 / hybrid
Selection从 top-N 挑 top-K 进 contextPrecision + positionrerank / filter / LLM-judge
Composition把 top-K 排序塞进 promptPosition、token 预算手工 + 模板

入门 RAG 教程只讲 retrieval,top-5 直接塞 prompt——90% recall 但 60% accuracy 的根因。

Selection 的三段式

第 5 章详述工具栈。整体形状:

Stage 1 — Filter(粗筛)

按硬规则去掉:

  • 时效过期(2023 年文档讲 2026 年事)
  • 来源黑名单(CSDN 二手抄文)
  • 长度异常(< 50 或 > 5000 字)

成本极低(O(n)),扔掉 30-50% 候选。

Stage 2 — Rerank(精筛)

用 cross-encoder 重新打分:

  • bi-encoder(retrieval 用)一次只看 query 或 doc,速度快但精度差
  • cross-encoder 同时看 query + doc,精度高 30-50%,成本是 bi-encoder 的 50-100 倍——只对 top-50 用

主流:Cohere rerank-3 / BGE-reranker-v2 / Anthropic contextual retrieval。

Stage 3 — LLM-as-judge(终筛)

用便宜模型(Haiku 或 4o-mini)当 judge:

  • Input: query + 单 doc
  • Output: 真的能回答 query 吗?yes/no + 理由

成本是 rerank 的 5-10 倍,但能 catch rerank 漏掉的「话题相关但答非所问」段落。

三段:retrieval 100 → filter 50 → rerank 10 → judge 3 → 进 context 3 段。recall 不变,distractor 打到 0

JR 真实案例:daily-jobs 的 selection pipeline

JR Academy 每天 3 个 daily-jobs routine 跑(给 ai-essentials / ai-engineer / ai-engineer-rag bootcamp 学员推荐 3 个岗位):

# tested: 2026-04-26 · routine: Daily Jobs - AI Engineer Bootcamp

Stage 0: 抓取(retrieval)
  WebFetch au.linkedin.com/jobs/junior-machine-learning-jobs
  WebFetch au.linkedin.com/jobs/ai-engineer-jobs
  → 抓回约 30 个 job

Stage 1: Filter(硬规则)
  剔除 recruiter spam(YO IT Consulting 这类同 job 多 location 群发)
  剔除 SEEK 来源(403 默认无效)
  剔除发布 > 7 天
  → 剩约 18 个 job

Stage 2: Rerank(按 tier 标签)
  打 3 个 tier 标签:
    aspirational(理想档 — Mid-Senior + T0/T1 brand)
    actionable(够得着档 — Junior/Graduate + AU Big 4)
    special(特殊机会 — Intern / Graduate Program / 2026-27 Start)
  → 每 tier 留 top 3-5 候选

Stage 3: LLM-as-judge(人称代入)
  以「JR Bootcamp 学员视角」给每个候选写 whyForLearners
  ≥ 30 字、必须具体、不允许模板填空
  → 每 tier 选 1 个最佳 → 共 3 个 final

最终 context 进 prompt:3 个 job 全文 + 3 个 whyForLearners

不是 fancy 算法——三段过滤 + 一个判断模型。出来的 3 个 job 都通过 distractor 筛选 + position 排序(tier 就是 position 信号)。

学员看到的不是「30 抓回选 3」,是「精挑 3 个对你有意义的」——selection 的产品价值。

多召少筛 vs 少召多筛 — Trade-off

维度多召 + 弱筛少召 + 强筛
Recall高(top 50 ≥ 95%)中(top 10 ≈ 75-85%)
Selection 工程量三段式 + LLM judge一段 rerank 即可
Token 成本高(50 段过 rerank)低(10 段直接进 prompt)
延迟+2-5 秒+200ms
Distractor 风险高,必须强筛低,但漏召高
适合知识库 QA(90%+ 准确率)实时对话(延迟敏感)
不适合实时聊天严肃合规(漏召不能接受)

JR 经验:对外 production RAG 走多召强筛,对内工具走少召弱筛。延迟、成本、质量要求都不一样。

一句话带走

Recall 是 retrieval 的事,accuracy 是 selection 的事。top-10 直接塞 prompt 是 toy demo;production RAG 必须分 retrieval / selection / composition 三段。中间那段是 90% recall 到 90% accuracy 之间的工程量。


引用来源

  1. Liu et al. (2023-07-06). Lost in the Middle. arXiv:2307.03172.
  2. He et al. (2024-03-08). Found in the Middle. arXiv:2403.04797.
  3. Anthropic. Long context tips.
  4. Anthropic. (2023-05-11). 100K context windows.
  5. Liu. GitHub: lost-in-the-middle.

Production case: JR Academy omni-report Daily Jobs — 三段 selection pipeline.

📚 相关资源

❓ 常见问题

关于本章主题最常被搜索的问题,点击展开答案

RAG 召回率 90% 但答对率只有 60%,问题在哪?

90% recall = top-k 里有正确答案但 LLM 没用上,三个原因:(1) Lost in the Middle 注意力衰减、(2) distractor 段落污染、(3) 长 context 下 instruction-following 下降。解法是加 selection 层,不是继续调 retrieval。

Selection 和 Rerank 是同一回事吗?

Rerank 是 selection 的一段,不是全部。完整 selection 三段:filter(硬规则去时效/来源/长度异常)→ rerank(cross-encoder 精筛)→ LLM-as-judge(Haiku/4o-mini 终筛)。100 候选 → 3 个真进 prompt。

什么时候不需要做 selection?

三个条件同时满足才能跳:实时聊天助手 + 召回数 ≤ 5 + 延迟敏感。否则 production RAG 必须做 selection。JR 内部规则:对外学员侧多召强筛,对内仪表盘少召弱筛。

Selection 一套上完整 pipeline 一个月成本多少?

10K query/天规模:Cohere rerank $30/月 + LLM-as-judge (Haiku) $300/月 + 向量库 Pinecone Standard $70/月 = ~$400/月。换 BGE 自托管 + Haiku 判断 = ~$120/月(不含 GPU 摊销)。比不做 selection 省下的 LLM input token 成本通常 5-10× 回本。

做企业内部知识库该不该上 selection?

该上。企业 KB 文档来源杂(Confluence / Slack / Google Doc 老版本),distractor 比公网 RAG 更严重。第一步先加 LLM-as-judge 一层,单 query $0.0005 即可把召回准确率从 60% 拉到 85%+。Filter + rerank 是后续优化。

Selection 最常见的失败模式是什么?

把 selection 做成「再排一次序」而不是「真砍掉」。100 候选 rerank 完仍塞 top-20 进 prompt = 没做 selection。正确做法:rerank 完按 score 阈值(< 0.3 直接扔)+ 硬上限 top-3 至 top-5。砍不下去就是没做。