拆解 Context Ranking Skill 的 5 個反直覺設計

作者:努力撞蘑菇AI
日期:2026年5月7日 上午4:54
來源:WeChat 原文

整理版優先睇

速讀 5 個重點 高亮

Context Ranking Skill 五個反直覺設計:搜到不等於排好

整理版摘要

呢篇文章係由專注 AI Agent 深度實踐嘅努力撞蘑菇AI寫嘅,佢拆解一個來自 GitHub 倉庫 h4vzz/awesome-ai-agent-skills 嘅 context-ranking Skill。作者想解決嘅問題係:好多 RAG 系統只用向量搜索,但餘弦相似度只係睇字面相似,唔識判斷資訊有冇用,結果 AI 回覆「飄咗」。整體結論係:Ranking 流程分六步,當中五個設計反直覺但工程上有效,可以大幅提升檢索精準度同多樣性。

文章先講「搜到」同「排好」嘅差距,再介紹完整工作流:收集候選、BM25+餘弦快速過濾、Cross-Encoder 精排、MMR 多樣性選擇、合併分數同加置信度分級。然後逐一拆解五個設計決策:第一階段用便宜模型快速過濾而非精確、Cross-Encoder 靠全局 Attention 比嵌入相似度精準 15-30%、MMR 解決相關但冗餘嘅問題、緩存 Cross-Encoder 結果唔只省錢仲減時延、置信度分級係俾 LLM 校準輸出用。最後作者話 Ranking 係放大器,但知識質量始終喺上游。

  • RAG 系統中「搜到」同「排好」係兩回事,Ranking 先係決定邊個片段上台嘅關鍵
  • 工作流六步:快速過濾、精排、多樣性、合併、置信度,每一步解決不同問題
  • BM25+餘弦相似度用 RRF 合併排名,避開量綱問題;Cross-Encoder 精排比嵌入相似度精準 15-30%
  • MMR 用 lambda 參數平衡相關性同多樣性,事實性問答用高 lambda,探索性用低 lambda
  • 緩存 Cross-Encoder 結果減少時延,置信度分級幫 LLM 判斷點樣引用資訊
值得記低
連結 github.com

awesome-ai-agent-skills 倉庫

收錄 70+ AI Agent Skill,包括 context-ranking

Skill

context-ranking SKILL.md

完整流程同參數建議,包括 RRF、MMR lambda、Edge Cases 處理

整理重點

向量搜索嘅陷阱:餘弦相似度唔識分好壞

你問「WebSocket 點解 60 秒後自動斷開?」向量搜索可能因為 package.json 有「60」同「WebSocket」就俾高分,但實際要睇 Nginx 配置同客戶端 pong 處理。呢個就係餘弦相似度嘅盲點:佢只係睇方向似唔似,唔理資訊有冇用。

餘弦相似度衡量嘅係「方向相似」,唔係「資訊有冇用

整理重點

六步工作流:由快至精,由精到多樣

成個 Ranking 流程分六步,每一步都有清晰輸入輸出,冇一步係「順手加」嘅。

context-ranking 工作流 text
Step 1: 收集候選片段(來自向量搜索嘅 top-15 到 top-30)
 ↓
Step 2: 第一階段快速評分(BM25 + 餘弦相似度)
 ↓
Step 3: Cross-Encoder 精排(對前 15-25 個候選深度打分)
 ↓
Step 4: MMR 多樣性選擇(去掉重複,保留覆蓋面)
 ↓
Step 5: 合併最終分數(相關性 + 多樣性 + 領域加權)
 ↓
Step 6: 附加元數據和置信度分級(high / medium / low)

第一階段解決速度,第三步解決精度,第四步解決覆蓋面,最後兩步解決可解釋性。呢個設計令成個流程可以落地。

整理重點

反直覺①:第一階段唔係為精確,係為快;反直覺②:Cross-Encoder 點解咁準

第一階段用 BM25 + 餘弦相似度呢兩個「便宜模型」,係有原則嘅妥協

如果一開始就用 Cross-Encoder 跑曬所有候選,時間成本頂唔順。BM25 同餘弦相似度夠快,召回率夠高,漏掉真正相關片段嘅機會好細。佢哋用 RRF 合併排名,避開量綱問題——因為 BM25 係概率打分,餘弦係角度值,直接加權會出錯。

