07-Rerank 与上下文工程:怎么把候选证据整理给大模型
上一篇讲检索增强时,重点放在 Query Rewrite、Hybrid Search 和多路召回。它们共同解决的是证据入口问题:让正确证据尽量进入候选池。
07-Rerank 与上下文工程:怎么把候选证据整理给大模型
上一篇讲检索增强时,重点放在 Query Rewrite、Hybrid Search 和多路召回。它们共同解决的是证据入口问题:让正确证据尽量进入候选池。
候选池只是中间结果。召回阶段为了覆盖,会主动放宽入口,把语义相似、关键词命中、结构化过滤、不同 query 路径得到的内容都拉进来。这样做可以降低漏召回的风险,也会带来重复、噪声、过期信息、相似但无答案的片段。到了这一篇,RAG 链路要继续往后走:从“可能相关的候选”变成“适合给大模型使用的证据”。
这一层通常由 Rerank 和上下文工程共同完成。Rerank 负责重新判断候选和问题的相关性,把更能回答问题的证据排到前面;上下文工程负责把这些证据去重、合并、压缩、排序、编号,并控制在模型上下文窗口里。
这一篇的核心判断可以先放在前面:
Rerank 决定候选证据的优先级,上下文工程决定证据进入 Prompt 后是否清晰、完整、可引用、少干扰。检索把材料找回来,Rerank 和上下文工程把材料整理成模型可以可靠使用的证据。
从候选池到可用证据
RAG 的在线链路可以粗略分成三段:召回、整理、生成。召回负责扩大覆盖,生成负责输出答案,中间的整理阶段决定模型实际看见什么。
很多 RAG 失败都发生在这个中间层。正确证据已经被某一路召回命中,但因为排序靠后,没有进入最终 topK。候选池里有多个相似 chunk,最终塞进 Prompt 的却是背景介绍,而关键限制条件被挤掉。文档片段本身相关,但离开标题和父级章节以后语义不完整。几个来源互相冲突,系统没有提前标注,模型只能把冲突内容混在一起回答。
这些问题很难靠单纯扩大 topK 解决。topK 变大以后,模型看见的内容更多,噪声也会更多。上下文窗口被重复和弱相关内容占满,答案可能反而更不稳定。更稳的做法,是在召回和生成之间加入细粒度排序与证据整理,让进入 Prompt 的内容更少、更准、更完整。
所以,Rerank 和上下文工程可以理解为 RAG 的证据加工层。它不负责创造知识,也不负责最终表达,而是负责把候选材料变成可被模型使用的证据包。
| 阶段 | 主要责任 |
|---|---|
| 召回 | 扩大覆盖,让正确证据尽量进入候选池 |
| Rerank | 重新排序,让更能回答问题的证据靠前 |
| 上下文工程 | 去重、合并、压缩、编号,让证据可读可用 |
| 生成 | 在证据边界内组织最终回答 |
Rerank 在链路中的位置
召回阶段通常追求速度和覆盖。向量检索用 embedding 近似判断语义相似,BM25 用词项匹配判断文本相关,多路召回再把不同路径的结果合并。这一阶段会尽量把可能有用的内容拉进来。
Rerank 出现在召回之后。它拿到的是一个相对较大的候选集合,例如 50 个、100 个或 200 个 chunk,然后用更细致的方式重新判断 query 和每个候选之间的相关性,输出一组新的排序。
简化链路可以这样看:
用户问题
-> 多路召回
-> 候选 chunk 集合
-> Rerank 重新排序
-> 选出高质量证据
-> 上下文工程整理
-> Prompt
-> 生成答案
这里有一个很重要的职责区分。召回阶段解决**“有没有找回来”,Rerank 阶段解决“谁更应该排在前面”**。正确证据只要没有进入候选池,Rerank 就无能为力;正确证据进入候选池以后,如果排序不够好,Rerank 就有发挥空间。
Rerank 的意义在于,它把粗粒度相似度判断变成更贴近问题的相关性判断。一个 chunk 可能包含很多和主题相关的词,但没有回答用户真正关心的点。另一个 chunk 词面重合较少,却直接给出了操作步骤、限制条件或结论。Rerank 要尽量识别这种差异。
召回分数不能直接决定最终上下文
向量检索返回的相似度分数,经常会被误用成答案相关性分数。这个做法在简单场景里可能可用,在复杂 RAG 里风险很高。
向量相似度衡量的是语义空间里的接近程度。它能说明 query 和 chunk 在主题上接近,但不能保证 chunk 包含答案。一个介绍“权限体系设计背景”的段落,可能和“权限继承怎么配置”很相似;真正回答配置步骤的段落,可能因为写得更具体、更短,向量分数反而略低。
BM25 分数也有类似问题。关键词重合高,说明候选文本包含用户输入中的词,但词面命中和答案有效性之间还有距离。错误码命中了,不代表这个段落给出了解决方案;接口名命中了,也可能只是出现在变更记录里。
多路召回会进一步放大分数问题。向量分数、BM25 分数、结构化检索分数和不同 query 改写路径得到的分数尺度并不一致。把它们直接拼到一起排序,很容易让某一路结果占据过高权重。
因此,召回分数适合用来产生候选,不适合直接决定最终上下文。Rerank 的存在,就是为了在候选基础上做第二次判断,把“相似”进一步推进到“能回答”。
| 分数来源 | 能说明什么 | 不能直接说明什么 |
|---|---|---|
| 向量相似度 | 语义主题接近 | 是否真的包含答案 |
| BM25 分数 | 词面命中强 | 是否给出有效结论或步骤 |
| 多路召回分数 | 某一路径认为相关 | 不同路径之间谁更可信 |
| Rerank 分数 | 与问题的答案相关性更高 | 是否符合版本、权限和来源质量 |
Cross-Encoder 和专门 reranker 的价值
常见的向量检索采用双塔结构。query 和 document 分别编码成向量,再通过相似度计算进行匹配。这种方式速度快,适合大规模召回,但 query 和 document 之间的细粒度交互较弱。
Cross-Encoder 或专门的 reranker 会把 query 和候选文本一起输入模型,让模型直接判断它们之间的相关性。这样可以看到更完整的交互信息,例如问题问的是“如何配置”,候选文本是否真的包含步骤;问题问的是“限制条件”,候选文本是否只是介绍概念;问题带有版本号,候选文本是否匹配同一版本。
这种方式通常更慢,成本也更高,所以它很少用于全量检索。更合理的位置是二阶段排序:先用向量检索、BM25、多路召回拿到一批候选,再用 reranker 对这批候选重新排序。
在实际系统里,Rerank 的输入规模要控制。候选太少,正确证据可能还没进入排序阶段;候选太多,延迟和成本会上升。常见做法是先召回较宽的 topN,再 rerank 出较窄的 topK 给上下文工程。topN 和 topK 需要通过评测集调,而不能只凭经验固定。
Rerank 还要关注模型适配。通用 reranker 可以提供基础能力,但企业知识库、代码文档、法律条款、医学资料、金融制度这类领域材料往往有自己的表达习惯。是否需要领域数据微调,取决于失败样本是否集中在专业术语、长条件、表格信息和复杂问法上。
| 排序方式 | 适合位置 | 主要特点 |
|---|---|---|
| 双塔 embedding | 大规模召回 | 快,但交互判断较粗 |
| Cross-Encoder / reranker | 二阶段排序 | 慢一些,但更能判断是否回答问题 |
| 业务规则排序 | Rerank 前后都可加入 | 处理来源、版本、权限、状态等约束 |
相关性之外还有证据质量
Rerank 经常被理解为相关性排序,但生产系统里,排序不只看相关性。证据能否进入上下文,还要考虑来源质量、时间有效性、版本适配、权限边界、内容完整性和冲突情况。
正式文档、人工审核知识、最新版本说明,通常应该比历史工单、旧 FAQ、自动抓取内容拥有更高优先级。来自相同主题的两个 chunk,如果一个带有明确版本和发布时间,另一个没有来源信息,前者更适合作为最终证据。用户问当前版本的行为,旧版本文档即使语义高度相似,也应该被降权或排除。
这些因素不一定全部交给 reranker 模型判断。更常见的做法,是把模型相关性分数和业务规则结合起来。模型负责判断 query 与 chunk 的语义和答案相关性,系统规则负责处理权限、版本、来源可信度、文档状态和发布时间。
可以把最终排序理解成一个综合评分:
最终优先级 = 相关性 + 来源质量 + 时间有效性 + 版本匹配 + 权限约束 + 多样性控制
这个公式不代表真实系统一定要线性加权,它强调的是排序信号的来源。RAG 给用户的答案来自证据,证据质量本身就是答案质量的一部分。
| 排序信号 | 主要作用 |
|---|---|
| 相关性 | 判断候选是否能回答当前问题 |
| 来源质量 | 区分正式文档、历史问答、自动抓取内容 |
| 时间有效性 | 避免旧文档和过期规则进入答案 |
| 版本匹配 | 保证证据适用于当前产品或接口版本 |
| 权限约束 | 确保用户只能看到有权访问的内容 |
| 多样性控制 | 避免相似 chunk 占满上下文 |
topK 需要动态控制
很多 RAG demo 会固定取 topK,例如检索前 5 个 chunk,直接拼给模型。固定 topK 简单直观,但生产系统里经常不够细。
用户问题的复杂度不同,需要的证据数量也不同。一个事实型问题可能只需要一段文档。一个对比型问题可能需要多个来源。一个排障型问题可能要同时给出错误原因、检查步骤和解决方案。一个政策解释问题还可能需要保留适用条件和例外条款。
因此,topK 更适合根据分数、证据类型和问题意图动态调整。Rerank 分数很高且第一条证据已经完整回答问题时,可以少放一些上下文。分数接近、证据分散、问题需要综合多个来源时,可以适当增加证据数量。若候选分数整体很低,系统应该倾向于拒答或提示信息不足,而非硬塞低质量内容给模型。
topK 还要和 token 预算一起看。不同 chunk 长度差异很大,固定条数不能保证上下文长度可控。一个长表格 chunk 可能占用大量 token,几个短段落可能仍然很轻。上下文工程更适合按 token 预算、证据重要性和结构完整性共同决策。
这里的关键是,topK 不适合只作为配置文件里的固定参数。它影响正确证据是否进入 Prompt,也影响噪声是否干扰模型。合理的 topK 应该来自评测、日志和失败样本分析。
上下文工程的目标是让证据可读可用
Rerank 输出排序之后,系统还要把证据组织成模型能够稳定使用的上下文。这个过程就是上下文工程。
上下文工程要解决的核心问题,是证据进入 Prompt 后是否清晰、完整、紧凑、可引用。它既要照顾模型理解,也要照顾后续追溯。模型需要知道每段证据的正文,系统需要保留来源、标题、文档 ID、时间、版本和引用编号。
一个更适合 RAG 的上下文片段,通常不会只有正文。它应该带着基本结构信息:
[source_id: S1]
title: 权限继承配置说明
section: 空间权限 > 子空间继承规则
version: v2.1
updated_at: 2026-05-18
content: 子空间默认继承父空间权限。若子空间配置了显式授权,以显式授权为准。
这样的上下文比孤立正文更可靠。模型能知道内容属于哪个章节,也能在回答里引用 S1。用户或系统后续可以根据 source_id 回到原文,检查答案是否被证据支持。
上下文工程的目标并非把更多文本塞给模型,而是让模型在有限窗口里看到最有用、最少歧义的证据。这里的“工程”二字很重要,因为它涉及取舍、排序、格式、边界和可观测性。
| 上下文工程动作 | 解决的问题 |
|---|---|
| 去重 | 避免相似内容重复占用窗口 |
| 合并相邻 chunk | 保留前置条件、步骤和例外说明 |
| 压缩 | 控制 token 成本,减少冗余 |
| 排序和布局 | 提高关键证据被模型使用的概率 |
| 引用编号 | 支持答案追溯和证据校验 |
| 冲突处理 | 避免模型强行合并不同版本或条件 |
去重避免上下文被相似内容占满
多路召回和 Rerank 之后,重复内容非常常见。同一个 chunk 可能被向量检索和关键词检索同时命中,同一篇文档里的相邻 chunk 可能都被召回,不同版本文档也可能有大量相似段落。
如果这些重复内容原样进入 Prompt,模型会反复看到近似表达,上下文窗口会被浪费。更麻烦的是,重复证据可能让模型误以为某个片面信息权重更高,因为它在上下文中出现了多次。
去重可以从多个层级做。chunk ID 相同可以直接去掉,文本高度相似可以合并,相邻 chunk 可以按文档结构聚合,同一文档多个片段可以保留最相关段落并补充标题和章节信息。对于多版本文档,去重还要结合版本和时间,保留当前有效版本。
去重不能简化成删除。相邻 chunk 之间可能存在互补关系。一个段落说明前置条件,下一段给出步骤,再下一段写例外限制。此时应该做结构化合并,单纯保留分数最高的一段会丢掉互补信息。上下文工程需要识别重复和互补之间的差异。
合并相邻 chunk 保留语义完整性
chunking 阶段为了检索效率,会把文档切成较小片段。到了上下文阶段,这些片段有时需要重新合并。
单个 chunk 被召回时,可能只包含答案的一部分。比如一个 chunk 写“开启该功能前需要先启用组织级权限管理”,下一个 chunk 才写具体开关位置。只把第二段给模型,答案会缺少前置条件;只把第一段给模型,又没有操作步骤。
这就是父子切分、相邻窗口和上下文补全发挥作用的地方。系统可以用小 chunk 做召回,用父级章节或相邻片段做补充。召回粒度服务于命中,生成粒度服务于表达,两者不一定相同。
合并时要控制边界。把整篇文档都塞进去会引入大量无关内容。更稳的做法,是围绕命中 chunk 向前后扩展少量内容,或者补充它的父标题、表格标题、步骤编号和引用来源。这样既保留语义完整性,又不会让上下文过长。
对于表格、代码块和配置示例,合并尤其重要。表格单元格离开表头就容易失去意义,代码片段离开说明文字也可能让模型误用。文档入库时保留结构信息,到了上下文工程阶段才能把这些内容重新组装出来。
压缩要保留答案支撑点
上下文窗口有限,候选证据太长时需要压缩。压缩的目标是减少冗余,同时保留支撑答案的关键信息。
粗糙压缩很容易造成信息损失。把长段落简单截断,可能删掉例外条件。只保留摘要,可能丢掉具体参数和版本限制。让模型先总结证据再回答,可能在总结阶段就引入偏差。
更稳的压缩方式,是围绕用户问题提取相关句子和关键字段。用户问配置步骤,就保留步骤、前置条件和注意事项。用户问限制条件,就保留阈值、范围、例外和版本。用户问对比差异,就保留对比项和来源。压缩后的内容仍然应该带 source_id,方便答案引用和追溯。
压缩还要保留不确定性。证据里写的是“部分地区灰度开放”,压缩后不能变成“已开放”。证据里写的是“默认 30 秒,可由管理员修改”,压缩后不能只留下“30 秒”。RAG 的上下文压缩如果丢掉限定词,后面的生成会更容易过度确定。
在高风险场景中,压缩可以分层进行。先保留原文片段,再附上面向问题的短摘要,让模型同时看到原始证据和提炼结果。这样可以降低摘要误差对最终答案的影响。
排序和布局会影响模型注意力
证据进入 Prompt 的顺序会影响模型使用方式。最相关证据通常应该靠前,直接回答问题的内容也应该靠前。背景信息、补充说明和低置信候选可以放在后面,甚至不进入上下文。
长上下文里还会出现中间信息被忽略的现象。模型对上下文开头和结尾的信息往往更敏感,中间位置的证据更容易被弱化。因此,把最关键证据随意放在中间并不稳。
上下文布局还要考虑任务类型。步骤类问题适合按执行顺序组织证据。对比类问题适合按对象分组。排障类问题适合按现象、原因、检查项、解决方案组织。政策类问题适合先给结论依据,再给适用范围和例外条件。
这种布局不只是格式问题。它会改变模型读取证据的路径。清晰的证据组织能减少模型自己在上下文里“找答案”的负担,也能降低它把无关信息混进答案的概率。
引用编号让答案可追溯
RAG 和普通聊天生成的重要差异之一,是答案应该能回到证据。引用编号就是这种可追溯性的基础。
如果上下文中的每段证据都有 source_id,模型就可以在回答中标注依据。用户看到结论时,可以知道它来自哪篇文档、哪个章节、哪个版本。系统在做答案校验时,也可以检查回答中的引用是否真的支持对应句子。
引用编号还可以帮助处理多证据答案。一个结论可能来自 S1,另一个限制条件来自 S2。如果答案只给出统一结论却没有来源区分,后续很难判断哪部分被哪段证据支撑。对于企业知识库、法务制度、技术文档和高风险业务,这种追溯能力非常关键。
引用也能暴露证据不足。当模型无法给出引用,或者引用段落无法支持答案时,系统就应该降低置信度。RAG 的可信度不只来自语言流畅,也来自答案和证据之间的可验证关系。
因此,上下文工程要在 Prompt 之前就把 source_id、标题、链接或文档 ID 准备好,不能让模型凭空生成来源。来源信息必须来自检索系统,不能由模型自由编造。
冲突证据要提前处理
候选证据里经常会出现冲突。旧版本文档和新版本文档说法不同,FAQ 和正式手册不一致,历史工单里的临时处理方案已经失效,不同地区政策存在差异。
如果冲突证据未经处理直接进入 Prompt,模型可能会随机选择一边,也可能把两边合并成一个看似合理但实际错误的答案。上下文工程应该尽量在生成前识别冲突,并把冲突边界标清楚。
冲突处理可以结合 metadata。新版本优先于旧版本,正式文档优先于讨论记录,当前租户或地区优先于通用说明,已发布状态优先于草稿状态。对于无法自动判断的冲突,Prompt 应该要求模型说明“资料存在不一致”,并给出各自来源,避免强行给出单一结论。
冲突并不总是错误。有时不同证据适用于不同条件。比如普通用户和管理员权限不同,免费版和企业版限制不同,国内区和海外区策略不同。上下文工程要尽量保留这些条件,让生成阶段可以回答得更有边界。
上下文污染是生成错误的常见来源
检索到了正确证据,答案仍然错误,一个常见原因是上下文被污染。
污染可能来自弱相关内容。它们和主题接近,但没有回答问题。模型读到后可能把背景描述当成结论。污染也可能来自过期内容。旧文档和新文档同时进入上下文,模型可能引用旧规则。还有一种污染来自过度补充,系统为了“保险”塞入很多候选,结果让模型在噪声中做推断。
上下文污染的治理方式,通常比继续调 Prompt 更有效。先减少低分候选,过滤过期版本,合并重复片段,明确证据来源和适用范围,再让模型生成。Prompt 可以约束模型,但如果上下文本身混乱,生成阶段会很吃力。
这也是 Rerank 与上下文工程的价值所在。它们把问题从“模型为什么答错”提前拆成“模型看到了什么证据”。模型看到的证据越干净,后面的生成越稳。
失败排查要看 Rerank 前后变化
排查 RAG 问题时,Rerank 前后的结果非常关键。
如果正确证据没有出现在召回候选里,问题在前面的 query、索引、向量检索、关键词检索或 metadata 过滤。此时调 Rerank 没有意义。
如果正确证据出现在召回候选里,但 Rerank 后排得很低,就要检查 reranker 是否适配领域语料,输入文本是否过短或缺少标题,候选是否被噪声干扰,排序规则是否过度偏向某类来源。
如果正确证据 Rerank 后排得很高,但最终没有进入 Prompt,就要检查 topK、token 预算、去重和截断策略。很多时候,证据已经被系统找到,最后却在上下文打包时丢掉。
如果正确证据进入 Prompt,答案仍然错误,就要继续看上下文是否存在冲突、Prompt 是否要求引用和拒答、模型是否忽略证据、答案是否需要后校验。
这种分层排查比笼统说“RAG 效果不好”更有工程价值。每一步都能通过日志和样本复现,优化方向也更明确。
| 观察位置 | 说明什么 | 优先排查 |
|---|---|---|
| 召回候选里没有正确证据 | 入口阶段失败 | query、索引、向量检索、关键词检索、metadata filter |
| 召回候选里有,但 Rerank 后靠后 | 排序阶段失败 | reranker 适配、输入文本、来源权重、排序规则 |
| Rerank 后靠前,但没进 Prompt | 上下文打包失败 | topK、token 预算、去重、截断策略 |
| 已进 Prompt,但答案仍错 | 生成或证据组织失败 | 上下文冲突、Prompt 约束、引用、拒答和后校验 |
小结
Rerank 与上下文工程处在 RAG 的关键中间层。召回阶段把候选材料找回来,Rerank 负责判断哪些候选更能回答问题,上下文工程负责把这些候选整理成模型可用的证据包。
Rerank 的重点在于二阶段排序,把粗粒度相似度推进到更贴近答案相关性的判断。它要和来源质量、版本有效性、权限约束、文档状态等业务规则配合,而不能只看模型分数。
上下文工程的重点在于证据组织。去重避免窗口浪费,合并相邻 chunk 保留语义完整性,压缩控制 token 成本,排序和布局影响模型注意力,引用编号保证可追溯,冲突处理减少生成阶段的误判。
理解这一层以后,再看 RAG 的幻觉治理会更自然。很多幻觉并非只来自模型“乱编”,也来自前面给它的证据不完整、不干净、不一致或不可追溯。下一篇进入幻觉治理时,核心就会落到引用、拒答、证据约束和答案校验上。