登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  科技周边 >  人工智能

RAG 检索结果怎样设置召回和重排的 Top K

来源:17golang原创

时间:2026-10-15 02:29:18 491浏览 收藏

我在调 RAG 检索链路时,最容易混在一起的是三个“数量”:召回阶段取多少候选、reranker 重排多少候选,以及最后交给生成模型多少片段。它们不是同一个 Top K。一个稳妥的起点是先让召回 top_k 留出覆盖率余量,再用 rerank_k 控制 Cross-Encoder 的计算预算,最后用 context_k 或 token 上限约束生成输入。不要把召回的前 5 条直接当成最终上下文。

要点速览
  • top_k 负责“别太早漏掉正确片段”,通常应大于最终上下文数。
  • rerank_k 负责“让更贵的模型看多少候选”,它受延迟和吞吐约束。
  • 最终数量要结合去重、来源覆盖、token 预算和 Recall@K、nDCG 等指标调节。

先拆开 top_k、rerank_k 与 context_k

Sentence Transformers 的 Retrieve & Re-Rank 文档把链路分成两段:先用高效检索器拿到较大的候选集合,再用 Cross-Encoder 对候选逐条打分。Hugging Face 的 RAG 配置也把检索文档数作为独立参数 n_docs。工程里最好再加一个最终上下文数量,形成三个边界:

参数所在阶段主要目标常见代价
top_k向量/关键词召回提高候选覆盖候选传输和后续排序输入变大
rerank_k重排模型提高候选顺序质量Cross-Encoder 延迟和显存增加
context_k拼接提示词控制生成上下文过小会丢证据,过大会稀释重点
RAG 召回 top_k、重排 rerank_k 和生成 context_k 的三层边界说明图
图1:RAG 三段 Top K 的静态结构说明图,展示候选集合、重排预算和上下文边界,不是运行截图。

用候选覆盖率确定召回 top_k

召回阶段先问一个更实际的问题:标注答案所需的片段,有多大概率进入候选集?如果正确片段在这里已经被截掉,后面的 reranker 再强也无法补回来。先固定一组带标准证据的查询,记录 Recall@K,再逐步增大 K;优先选择覆盖率明显趋于平缓、但延迟仍可接受的拐点。

例如,内部知识库可以从 top_k=20 开始,比较 20、40、80 的候选覆盖,而不是直接照搬某个框架的默认值。文档重复、切块过短或查询改写不足时,单纯增大 K 只会把相似噪声一起放大;这时应先检查 chunk 边界、元数据过滤和混合检索召回。

用重排预算确定 rerank_k

重排不是“再取一次前 K”,而是让更昂贵的模型同时观察查询与候选文本。它通常比向量相似度更能处理词面相近但答案不对的片段,却不适合对整个文档库逐条计算。因此 rerank_k 应满足 最终上下文数 ≤ rerank_k ≤ top_k,并通过延迟预算决定上限。

# 这是参数关系示例:先扩大召回,再限制重排和上下文成本
top_k = 50       # 召回候选,优先保证正确片段进入候选集
rerank_k = 30    # 只让重排模型处理其中一部分,控制 P95 延迟
context_k = 6    # 只把最终证据片段送入生成模型,避免上下文膨胀

# 生产代码还应记录 query_id、阶段耗时和每阶段候选数量,便于回滚调参
assert context_k 

这组数字不是通用答案。若 reranker 很小、查询量很高,可以降低 rerank_k;若答案依赖多个分散来源,则应保留更大的重排候选,并在最终阶段做去重和来源配额。

RAG reranker 重排预算与最终证据选择的静态关系图
图2:重排候选、Cross-Encoder 预算和最终证据片段之间的静态关系说明图。

把最终上下文数量单独限住

最后不要只按分数截断。高分片段可能来自同一段落,或者都来自同一个来源,结果看起来相关,却没有覆盖问题的不同条件。生成前可以按文档 ID、来源、章节和相似度做轻量去重,再用 token 上限裁剪。对“定义型”问题,较小的 context_k 往往足够;对需要比较多个版本或多个步骤的问题,宁愿增加来源覆盖,也不要只堆同一文档的近邻片段。

我通常把调参记录成一张小表:固定查询集,分别改变一个 K,观察证据召回率、最终答案命中率、平均延迟和 P95。线上先灰度一组新参数,遇到长查询、空召回或 reranker 超时,再按阶段日志定位,而不是笼统地把三个 K 一起调大。

常见问题

top_k 越大,答案一定越准吗?

不一定。它只能提高正确片段进入候选集的机会,后续重排、去重和上下文截断仍可能丢失证据;噪声过多还会增加延迟。

rerank_k 可以大于 top_k 吗?

在同一条链路里不应大于 top_k,因为重排只能处理已经召回的候选。若需要更多候选,应先扩大召回范围。

如何判断应该调哪个 K?

正确证据没进候选集,调召回 top_k 或检索器;证据已在候选集但排序靠后,调 rerank_k 或重排模型;证据正确但提示词过长,调 context_k、去重和 token 预算。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>