RRFReciprocal Rank Fusion)將兩個模型嘅排名位次合併,繞過量綱問題

代價係慢 5 到 20 倍,所以只可以用喺第二階段小規模精排。

整理重點

反直覺③:相關性高唔代表答案完整;反直覺④:緩存唔只為慳錢

Cross-Encoder 排完之後,好多系統就停咗——但 context-ranking 加多步 MMR,解決「相關但冗餘」嘅問題。

MMR(最大邊際相關性)每次選下一個片段時,同時考慮相關性同同已選片段嘅相似度

  1. 1 lambda = 1.0:純按相關性,唔理多樣性
  2. 2 lambda = 0.0:純按多樣性,唔理相關性
  3. 3 lambda = 0.5~0.7:平衡兩者,係 Skill 推薦嘅默認區間
  4. 4 事實性問答用更高 lambda(0.7-0.8),探索性研究用更低 lambda(0.4-0.5)

另外,多輪對話入面緩存 Cross-Encoder 結果,除咗慳算力,仲有一個隱性收益:減少時延。Cross-Encoder 慢,但命中緩存時整個 Ranking 時延接近零,對實時產品好重要。

緩存唔只為省錢,更重要係減少時延對用戶體驗嘅影響

整理重點

反直覺⑤:置信度分級係俾 LLM 睇嘅;結尾:Ranking 係放大器

最後一步附加 high / medium / low 置信度標籤,初睇好似多餘——因為排序本身已經反映咗信心。但呢一步係俾下游 LLM 用嘅:Prompt 設計會指示模型,見到 high confidence 更確定咁引用,見到 low confidence 要加不確定語氣,甚至叫用戶驗證。

置信度標籤「幫助下游 Prompt 組裝步驟決定如何呈現上下文,並允許模型在引用來源時校準自己的置信度」

Edge Cases 都要留意:超大候選集要加「分數閾值截斷」,單結果查詢要跳過 MMR。呢啲細節令個流程更實用。

一排整齊的檔案櫃,光線從側面打進來,製造出層次感
一排整齊嘅檔案櫃,光線由側邊射入嚟,營造到層次感

你有冇遇過呢種情況:明明問咗一個好具體嘅問題,AI 俾嘅回答卻離曬題——好似講緊嘢,但又乜都講唔清楚?

你可能覺得係模型唔夠聰明,或者自己嘅問法唔夠準。但其實,問題更可能出喺一個大多數人根本冇留意到嘅地方:AI 搜到嘅內容,唔一定係「最相關嘅內容」

呢個唔係玄學,而係一個工程問題。

喺 RAG(檢索增強生成)系統入面,「搜到」同「排好」係兩件完全唔同嘅事。大部分人識得前者,但對後者就知得唔多。呢篇文章,我哋拆解一個專門處理呢件事嘅 Skill:context-ranking——嚟自 GitHub 倉庫 h4vzz/awesome-ai-agent-skills,截至 2026 年 5 月,呢個倉庫已經收錄咗 70+ 個 AI Agent Skill。


先講清楚:「搜到」同「排好」嘅差距有幾大

向量搜尋(Vector Search)係目前最主流嘅 RAG 檢索方式。你問一條問題,系統將條問題轉成一個向量,然後喺知識庫入面揾「向量最接近」嘅文檔片段,返回 top-k 個結果。

聽落好完美。但呢度有一個你可能冇意識到嘅陷阱:餘弦相似度衡量嘅係「方向相似」,唔係「資訊有冇用」

舉個例:你問「WebSocket 連接點解 60 秒後自動斷開?」——知識庫裏面有八個候選片段:

  • 服務器端 pingTimeout 配置(60000ms)
  • Nginx 代理嘅 proxy_read_timeout 設置
  • 客戶端缺少 pong 響應處理
  • 連接超時日誌
  • 版本更新日誌(「v2.1 修復咗重連邏輯」,冇細節)
  • package.json 裏面嘅 ws 依賴版本號

用餘弦相似度排序,「60 秒重連」「WebSocket 連接」呢啲關鍵詞匹配度高嘅片段會排喺前面——但 package.json 裏面嘅版本號同 CHANGELOG 裏面嘅一句話會因為字面相似而搶佔位置,將真正有用嘅 Nginx 配置同客戶端 pong 缺失推到後面

