RAG 检索结果太多时怎么用 reranker 控制上下文长度
RAG 检索结果太多时,最稳妥的做法不是把向量检索的 top_k 直接塞进提示词,而是把流程拆成“扩大召回、reranker 重排、按 token 预算装配”三层。比如先召回 30 个片段,再用 reranker 排出相关性顺序,最后只装入不超过 3000 token 的 5~8 个片段。这样既保留了召回的余量,也不会让无关内容挤占模型真正需要的上下文。
reranker 负责回答“哪些片段更相关”,不负责回答“还能放多少文字”。最终上下文数量必须由 token 预算、单片段长度和重复来源共同决定。
- 向量召回的 top_k 是候选池大小,不是最终上下文数量。
- reranker 先给候选片段排序,再按分数、token 和来源去重做二次筛选。
- 日志至少记录召回数、重排数、最终片段数、累计 token 和被跳过原因。
先把召回数和上下文预算分开
向量检索适合快速缩小范围,但它通常只根据 embedding 相似度做初筛。查询中同时出现“安装失败”“权限”和“回滚”时,相关片段可能分散在多个 chunk 中,top_k 过小会在第一层就丢证据。因此可以让召回池略大一些,再把更昂贵的 reranker 用在这批候选上。
| 环节 | 建议记录 | 它解决什么问题 |
|---|---|---|
| 向量召回 | top_k=30 | 避免候选池过窄 |
| reranker | 保留 15~20 个排序候选 | 把 query 与片段放在一起判断相关性 |
| 上下文装配 | 预算 3000 token,约 5~8 个片段 | 控制提示词长度和重复内容 |

这里的数字只是起始配置,不是通用标准。长文档、短问句和多轮对话的预算完全不同。生产环境应把输入提示、历史消息、工具说明和模型输出预留一起算入,而不是只给检索片段留一个孤立的上限。
reranker 只做相关性排序
reranker 可以理解为一个把“查询+候选片段”放在一起打分的模型适配器。Hugging Face 的 Transformers 文档把文本分类模型的推理结果表示为标签和分数,也支持用 tokenizer 截断输入;项目可以据此封装自己的 pair scorer。下面的代码故意不绑定某个模型名称,避免把一个 checkpoint 当成所有语料的答案。
from dataclasses import dataclass
@dataclass
class Chunk:
text: str
source: str
vector_score: float
rerank_score: float = 0.0
def rerank(query: str, chunks: list[Chunk], pair_scorer) -> list[Chunk]:
# 让重排模型同时看到查询和片段,而不是只比较两个向量分数。
pairs = [[query, chunk.text] for chunk in chunks]
scores = pair_scorer(pairs)
for chunk, score in zip(chunks, scores):
# 分数只用于当前查询内排序,不跨查询比较阈值。
chunk.rerank_score = float(score)
return sorted(chunks, key=lambda item: item.rerank_score, reverse=True)
重排后仍然要保留来源、chunk_id 和原始分数。它们是后面做去重、调参和排查“为什么答案缺证据”的依据。不要因为 reranker 给出了 0.82 就直接认为它能占用 820 个 token;分数和长度是两条独立的轴。
按分数和 token 双门槛选最终片段
最终装配可以采用一个简单的贪心策略:按 rerank_score 从高到低浏览候选,遇到过长片段先跳过;如果来源已经出现且还有其他来源可选,也先跳过;只有累计 token 不超过预算时才加入上下文。
def choose_context(ranked, tokenizer, context_budget=3000, per_chunk_limit=700):
# 预留系统提示、历史消息和模型输出,检索片段不要吃满窗口。
used_tokens = 0
selected = []
seen_sources = set()
for chunk in ranked:
# 先截断超长片段,避免一个 chunk 吞掉整个预算。
text = chunk.text[:per_chunk_limit]
token_count = len(tokenizer.encode(text, add_special_tokens=False))
if token_count == 0 or used_tokens + token_count > context_budget:
continue
# 同一文档重复命中时,优先保留分数更高的第一段。
if chunk.source in seen_sources:
continue
selected.append({"text": text, "source": chunk.source,
"score": chunk.rerank_score})
seen_sources.add(chunk.source)
used_tokens += token_count
return selected, used_tokens
代码中的 `per_chunk_limit` 是字符截断示意,真正项目应使用同一个 tokenizer 计算截断位置,否则中文、代码和中英混排会产生偏差。若业务允许同一来源出现多段,可以把 `seen_sources` 换成来源配额,例如每个来源最多两段。

