关于 context-ranking
此技能为检索到的文本片段排序,供检索增强生成流程构建更相关且多样的上下文。它结合初筛评分、交叉编码器重排和多样性选择,并附上分数与置信等级。
主要功能
- 01融合 BM25 与语义相似度
- 02使用交叉编码器重排
- 03通过 MMR 减少内容重复
- 04组合相关性与领域加权评分
- 05附加来源、分数和置信等级
适用场景
- 01筛选代码搜索结果以排查故障
- 02为文档问答挑选相关片段
- 03为多主题查询生成多样上下文
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ seb1n/ awesome-ai-agent-skills --skill context-ranking安装后在 Claude Code 中输入/context-ranking确认已加载。
详细介绍
上下文排序
上下文排序是指对检索到的文本块进行排序,让最相关、多样且有用的信息排在前面。在任何检索流水线中,初始搜索都会返回大量候选项——其中许多与查询只有间接关联。排序会将这个无序的候选集合转换为按优先级排列的列表,使后续步骤(上下文组装、提示词构建)能够选出最合适的材料并舍弃其余内容。有效的排序是答案有据可依、准确精炼,还是模糊且偏题的关键所在。
工作流
-
收集候选文本块:从搜索层收集初始检索到的文本块。通常是向量搜索、关键词搜索或混合搜索返回的前 k 个结果(k = 15-30)。每个文本块都带有初步分数(例如余弦相似度或 BM25 分数)和来源元数据。
-
应用第一阶段评分:使用快速、轻量的算法为每个候选项评分。BM25 是评估关键词相关性的标准选择;查询嵌入与文本块嵌入之间的余弦相似度是评估语义相关性的标准方法。在混合流水线中,同时计算这两种分数,并使用倒数排名融合(RRF)或加权线性组合将它们合并。此阶段旨在快速处理所有候选项。
-
使用交叉编码器重新排序:将第一阶段中排名靠前的候选项(通常为 15-25 个)输入交叉编码器重排序器。双编码器嵌入会分别评估查询和文档,而交叉编码器会通过完整注意力机制同时处理查询和文本块,从而生成准确得多的相关性分数。常用模型包括 Cohere Rerank、
bge-reranker-v2-m3或 ColBERTv2。此步骤速度较慢,但能大幅提升准确率。 -
应用多样性选择:重新排序后,排名靠前的结果可能集中在同一个子主题上,导致查询的其他方面未被覆盖。应用最大边际相关性(MMR)或类似的多样性算法,对与已选文本块过于相似的文本块进行惩罚。这可确保最终排序列表涵盖查询的多个方面,而不只是最明显的解读。
-
分配最终分数并排序:将重排序器的相关性分数与多样性惩罚及任何特定领域的加权信号(例如新近度加权、来源权威性权重)合并为最终综合分数。根据该综合分数按降序排列文本块。排名前 n 的文本块(n = 3-7)构成最终排序后的上下文,并会注入提示词中。
-
附加元数据和置信度:为每个排序后的文本块标注最终分数、来源路径和置信度等级(高 / 中 / 低)。这些元数据有助于后续的提示词组装步骤决定如何呈现上下文,并帮助模型在引用来源时校准置信度。
核心概念
- BM25:一种基于词频、逆文档频率和文档长度归一化的概率关键词匹配算法。擅长匹配精确词项和罕见关键词。速度快且易于解释,但无法识别同义词和改述内容。是关键词搜索的标准第一阶段排序算法。
- 余弦相似度:衡量两个嵌入向量之间的夹角。取值范围为 -1 到 1,值越高表示语义相似度越高。是语义搜索的标准第一阶段排序算法。其质量很大程度上取决于所用的嵌入模型。
- 交叉编码器重排序:一种以查询和文档的拼接内容作为输入,并输出相关性分数的 Transformer 模型。由于它会在查询和文档词元之间应用完整的交叉注意力,因此能捕捉双编码器遗漏的细粒度相关性。通常比余弦相似度慢 5-20 倍,但排序效果显著更好。
- 最大边际相关性(MMR):一种通过平衡内容块与查询的相关性及其与已选内容块之间的冗余度,迭代选择内容块的算法。由 lambda 参数控制:lambda = 1.0 表示完全按相关性选择,lambda = 0.0 表示完全按多样性选择,取值在 0.5-0.7 左右时则兼顾两者。对于多方面查询至关重要。
- 倒数排名融合(RRF):一种用于混合搜索的分数合并方法。对于每个内容块,针对每个排序来源计算 1/(k + rank),然后求和。这样可生成融合排序,并能有效应对 BM25 和余弦相似度之间的分数量纲差异。
用法
提供查询和候选文本内容块列表(可选提供初步分数和元数据)。该技能会对内容块进行评分、重排序和多样化处理,并返回包含最终分数和置信度等级的排序列表。指定所需的输出内容块数量(top-n)和可选的多样性参数(MMR lambda)。
示例
示例 1:为调试查询排序代码搜索结果
查询:“为什么 WebSocket 连接在闲置 60 秒后断开?”
候选文本块(来自混合搜索,前 8 个):
| # | 来源 | BM25 | 余弦相似度 | 内容摘要 |
|---|---|---|---|---|
| 1 | src/ws/server.ts:40-65 | 12.4 | 0.88 | WebSocket 服务配置,包含 pingInterval: 30000 和 pingTimeout: 60000 |
| 2 | src/ws/server.ts:80-95 | 8.1 | 0.82 | 连接清理处理程序,会记录“连接超时” |
| 3 | docs/websocket.md:15-30 | 6.3 | 0.79 | 文档:“连接通过 ping/pong 保持活动状态。默认超时时间为 60s。” |
| 4 | src/ws/client.ts:10-35 | 5.7 | 0.84 | 客户端 WebSocket 封装——未实现 pong 响应处理程序 |
| 5 | nginx.conf:22-28 | 9.8 | 0.71 | Nginx 代理配置:WebSocket 上游的 proxy_read_timeout 60s |
| 6 | CHANGELOG.md:44-50 | 3.2 | 0.55 | “v2.1:修复了 WebSocket 重连逻辑”——没有超时详情 |
| 7 | src/ws/server.ts:100-120 | 4.5 | 0.76 | WebSocket 消息的速率限制中间件 |
| 8 | package.json:15-20 | 2.1 | 0.45 | "ws": "^8.14.0" 依赖项 |
交叉编码器重排后:
| 排名 | # | 重排器评分 | 原因 |
|---|---|---|---|
| 1 | 1 | 0.96 | 直接显示了 60s 超时配置 |
| 2 | 5 | 0.93 | Nginx 代理超时——60s 连接断开的另一个原因 |
| 3 | 4 | 0.89 | 客户端缺少 pong 处理程序——解释了 ping 为什么会失败 |
| 4 | 2 | 0.85 | 清理处理程序证实了超时行为 |
| 5 | 3 | 0.78 | 文档印证了 60s 的默认值 |
| 6 | 7 | 0.42 | 速率限制——关联性较弱 |
| 7 | 6 | 0.30 | 更新日志——没有有用的细节 |
| 8 | 8 | 0.15 | Package.json——无关 |
MMR 多样性选择后(前 5 个,lambda=0.6):
src/ws/server.ts:40-65(评分 0.96)——服务端 60s 超时配置nginx.conf:22-28(评分 0.93)——Nginx 代理 60s 读取超时(问题的另一个来源)src/ws/client.ts:10-35(评分 0.89)——客户端缺少 pong 处理程序(客户端侧根本原因)src/ws/server.ts:80-95(评分 0.85)——清理处理程序证实了超时行为docs/websocket.md:15-30(评分 0.78)——文档确认了 60s 的默认值
排序列表涵盖了三个不同的原因(服务配置、Nginx 代理、客户端 pong 处理程序),并包含清理处理程序和文档提供的佐证。
示例 2:为问答任务排序文档文本块
查询:“如何为我的组织配置 SAML 单点登录?”
候选文本块(来自向量搜索的前 6 个):
| # | 来源 | 余弦相似度 | 内容摘要 |
|---|---|---|---|
| 1 | docs/sso/saml-setup.md | 0.91 | SAML 配置分步指南:元数据 URL、证书上传、属性映射 |
| 2 | docs/sso/overview.md | 0.85 | 单点登录选项概览:SAML、OIDC、LDAP。高层次比较。 |
| 3 | docs/sso/saml-setup.md | 0.83 | SAML 错误排查:签名无效、时钟偏差、缺少 NameID |
| 4 | docs/sso/oidc-setup.md | 0.80 | OIDC 配置指南——不是 SAML |
| 5 | docs/admin/org-settings.md | 0.77 | 组织设置页面:查找单点登录配置面板的位置 |
| 6 | blog/sso-announcement.md | 0.72 | 宣布单点登录功能上线的博客文章——营销文案,没有设置详情 |
交叉编码器重排和 MMR 处理后(前 4 个,lambda=0.7):
docs/sso/saml-setup.md(设置指南,评分 0.95)——直接解答:SAML 配置分步指南docs/admin/org-settings.md(评分 0.82)——如何进入单点登录设置(不同文档,可补充 #1)docs/sso/saml-setup.md(故障排查,评分 0.79)——预先说明用户可能遇到的常见错误docs/sso/overview.md(评分 0.71)——提供有关单点登录选项的更广泛背景信息
文本块 4(OIDC 指南)因与 SAML 无关而被筛除。文本块 6(博客文章)因信息密度低而被筛除。
最佳实践
- 始终进行重排序——不要仅依赖嵌入余弦相似度或 BM25 进行最终排序。基准测试表明,对排名前 15-25 的结果使用交叉编码器重排序器,可稳定地将精确率提高 15-30%。
- 第一阶段评分采用混合方式——通过 RRF 结合 BM25 和余弦相似度,其效果优于单独使用任一方式,尤其适用于同时包含具体词语和一般意图的查询。
- 对多方面查询使用 MMR——诸如“X 的成因是什么,该如何解决?”的查询包含两个子意图。如果不进行多样性选择,排名靠前的结果可能全都涉及成因,却没有任何结果涉及解决方法。
- 调整 MMR 的 lambda 参数——从 lambda = 0.6 开始(略微偏重相关性而非多样性),再根据具体用途进行调整。事实型问答适合较高的 lambda(0.7-0.8),而探索性研究适合较低的 lambda(0.4-0.5)。
- 缓存重排序器结果——交叉编码器推理成本较高。如果相同的查询-文本块组合反复出现(多轮对话中很常见),请缓存重排序器的分数,避免重复计算。
- 使用 NDCG 和 MRR 进行评估——在带标签的测试集上使用归一化折损累计增益和平均倒数排名来衡量排序质量。对于排序评估,这些指标比简单的 Recall@k 更有参考价值。
边缘情况
- 分数相同:当多个文本块获得相同或近似相同的重排序器分数时,可优先选择来自更权威来源、文档更新、更近期或信息密度更高的文本块,以打破平局。
- 单结果查询:有些查询在语料库中恰好只有一个相关文本块。排序流程仍应正常工作——重排序器应为该文本块打出较高分数,MMR 也不应因其缺乏多样性而对其进行惩罚。
- 对抗性或含噪文本块:网页抓取内容或用户生成内容可能包含 SEO 垃圾信息或无关的关键词堆砌,从而抬高 BM25 分数。交叉编码器重排序器通常能很好地处理这种情况,但可考虑在预处理阶段添加质量过滤步骤。
- 跨语言查询:当查询语言与语料库语言不同时,请确保嵌入模型和重排序器支持跨语言匹配,或在排序前添加翻译步骤。
- 超大型候选集(100+):如果初始检索返回数百个候选项,请在交叉编码器之前添加中间过滤步骤(例如,按分数阈值截断),以控制重排序延迟。