呢個就係點解你需要 Ranking。


Ranking 嘅完整工作流

context-ranking Skill 將成個排序過程拆成六步。每一步都有清晰嘅輸入輸出,冇任何一步係「順手加嘅」。

Step 1: 收集候選片段(來自向量搜索的 top-15 到 top-30)
        ↓
Step 2: 第一階段快速評分(BM25 + 餘弦相似度)
        ↓
Step 3: Cross-Encoder 精排(對前 15-25 個候選深度打分)
        ↓
Step 4: MMR 多樣性選擇(去掉重複,保留覆蓋面)
        ↓
Step 5: 合併最終分數(相關性 + 多樣性 + 領域加權)
        ↓
Step 6: 附加元數據和置信度分級(high / medium / low)

六步睇落多,但每一步解決嘅問題係唔同嘅:第一階段解決「速度」,第三步解決「精度」,第四步解決「覆蓋面」,最後兩步解決「可解釋性」。

跟住落嚟,我哋逐個拆最值得關注嘅設計決策。


反直覺設計 ①:第一階段唔係為咗精確,而係為咗「快速過濾」

數據密集的儀表盤屏幕,綠色熒光數字在暗色背景上
數據密集嘅儀錶板屏幕,綠色熒光數字喺暗色背景上

好多人以為:既然要精準排序,就應該用最好嘅模型由頭打分。

呢個邏輯聽落冇問題,但實際工程上完全行唔通。原因係:精排模型(Cross-Encoder)好慢

Skill 裏面嘅設計係咁嘅:第一階段用 BM25 + 餘弦相似度呢兩個「平價模型」行曬所有候選,將 top-15 到 top-30 篩出嚟;第二階段先用 Cross-Encoder 精排,只行呢十幾個二十個候選。

呢度最值得關注嘅係「點解唔跳過第一階段,直接用 Cross-Encoder 行曬所有候選?」——因為 Cross-Encoder 處理每一個 (query, chunk) 對嗰陣,都要做完整嘅 Attention 計算。候選片段每多一倍,耗時就多一倍甚至更多。如果知識庫有幾千個片段,全量精排根本冇可能實時完成。

第一階段嘅「BM25 + 餘弦相似度」係設計上嘅妥協,但係有原則嘅妥協:佢哋夠快,而且召回率(Recall)夠高,幾乎唔會漏咗真正相關嘅片段——漏咗嘅代價,比精度損失大得多。

仲有一個細節:Skill 裏面建議用 RRF(Reciprocal Rank Fusion) 合併 BM25 同餘弦相似度嘅排名,而唔係直接加權求和。點解?因為 BM25 嘅分數同餘弦相似度嘅分數喺數值上冇可比性——一個係概率打分,一個係角度值。直接加權會令到量綱大嗰個主導結果。RRF 將佢哋都轉成「排名位次」再合併,繞開咗量綱問題。


反直覺設計 ②:Cross-Encoder 點解比「嵌入相似度」精準咁多?

呢個係成個 Ranking 流程裏面最重要嘅一步,亦都係最難理解嘅。

嵌入模型(Bi-Encoder) 嘅工作方式:將 query 同每個 chunk 分別編碼成兩個向量,計算向量之間嘅餘弦相似度。優點係極快——向量一旦計好,搜尋嗰陣只係計一次點積。

Cross-Encoder 嘅工作方式:將 query 同 chunk 拼埋一齊輸入入去,讓 Transformer 對兩者做全局 Attention,輸出一個相關性分數。

關鍵差異在「全局 Attention」:Bi-Encoder 喺對兩段文字分別編碼嗰陣,佢哋係互相「唔知對方存在」嘅。Cross-Encoder 就讓 query 裏面每個詞都可以「見到」chunk 裏面每個詞,反轉都一樣。

呢個意味住咩?Cross-Encoder 可以捕捉到「呢個 chunk 裏面啱啱好答咗 query 裏面嗰個具體細節」——呢種細粒度的匹配,嵌入向量根本睇唔到。Skill 裏面嘅數據顯示:Cross-Encoder 精排可以將精度(Precision)提升 15-30%(來源:h4vzz/awesome-ai-agent-skillscontext-ranking/SKILL.md,截至 2026 年 5 月)。

