如何使用 Milvus Boost Ranker 進行商業感知矢量搜尋
向量搜尋根據嵌入相似度來排列結果 - 向量越接近,結果越高。有些系統加入了基於模型的重新排序器 (BGE、Voyage、Cohere) 來改善排序。但這兩種方法都無法處理生產中的基本需求:業務情境與語意相關性同樣重要,有時甚至更重要。
電子商務網站需要先顯示官方商店的庫存產品。內容平台則希望將最近的公告放在最前面。企業知識庫需要將權威文件放在最前面。當排名僅依賴向量距離時,這些規則就會被忽略。結果可能是相關的,但並不適當。
Milvus2.6 中引入的Boost Ranker 可以解決這個問題。它可以讓您使用元資料規則調整搜尋結果的排名 - 不需要重建索引,也不需要改變模型。這篇文章涵蓋了它如何運作、何時使用,以及如何用程式碼實作。
什麼是 Boost Ranker?
Boost Ranker 是 Milvus 2.6.2 中一個輕量級的、基於規則的重新排名功能,可以使用標量元資料欄位調整向量搜尋結果。與呼叫外部 LLM 或嵌入服務的基於模型的重排器不同,Boost Ranker 完全在 Milvus 內使用簡單的過濾與加權規則運作。沒有外部依賴,延遲開銷最小 - 適合即時使用。
您可以透過Function API 進行設定。向量搜尋傳回一組候選結果後,Boost Ranker 會應用三種操作:
- 過濾:找出符合特定條件的結果 (例如:
is_official == true) - Boost:將其分數乘以設定的權重
- 洗牌:可選擇加入一個小隨機因子 (0-1) 以引入多樣性
引擎蓋下的運作方式
Boost Ranker 在 Milvus 內執行,作為後處理步驟:
- 向量搜尋- 每個區段都會傳回具有 ID、相似度分數和元資料的候選人。
- 應用規則- 系統過濾匹配記錄,並使用配置的權重和可選的
random_score來調整它們的分數。 - 合併與排序-合併所有候選人,並根據更新的分數重新排序,以產生最終的 Top-K 結果。
由於 Boost Ranker 只會對已擷取的候選人進行操作,而非整個資料集,因此額外的計算成本可以忽略不计。
什麼時候應該使用 Boost Ranker?
提升重要結果
最常見的使用案例:在語義搜尋上層疊加簡單的業務規則。
- 電子商務:推廣來自旗艦店、官方賣家或付費促銷的商品。將近期銷售額或點擊率高的商品推高。
- 內容平台:透過
publish_time欄位優先處理最近發表的內容,或提升來自已驗證帳號的文章。 - 企業搜尋:優先推送
doctype == "policy"或is_canonical == true的文件。
所有都可透過篩選器 + 權重進行設定。無需改變嵌入模型,無需重建索引。
降級而不移除
Boost Ranker 也可以降低某些結果的排名 - 比硬過濾更柔和的替代方式。
- 低庫存產品:如果
stock < 10,稍微降低其權重。仍然可以找到,但不會佔據頂部位置。 - 敏感內容:降低標記內容的權重,而非完全移除。限制曝光率,但不會硬性審查。
- 陳舊文件:
year < 2020的文件會被降級,因此較新的內容會先出現。
使用者仍可透過捲動或更精確的搜尋找到被降級的結果,但它們不會排擠更相關的內容。
使用受控制的隨機性增加多樣性
當許多結果都有相似的分數時,Top-K 在不同的查詢中看起來就會完全相同。Boost Ranker 的random_score 參數引入了輕微的變化:
"random_score": {
"seed": 126,
"field": "id"
}
seed:控制整體的隨機性,以提高可重複性field:通常是主索引鍵id,確保相同的記錄每次都得到相同的隨機值。
這對於多樣化推薦(防止相同的項目總是出現在第一位) 和探索(結合固定的商業權重和小隨機擾動) 非常有用。
將 Boost Ranker 與其他排名器結合
Boost Ranker 是透過 Function API 與params.reranker = "boost" 設定的。關於結合它,有兩點需要知道:
- 限制:在混合(多向量)搜索中,Boost Ranker 不能作為頂層排名器。但它可以用在每個個別的
AnnSearchRequest內,在合併之前調整結果。 - 常見組合:
- RRF + Boost:使用 RRF 合併多模式結果,然後應用 Boost 來進行以元資料為基礎的微調。
- 模型排序器 + Boost:使用基於模型的排序器進行語意品質,然後應用 Boost 進行業務規則。
如何設定 Boost Ranker
Boost Ranker 是透過 Function API 來設定的。若要更複雜的邏輯,請結合FunctionScore 一起套用多個規則。
必填欄位
建立Function 物件時:
name:任何自訂名稱input_field_names:必須是空列表[]function_type:設定為FunctionType.RERANKparams.reranker:必須是"boost"
關鍵參數
params.weight (必填)
應用於匹配記錄分數的乘數。如何設定取決於度量:
| 度量類型 | 提升結果 | 降低結果 |
|---|---|---|
| 越高越好 (COSINE, IP) | weight > 1 | weight < 1 |
| 較低為佳 (L2/Euclidean) | weight < 1 | weight > 1 |
params.filter (選用)
選擇哪些記錄的分數會被調整的條件:
"doctype == 'abstract'""is_premium == true""views > 1000 and category == 'tech'"
只有匹配的記錄會受到影響。其他所有記錄都會保持原始分數。
params.random_score (選用)
為多樣性加入介於 0 和 1 之間的隨機值。詳情請參閱上述隨機性部分。
單一規則與多重規則
單一規則- 當您有一個業務約束 (例如,提升官方文件),直接將排名器傳到search(..., ranker=ranker) 。
多重規則- 當您需要數個約束 (優先處理庫存貨品 + 降級低評級產品 + 增加隨機性),請建立多個Function 物件,並將它們與FunctionScore 結合。 您可以設定:
boost_mode:每個規則如何與原始分數結合 (multiply或add)function_mode:多個規則如何互相結合 (multiply或add)
實作:優先處理官方文件
讓我們來看看一個具體的範例:讓官方文件在文件搜尋系統中排名較前。
模式
一個稱為milvus_collection 的集合,包含這些欄位:
| 欄位 | 欄位類型 | 目的 |
|---|---|---|
id | INT64 | 主索引鍵 |
content | VARCHAR | 文件文字 |
embedding | 浮動向量 (3072) | 語意向量 |
source | VARCHAR | 來源:「官方」、「社群 」或 「票據」 |
is_official | BOOL | True 如果source == "official" |
source 和is_official 欄位是 Boost Ranker 用來調整排名的元資料。
設定程式碼
from pymilvus import (
MilvusClient,
DataType,
Function,
FunctionType,
)
# 1. Connect to Milvus
client = MilvusClient(uri=“http://localhost:19530”)
collection_name = “milvus_collection”
# If it already exists, drop it first for repeated testing
if collection_name in client.list_collections():
client.drop_collection(collection_name)
# 2. Define schema
schema = MilvusClient.create_schema(
auto_id=False,
enable_dynamic_field=False,
)
schema.add_field(
field_name=“id”,
datatype=DataType.INT64,
is_primary=True,
)
schema.add_field(
field_name=“content”,
datatype=DataType.VARCHAR,
max_length=512,
)
schema.add_field(
field_name=“source”,
datatype=DataType.VARCHAR,
max_length=32,
)
schema.add_field(
field_name=“is_official”,
datatype=DataType.BOOL,
)
schema.add_field(
field_name=“embedding”,
datatype=DataType.FLOAT_VECTOR,
dim=3072,
)
text_embedding_function = Function(
name=“openai_embedding”,
function_type=FunctionType.TEXTEMBEDDING,
input_field_names=[“content”],
output_field_names=[“embedding”],
params={
“provider”: “openai”,
“model_name”: “text-embedding-3-large”
}
)
schema.add_function(text_embedding_function)
# 3. Create Collection
client.create_collection(
collection_name=collection_name,
schema=schema,
)
# 4. Create index
index_params = client.prepare_index_params()
index_params.add_index(
field_name=“embedding”,
index_type=“IVF_FLAT”,
metric_type=“COSINE”,
params={“nlist”: 16},
)
client.create_index(
collection_name=collection_name,
index_params=index_params,
)
# 5. Load Collection into memory
client.load_collection(collection_name=collection_name)
docs = [
{
“id”: 1,
“content”: "How to deploy Milvus on Kubernetes (Official Guide)",
“source”: “official”,
“is_official”: True
},
{
“id”: 2,
“content”: "Quick deployment of Milvus with Docker Compose (Official Tutorial)",
“source”: “official”,
“is_official”: True
},
{
“id”: 3,
“content”: “Community experience: Lessons learned from deploying Milvus”,
“source”: “community”,
“is_official”: False
},
{
“id”: 4,
“content”: “Ticket record: Milvus deployment issue”,
“source”: “ticket”,
“is_official”: False
},
]
client.insert(
collection_name=collection_name,
data=docs,
)
比較結果:使用和不使用 Boost Ranker
首先,在沒有 Boost Ranker 的情況下執行基線搜尋。然後將 Boost Ranker 加入filter: is_official == true 和weight: 1.2 ,並進行比較。
# 6. Baseline search (without Boost Ranker)
query_vector = "how to deploy milvus"
search_params = {
“metric_type”: “COSINE”,
“params”: {“nprobe”: 2},
}
results = client.search(
collection_name=collection_name,
data=[query_vector],
anns_field=“embedding”,
search_params=search_params,
limit=4,
output_fields=[“content”, “source”, “is_official”],
)
print(“=== Baseline search (no Boost Ranker) ===”)
for hit in results[0]:
entity = hit[“entity”]
print(
f"id={hit[‘id’]}, "
f"score={hit[‘distance’]:.4f}, "
f"source={entity[‘source’]}, "
f"is_official={entity[‘is_official’]}"
)
# 7. Define Boost Ranker: apply weight to documents where is_official == true
boost_official_ranker = Function(
name=“boost_official”,
input_field_names=[], # Boost Ranker requires this to be an empty list
function_type=FunctionType.RERANK,
params={
“reranker”: “boost”, # Specify Boost Ranker
“filter”: “is_official==true”,
# For COSINE / IP (higher score is better), use weight > 1 to boost
“weight”: 1.2
},
)
boosted_results = client.search(
collection_name=collection_name,
data=[query_vector],
anns_field=“embedding”,
search_params=search_params,
limit=4,
output_fields=[“content”, “source”, “is_official”],
ranker=boost_official_ranker,
)
print(“\n=== Search with Boost Ranker (official boosted) ===”)
for hit in boosted_results[0]:
entity = hit[“entity”]
print(
f"id={hit[‘id’]}, "
f"score={hit[‘distance’]:.4f}, "
f"source={entity[‘source’]}, "
f"is_official={entity[‘is_official’]}"
)
結果
=== Baseline search (no Boost Ranker) ===
id=1, score=0.7351, source=official, is_official=True
id=4, score=0.7017, source=ticket, is_official=False
id=3, score=0.6706, source=community, is_official=False
id=2, score=0.6435, source=official, is_official=True
=== Search with Boost Ranker (official boosted) ===
id=1, score=0.8821, source=official, is_official=True
id=2, score=0.7722, source=official, is_official=True
id=4, score=0.7017, source=ticket, is_official=False
id=3, score=0.6706, source=community, is_official=False
主要的改變:文件id=2 (官方) 從第四名躍升到第二名,因為它的分數乘以 1.2。社群文章和票券記錄並沒有被移除 - 只是排名較低。這就是 Boost Ranker 的重點:以語義搜尋為基礎,然後在其上層疊商業規則。
總結
Boost Ranker提供您一種方式,讓您可以在向量搜尋結果中注入商業邏輯,而無須碰觸您的嵌入或重建索引。提升官方內容、降級陳舊的搜尋結果、增加可控的多樣性 - 所有這些都可以透過Milvus Function API 中簡單的過濾器 + 權重設定來達成。
無論您是在建立 RAG 管道、推薦系統或企業搜尋,Boost Ranker 都能幫助您縮小語義相似性與對使用者實際有用性之間的差距。
如果您正在研究搜尋排名,並想要討論您的使用個案:
- 加入Milvus Slack 社群,與其他建立搜尋與檢索系統的開發人員交流。
- 預約 20 分鐘的 Milvus Office Hours 免費課程,與團隊一起探討您的排序邏輯。
- 如果您想跳過基礎架構的設定,Zilliz Cloud(管理 Milvus) 有免費的層級可供您開始使用。
團隊開始使用 Boost Ranker 時會遇到的幾個問題:
Boost Ranker 可以取代 Cohere 或 BGE 等基於模型的 reranker 嗎?他們解決的是不同的問題。基於模型的 reranker 會依據語意品質對結果重新評分 - 他們擅長判斷「哪個文件能真正回答問題」。Boost Ranker 會根據業務規則調整評分 - 它會決定「哪個相關文件應該先出現」。實際上,您通常需要兩者兼具:先用模型排名器來判斷語意相關性,然後再用 Boost Ranker 來判斷商業邏輯。
Boost Ranker 會顯著增加延遲時間嗎?不會。它會在已擷取的候選集(通常是向量搜尋的 Top-K)上運作,而非整個資料集。操作是簡單的篩選和乘法,因此相較於向量搜尋本身,開銷可以忽略不计。
如何設定權重值?先從小幅度調整開始。對於 COSINE 相似度 (越高越好),1.1-1.3 的權重通常足以明顯改變排名,而不會完全取代語意相關性。使用您的實際資料進行測試 - 如果相似度較低的提升結果開始佔優,請降低權重。
我可以結合多個 Boost Ranker 規則嗎?可以。建立多個Function 物件,並使用FunctionScore 將其合併。您可以透過boost_mode (每個規則如何與原始分數結合)和function_mode (規則如何彼此結合)來控制規則的互動方式 - 兩者都支援multiply 和add 。
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word