四个容易让结果变差的参数坑
- 召回太窄:reranker 只能重排手里已有的候选,第一层没有召回的证据不会凭空出现。
- 跨查询比较分数:不同问题的分布可能不同,固定写死“分数低于 0.7 就丢弃”需要先用业务数据校准。
- 片段过长:一段包含多个主题时,重排分数可能不错,但会挤掉更短、更聚焦的证据。
- 只看最终条数:5 个片段可能有 500 token,也可能有 5000 token;必须同时记录累计 token 和跳过原因。
排查时建议输出一条结构化日志:`retrieved=30 reranked=20 selected=6 used_tokens=2764 skipped_by_budget=8 skipped_by_source=3`。这条日志不能证明答案一定正确,但能快速说明问题发生在召回、重排还是上下文装配阶段。
RAG 上下文控制常见问题
reranker 能不能直接决定最终 top_n?
它可以提供排序依据,但最终 top_n 仍要经过 token 预算和片段长度约束。固定 top_n 适合做初始实验,不适合作为唯一闸门。
为什么把 top_k 从 10 调到 50 后反而变慢?
候选变多会增加 reranker 的 pair 推理量;可以先限制重排候选数,或批量推理,再观察召回收益是否值得这部分成本。
应该按 rerank 分数还是向量分数截断?
初筛用向量分数,最终排序通常用 rerank 分数;不要把两种分数当作同一量纲,更不要未经校准直接相加。
上下文不够时优先删哪类片段?
先删重复来源、低分且过长的片段,再检查是否保留了至少一个直接回答问题的高分证据;同时记录每次删减原因,方便回放。
Go 关闭已经关闭的 channel 为什么会 panic
- 上一篇
- Go 关闭已经关闭的 channel 为什么会 panic
- 下一篇
- Go 怎么逐段解析带注释的配置文本
-
- 科技周边 · 人工智能 | 4小时前 |
- RAG 处理 PDF 表格时怎么避免只提取正文文本
- 244浏览 收藏
-
- 科技周边 · 人工智能 | 6小时前 |
- AI 问答结果波动大时怎么固定评测提示和数据集
- 215浏览 收藏
-
- 科技周边 · 人工智能 | 7小时前 | 人工智能 · rag · 模型评测 · RAG 召回率 evaluation Context Recall Answer Correctness 答案正确率
- RAG 评测怎么分别统计召回率和答案正确率
- 293浏览 收藏
-
- 科技周边 · 人工智能 | 9小时前 | 人工智能 · ai agent · json schema · 工程实践 · 函数调用 · 参数校验 AI Agent JSON Schema 工具调用 tool use
- AI Agent 工具参数经常缺字段时怎么收紧 schema
- 316浏览 收藏
-
- 科技周边 · 人工智能 | 10小时前 | rag · embedding · 向量库 · embeddings
- 向量库维度不一致报错时怎么检查 embedding 配置
- 498浏览 收藏
-
- 科技周边 · 人工智能 | 13小时前 |
- RAG 混合检索结果重复时怎么做去重和排序
- 244浏览 收藏
-
- 科技周边 · 人工智能 | 14小时前 |
- RAG 只用向量检索找不到精确编号时怎么加混合检索
- 320浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 26次使用
-
- SuperCLUE
- SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
- 179次使用
-
- C-Eval
- 深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
- 117次使用
-
- AI Prompt Library
- 探索AI Prompt Library免费资源库,涵盖营销、写作及多场景AI提示词。兼容ChatGPT、Claude等工具,一键复制优化输出,提升工作效率。
- 41次使用
-
- Generrated
- Generrated汇集9300+张DALL·E生成图像及对应提示词,支持查看完整图集、对比DALL·E 2与3版本差异,是AI绘图新手学习Prompt设计与获取创作灵感的实用工具。
- 23次使用
-
- 本地大模型反复输出同一句话怎么调整生成参数
- 2026-09-06 501浏览
-
- Python 调用大模型时如何用结构化输出校验 JSON:从解析失败到可重试
- 2026-08-29 501浏览
-
- AI写作工具免费版安装教程(含豆包Clawdbot)
- 2026-05-30 501浏览
-
- WPS AI能自动生成PPT吗?输入主题一键制作演示文稿
- 2026-05-27 501浏览
-
- Canva手机闪退解决方法及适配指南
- 2026-05-25 501浏览