代價係速度——Cross-Encoder 通常比餘弦相似度慢 5 到 20 倍。呢個就係點解佢只用於第二階段嘅「小規模精排」,而唔係全量檢索。


反直覺設計 ③:相關性高,唔代表答案齊全

一張多層書架的局部特寫,書脊顏色各異,光線柔和
一張多層書架嘅局部特寫,書脊顏色各異,光線柔和

Cross-Encoder 排完之後,你會得到一個按相關性降序排列嘅列表。大多數系統到呢度就完咗——攞前 n 個送入 Prompt 就搞掂。

但 context-ranking 喺呢度多做咗一步:MMR(Maximal Marginal Relevance,最大邊際相關性)

呢一步解決嘅問題,係「相關但冗餘」嘅陷阱。

想像一下:你問嘅係「WebSocket 斷開嘅原因同修復方法」,精排後嘅前五個片段,有三個都係關於「服務器端 ping timeout 配置」嘅——三段講嘅係同一件事,只係嚟自唔同文件。送入 Prompt 之後,佔用咗大量 Token,但對回答「修復方法」冇任何幫助。

MMR 嘅邏輯係:每次由剩餘候選入面揀下一個片段嗰陣,同時考慮佢對 query 嘅相關性,以及佢同已選片段嘅相似度。公式裏面有一個 lambda 參數控制權重:

  • lambda = 1.0:純按相關性揀,唔考慮多樣性
  • lambda = 0.0:純按多樣性揀,唔考慮相關性
  • lambda = 0.5~0.7:平衡兩者(Skill 推薦嘅默認區間)

呢個參數有具體嘅調參建議:事實性問答用高啲嘅 lambda(0.7-0.8)——答案好具體,相關性更重要,唔需要多樣性;探索性研究用低啲嘅 lambda(0.4-0.5)——問題比較開放,需要覆蓋唔同角度。

呢個細節好多系統根本唔做——佢哋嘅「多樣性」只係隨機打亂或者簡單去重。MMR 係有理論根據嘅去冗餘,而且可以按需調參。


反直覺設計 ④:快取 Cross-Encoder 嘅結果,唔係為咗「慳錢」

多輪對話入面,用戶成日問類似嘅問題——「Python 裏面點樣連接數據庫?」「Django ORM 點樣用?」呢兩個問題可能會檢索到大量重疊嘅文檔片段。

Skill 裏面有一條 Best Practice:快取 Cross-Encoder 嘅打分結果

呢條建議睇落好普通——快取當然慳算力。但佢背後嘅設計邏輯更加有意思:Cross-Encoder 嘅輸入係 (query, chunk) 對,相同嘅 query 喺唔同輪次入面可能會反覆出現。每次都重新計,唔單止浪費推理資源,而且結果係確定嘅——完全冇必要計第二次。

更深一層:喺多輪對話入面做快取,仲有一個隱性收益——減少時延對用戶體驗嘅影響。Cross-Encoder 通常比嵌入搜索慢幾倍,如果命中快取,成個 Ranking 階段嘅時延接近零。對於追求實時響應嘅產品嚟講,呢個設計決策嘅價值遠超「慳錢」本身。


反直覺設計 ⑤:最後一步附加「置信度分級」,係俾邊個睇嘅?

黑色背景上懸浮的半透明數據層,代表信息的分級與結構
黑色背景上懸浮嘅半透明數據層,代表資訊嘅分級與結構

Ranking 嘅最後一步,係俾每個被揀中嘅片段附上一個置信度標籤:high / medium / low

呢一步我第一次讀到嗰陣覺得「呢個唔係多此一舉咩」——已經排好序喇,次序本身唔就代表咗置信度咩?

但仔細諗嚇,呢一步嘅目的根本唔係俾排序算法用嘅,係俾下游嘅 LLM 用嘅

Skill 裏面嘅說明係:呢個置信度元數據「幫助下游 Prompt 組裝步驟決定點樣呈現上下文,並允許模型喺引用來源嗰陣校準自己嘅置信度」。

翻譯成白話:當模型見到一段被標記為「high confidence」嘅片段,佢傾向於更肯定咁引用;見到「low confidence」,佢會喺表述上加返啲唔確定嘅語氣,甚至主動提示用戶驗證。呢個唔係模型自發嘅行為,而係透過 Prompt 設計明確話俾模型知「呢段嘢嘅可信程度」,模型先可以做出對應嘅輸出調整。

換句話講:Ranking 唔只係俾系統內部用嘅,佢嘅輸出結果需要被透傳俾 LLM,影響最終嘅生成質量。呢一步令到成個 Ranking 流程閉環咗。


橫向對比:Ranking 解決咗咩,仲未解決咩

讀完呢五個設計決策,可以做一個整體嘅橫向審視:

問題
Ranking 嘅解決方案
係咪完全解決
嵌入相似度精度唔夠
Cross-Encoder 精排
✅ 大幅改善
前幾個結果講嘅係同一件事
MMR 多樣性選擇
✅ 有效處理
BM25 同餘弦分數量綱唔統一
RRF 排名融合
✅ 設計合理
多輪對話重複計算開銷大
Cross-Encoder 結果快取
✅ 工程可行
跨語言檢索質量
需要多語言 reranker 或翻譯前處理
⚠️ 依賴外部組件
對抗性/SEO 噪聲內容
Cross-Encoder 部分抵禦,需額外質量過濾
⚠️ 唔完全
知識庫內容過期
元數據時效加權(需配置)
⚠️ 需人工維護

Skill 裏面有幾個 Edge Cases 值得特別記錄:

超大候選集(100+個片段):如果檢索返回咗幾百個候選,Cross-Encoder 全跑嘅延遲會超出接受範圍。Skill 嘅建議係喺入精排之前加一個「分數閾值截斷」——低過閾值嘅直接丟掉,唔入 Cross-Encoder。呢個閾值點定?憑經驗,通常設喺第一階段分數分佈嘅中位數附近,具體數字要喺自己嘅數據上試。

單結果查詢:有啲問題嘅答案喺知識庫裏面得一個片段係真正相關嘅。呢個時候 MMR 可能會因為「強制多樣化」而將一個低質量片段抬入結果集。Skill 嘅處理方式係:當候選總數好少(例如 3 個以下),跳過 MMR 直接用 reranker 排名。


結尾:AI 搜到嘅係「候選人」,排序決定邊個上台

舞台燈光打在空曠的講台上,象徵最終的選擇與呈現
舞台燈光打喺空曠嘅講台上,象徵最終嘅選擇與呈現

用一個比喻嚟收尾:向量搜索好似初輪簡歷篩選,將數千份簡歷入面「關鍵詞匹配」嘅嗰啲揀出嚟;Ranking 先係面試環節,透過深度評估決定邊個真係適合呢個崗位。

大多數 RAG 系統停咗喺「簡歷篩選」。佢哋搜到咗候選,然後直接將前幾名送入咗決策層——相當於睇完簡歷就出 offer。Ranking 要做嘅事,係讓系統真正「讀明」每個候選,而唔係只係比較字面相似。

呢件事 Skill 覆蓋咗——佢俾咗一套工程上可落地嘅流程,有具體嘅模型選型(Cohere Rerank、bge-reranker-v2-m3、ColBERT)、有具體嘅參數建議(lambda=0.6 起步)、有具體嘅 Edge Cases 處理。

但 Skill 覆蓋唔到嘅係:你嘅知識庫裏面有冇足夠好嘅內容。Ranking 係一個放大器,佢可以令好內容更易被揾到,但揾唔到嘅嘢,佢排唔出嚟。

知識嘅質量,永遠喺算法嘅上游。


我係專注 AI Agent 深度實踐嘅努力撞蘑菇AI,致力於分享真實可用嘅 AI 使用經驗與工作流探索,歡迎你同我一齊將 AI 玩明白,如果內容對你有幫助,歡迎關注、點讚、轉發。
一排整齊的檔案櫃,光線從側面打進來,製造出層次感
一排整齊的檔案櫃,光線從側面打進來,製造出層次感

你有沒有遇到過這種情況:明明問了一個很具體的問題,AI 給出的回答卻飄了——像是在說什麼,又什麼都沒說清楚?

你覺得可能是模型不夠聰明,或者你的問法不夠準。但其實,問題更可能出在一個大多數人根本沒注意到的地方:AI 搜到的內容,不一定是「最相關的內容」

這不是玄學,這是一個工程問題。

在 RAG(檢索增強生成)系統裏,「搜到」和「排好」是兩件完全不同的事。大部分人瞭解前者,卻對後者知之甚少。這篇文章,我們來拆一個專門解決這件事的 Skill:context-ranking——來自 GitHub 倉庫 h4vzz/awesome-ai-agent-skills,截至 2026 年 5 月,該倉庫已收錄 70+ 個 AI Agent Skill。


先說清楚:「搜到」和「排好」的差距有多大

向量搜索(Vector Search)是目前最主流的 RAG 檢索方式。你問一個問題,系統把問題轉成一個向量,然後在知識庫裏找「向量最接近」的文檔片段,返回 top-k 個結果。

聽起來很完美。但這裏有一個你可能沒意識到的陷阱:餘弦相似度衡量的是「方向相似」,不是「信息有沒有用」

舉個例子:你問「WebSocket 連接為什麼 60 秒後自動斷開?」——知識庫裏有八個候選片段:

  • 服務器端 pingTimeout 配置(60000ms)
  • Nginx 代理的 proxy_read_timeout 設置
  • 客戶端缺少 pong 響應處理
  • 連接超時日誌
  • 版本更新日誌(「v2.1 修復了重連邏輯」,無細節)
  • package.json 裏的 ws 依賴版本號

用餘弦相似度排序,「60 秒重連」「WebSocket 連接」這些關鍵詞匹配度高的片段會排在前面——但 package.json 裏的版本號和 CHANGELOG 裏的一句話會因為字面相似而搶佔位置,把真正有用的 Nginx 配置和客戶端 pong 缺失推到後面

這就是為什麼你需要 Ranking。


Ranking 的完整工作流

context-ranking Skill 把整個排序過程拆成了六步。每一步都有清晰的輸入輸出,沒有任何一步是「順手加的」。

Step 1: 收集候選片段(來自向量搜索的 top-15 到 top-30)
        ↓
Step 2: 第一階段快速評分(BM25 + 餘弦相似度)
        ↓
Step 3: Cross-Encoder 精排(對前 15-25 個候選深度打分)
        ↓
Step 4: MMR 多樣性選擇(去掉重複,保留覆蓋面)
        ↓
Step 5: 合併最終分數(相關性 + 多樣性 + 領域加權)
        ↓
Step 6: 附加元數據和置信度分級(high / medium / low)

六步看起來多,但每一步解決的問題是不同的:第一階段解決「速度」,第三步解決「精度」,第四步解決「覆蓋面」,最後兩步解決「可解釋性」。

接下來,我們逐個拆最值得關注的設計決策。


反直覺設計 ①:第一階段不是為了精確,是為了「快速過濾」

數據密集的儀表盤屏幕,綠色熒光數字在暗色背景上
數據密集的儀表盤屏幕,綠色熒光數字在暗色背景上

很多人以為:既然要精準排序,就應該用最好的模型從頭打分。

這個邏輯聽起來沒問題,但實際工程上完全行不通。原因是:精排模型(Cross-Encoder)很慢

Skill 裏的設計是這樣的:第一階段用 BM25 + 餘弦相似度這兩個「便宜模型」跑完所有候選,把 top-15 到 top-30 篩出來;第二階段才用 Cross-Encoder 精排,只跑這十幾二十個候選。

這裏最值得關注的是「為什麼不跳過第一階段,直接用 Cross-Encoder 跑所有候選?」——因為 Cross-Encoder 處理每一個 (query, chunk) 對時,都要做完整的 Attention 計算。候選片段每多一倍,耗時就多一倍甚至更多。如果知識庫有幾千個片段,全量精排根本不可能實時完成。

第一階段的「BM25 + 餘弦相似度」是設計上的妥協,但是有原則的妥協:它們足夠快,且召回率(Recall)足夠高,幾乎不會漏掉真正相關的片段——漏掉的代價,比精度損失要大得多。

還有一個細節:Skill 裏建議用 RRF(Reciprocal Rank Fusion) 合併 BM25 和餘弦相似度的排名,而不是直接加權求和。為什麼?因為 BM25 的分數和餘弦相似度的分數在數值上沒有可比性——一個是概率打分,一個是角度值。直接加權會讓量綱大的那個主導結果。RRF 把它們都轉成「排名位次」再合併,繞開了量綱問題。


反直覺設計 ②:Cross-Encoder 為什麼比「嵌入相似度」精準得多?

這是整個 Ranking 流程裏最重要的一步,也是最難理解的。

嵌入模型(Bi-Encoder) 的工作方式:把 query 和每個 chunk 分別編碼成兩個向量,計算向量之間的餘弦相似度。優點是極快——向量一旦算好,搜索時只用算一次點積。

Cross-Encoder 的工作方式:把 query 和 chunk 拼在一起輸入進去,讓 Transformer 對兩者做全局 Attention,輸出一個相關性分數。

關鍵差異在「全局 Attention」:Bi-Encoder 在對兩段文字分別編碼時,它們是互相「不知道對方存在的」。Cross-Encoder 則讓 query 裏的每個詞都能「看到」chunk 裏的每個詞,反過來也一樣。

這意味着什麼?Cross-Encoder 能捕捉到「這個 chunk 裏恰好回答了 query 裏那個具體細節」——這種細粒度的匹配,嵌入向量根本看不到。Skill 裏的數據顯示:Cross-Encoder 精排能把精度(Precision)提升 15-30%(來源:h4vzz/awesome-ai-agent-skillscontext-ranking/SKILL.md,截至 2026 年 5 月)。

代價是速度——Cross-Encoder 通常比餘弦相似度慢 5 到 20 倍。這就是為什麼它只用於第二階段的「小規模精排」,而不是全量檢索。


反直覺設計 ③:相關性高,不代表答案全

一張多層書架的局部特寫,書脊顏色各異,光線柔和
一張多層書架的局部特寫,書脊顏色各異,光線柔和

Cross-Encoder 排完之後,你會得到一個按相關性降序排列的列表。大多數系統到這裏就結束了——取前 n 個送進 Prompt 就完事。

但 context-ranking 在這裏多做了一步:MMR(Maximal Marginal Relevance,最大邊際相關性)

這一步解決的問題,是「相關但冗餘」的陷阱。

想象一下:你問的是「WebSocket 斷開的原因和修復方法」,精排後的前五個片段,有三個都是關於「服務器端 ping timeout 配置」的——三段說的是同一件事,只是來自不同文件。送進 Prompt 後,佔用了大量 Token,卻對回答「修復方法」沒有任何幫助。

MMR 的邏輯是:每次從剩餘候選裏選下一個片段時,同時考慮它對 query 的相關性,以及它和已選片段的相似度。公式裏有一個 lambda 參數控制權重:

  • lambda = 1.0:純按相關性選,不考慮多樣性
  • lambda = 0.0:純按多樣性選,不考慮相關性
  • lambda = 0.5~0.7:平衡兩者(Skill 推薦的默認區間)

這個參數有具體的調參建議:事實性問答用更高的 lambda(0.7-0.8)——答案很具體,相關性更重要,不需要多樣性;探索性研究用更低的 lambda(0.4-0.5)——問題比較開放,需要覆蓋不同角度。

這個細節很多系統根本不做——它們的「多樣性」只是隨機打亂或者簡單去重。MMR 是有理論依據的去冗餘,而且可以按需調參。


反直覺設計 ④:緩存 Cross-Encoder 的結果,不是為了「省錢」

多輪對話裏,用戶經常問類似的問題——「Python 裏怎麼連接數據庫?」「Django ORM 怎麼用?」這兩個問題可能檢索到大量重疊的文檔片段。

Skill 裏有一條 Best Practice:緩存 Cross-Encoder 的打分結果

這條建議看起來很普通——緩存當然省算力。但它背後的設計邏輯更有意思:Cross-Encoder 的輸入是 (query, chunk) 對,相同的 query 在不同輪次裏可能反覆出現。每次都重新算,不僅浪費推理資源,而且結果是確定的——完全沒必要算第二遍。

更深一層:在多輪對話裏做緩存,還有一個隱性收益——減少時延對用戶體驗的影響。Cross-Encoder 通常比嵌入搜索慢幾倍,如果命中緩存,整個 Ranking 階段的時延接近於零。對於追求實時響應的產品來說,這個設計決策的價值遠超「省錢」本身。


反直覺設計 ⑤:最後一步附加「置信度分級」,是給誰看的?

黑色背景上懸浮的半透明數據層,代表信息的分級與結構
黑色背景上懸浮的半透明數據層,代表信息的分級與結構

Ranking 的最後一步,是給每個被選中的片段附上一個置信度標籤:high / medium / low

這一步我第一次讀到時覺得「這不是多此一舉嗎」——已經排好序了,順序本身不就代表了置信度?

但仔細想想,這一步的目的根本不是給排序算法用的,是給下游的 LLM 用的

Skill 裏的說明是:這個置信度元數據「幫助下游 Prompt 組裝步驟決定如何呈現上下文,並允許模型在引用來源時校準自己的置信度」。

翻譯一下:當模型看到一段被標記為「high confidence」的片段,它傾向於更確定地引用;看到「low confidence」,它會在表述上加入不確定語氣,甚至主動提示用戶驗證。這不是模型自發的行為,而是通過 Prompt 設計明確告訴模型「這段話的可信程度」,模型才能做出對應的輸出調整。

換句話說:Ranking 不只是給系統內部用的,它的輸出結果需要被透傳給 LLM,影響最終的生成質量。這一步讓整個 Ranking 流程閉環了。


橫向對比:Ranking 解決了什麼,還沒解決什麼

讀完這五個設計決策,可以做一個整體的橫向審視:

問題
Ranking 的解決方案
是否完全解決
嵌入相似度精度不夠
Cross-Encoder 精排
✅ 大幅改善
前幾個結果說的是同一件事
MMR 多樣性選擇
✅ 有效處理
BM25 和餘弦分數量綱不統一
RRF 排名融合
✅ 設計合理
多輪對話重複計算開銷大
Cross-Encoder 結果緩存
✅ 工程可行
跨語言檢索質量
需要多語言 reranker 或翻譯前處理
⚠️ 依賴外部組件
對抗性/SEO 噪聲內容
Cross-Encoder 部分抵禦,需額外質量過濾
⚠️ 不完全
知識庫內容過期
元數據時效加權(需配置)
⚠️ 需人工維護

Skill 裏有幾個 Edge Cases 值得特別記錄:

超大候選集(100+個片段):如果檢索返回了幾百個候選,Cross-Encoder 全跑的延遲會超出接受範圍。Skill 的建議是在進入精排前加一個「分數閾值截斷」——低於閾值的直接丟掉,不進入 Cross-Encoder。這個閾值怎麼定?憑經驗,通常設在第一階段分數分佈的中位數附近,具體數字需要在自己的數據上測。

單結果查詢:有些問題的答案在知識庫裏只有一個片段是真正相關的。這時候 MMR 可能會因為「強制多樣化」而把一個低質量片段抬進結果集。Skill 的處理方式是:當候選總數很少(比如 3 個以下),跳過 MMR 直接用 reranker 排名。


結尾:AI 搜到的是「候選人」,排序決定誰上台

舞台燈光打在空曠的講台上,象徵最終的選擇與呈現
舞台燈光打在空曠的講台上,象徵最終的選擇與呈現

用一個比喻來收尾:向量搜索像是初輪簡歷篩選,把數千份簡歷裏「關鍵詞匹配」的那些挑出來;Ranking 才是面試環節,通過深度評估決定誰真的適合這個崗位。

大多數 RAG 系統停在了「簡歷篩選」。它們搜到了候選,然後直接把前幾名送進了決策層——相當於只看簡歷就發了 offer。Ranking 要做的事,是讓系統真正「讀懂」每個候選,而不是隻比較字面相似。

這件事 Skill 覆蓋了——它給出了一套工程上可落地的流程,有具體的模型選型(Cohere Rerank、bge-reranker-v2-m3、ColBERT)、有具體的參數建議(lambda=0.6 起步)、有具體的 Edge Cases 處理。

但 Skill 覆蓋不到的是:你的知識庫裏有沒有足夠好的內容。Ranking 是一個放大器,它能讓好內容更好地被找到,但找不到的東西,它排不出來。

知識的質量,永遠在算法的上游。


我是專注 AI Agent深度實踐的努力撞蘑菇AI,致力於分享真實可用的 AI 使用經驗與工作流探索,歡迎你和我一起把 AI 玩明白,如果內容對你有幫助,歡迎關注、點贊、轉發。