news 2026/3/25 19:44:54

Zilliz | embedding分数不是唯一解!搜索场景,如何根据元数据做加权rerank

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Zilliz | embedding分数不是唯一解!搜索场景,如何根据元数据做加权rerank

本文来源公众号“Zilliz”,仅用于学术分享,侵权删,干货满满。

原文链接:https://mp.weixin.qq.com/s/HjV1FjpVjc6qt-ubyeAl-w

1 rerank如何影响业务表现

今天聊一聊我们如何做高质量rerank。

一个常识是,无论企业知识库、电商、新闻,还是RAG、agent场景,只依靠语义相似度对检索结果进行排名,无疑都是粗暴且低效的。

一方面,元数据往往包含了语义、时间、标签、地理位置等多元信息,语义并不总是最重要的那一项;

另一方面,用户检索时,往往还需要对数据按照距离远近、好评分数、复购数量等信息进行综合排序。

比如:

  • 电商:付费/旗舰店商品要更靠前,缺货商品要略微靠后;

  • 内容搜索:官方内容、最近发布的内容要优先;

  • 企业知识库:部分标签(如“权威文档”“最佳实践”)需要被提升或者置顶。

在很多数据库的向量插件,或者早期版本的向量数据库产品中,向量检索结果排序主要依赖向量相似度本身(距离越近/相似度越高越靠前),或者通过模型类 Reranker(如 BGE, Voyage, Cohere)进行更智能的重排。但很显然,这两种方案中的任意一种,都无法解决实际场景中复杂的rerank需求。

针对这一困境,Milvus推出了Boost Ranker功能:在 Milvus 内部,我们可以对候选结果应用一组基于元数据的“加权规则”,做到不改索引、不改向量模型,就能按照需求更新排序逻辑

那么这个功能是如何实现的,要如何在实战中使用,本文将重点解读。

2 Boost Ranker 是什么

2.1 核心能力概览

Boost Ranker 是 Milvus 2.6.2 引入的一种 rerank 策略,通过 Function API 配置:

  • 在向量检索返回的候选集合上,再执行一轮基于过滤表达式的匹配

  • 对命中的实体按照配置的weight(权重)重新缩放分数;

  • 引入random_score,在 0~1 范围内生成一个随机因子,做轻量的“打散”。

相比模型类 Reranker(调用外部 LLM / rerank 模型),Boost Ranker完全基于已有的标量字段 + 简单规则,不需要外部服务,代价低,实时性强。

2.2 内部工作机制
Boost Ranker 在 Milvus 内部的工作流程大致为:

第一步,向量检索阶段:每个 segment 独立返回一批候选结果(包含 id、原始 score、相关元数据);

第二步,应用 Boost Ranker:

  • 使用filter表达式(可选)在候选中筛出“需要加权”的实体;

  • 对这些实体的分数按weightrandom_score做缩放;

第三步,再聚合所有 segment 的候选,按新的分数排序得到最终 TopK。

需要注意的是 Boost Ranker 对候选集合生效,而不是在全量数据上跑一次新查询,因此性能开销非常小。

3
什么情况下优先考虑 Boost Ranker

3.1 业务驱动的内容加权

典型场景:

  • 电商搜索:

    • 提升“旗舰店/自营/付费推广”商品的权重;

    • 提升近期销量/点击高的商品;

  • 内容/资讯搜索:

    • 提升最近一段时间内发布的内容(结合publish_time字段);

    • 提升来源为“官方账号”“认证作者”的内容;

  • 企业内部文档检索:

    • 提升doctype == 'policy'is_canonical == true的权威文档。

这些都可以通过简单的filter+weight实现,无需触碰向量模型、索引。

3.2 策略性降权与风控

另一类是温柔的隐藏而不是直接过滤:

  • 低库存但仍可售的商品:stock < 10适当降权;

  • 含有潜在敏感词的内容:打一点折扣,但不做硬过滤;

  • 过旧的文档:例如year < 2020适当往后排。

优势是:用户仍能在某些场景看到这些结果,但它们会自然地出现在靠后位置。

3.3 探索/多样化:利用 random_score

Boost Ranker 支持random_score字段:

    "random_score": {"seed": 126,"field": "id"}
    • seed:随机数种子,控制全局一致性;

    • field:作为随机数生成的输入(通常用主键),保证同一条数据多次搜索随机结果一致

    可以用它来:

    • 在同一相似度的多个候选中稍微“打散”顺序,避免永远只看到相同 Top;

    • 配合固定权重做固定 + 小范围随机的混合排序,用于推荐系统里的探索策略。

    3.4 与其它 Ranker 的关系与限制
    • Boost Ranker 是通过Function(FunctionType.RERANK, params.reranker='boost')创建的rerank 函数

    • 它不能作为多向量 hybrid search(多个向量字段一起搜)的顶层 ranker,但可以作为每个AnnSearchRequest的 ranker 使用。

    • 可以与其他 Ranker 组合:

      • 比如先用 RRF Ranker 融合多模态结果,再用 Boost Ranker 做基于元数据的微调;

      • 或者模型 Ranker 提升语义相关性,然后 Boost Ranker 叠加业务规则。

    4 核心参数与使用注意事项

    Boost Ranker 是通过FunctionFunctionScore(可选)配置的。

    4.1 创建 Boost Ranker 所需的字段

    Python 里一般这么创建(后面实战会给完整代码):

    • name:这个 Function 的名字;

    • input_field_names:Boost Ranker 必须是空列表[]

    • function_type:固定使用FunctionType.RERANK

    • params.reranker:固定字符串"boost",告诉 Milvus 使用 Boost Ranker。

    4.2 重点参数:weight、filter、random_score

    (1)params.weight(必填)

    • 对所有命中 filter 的实体,将其原始分数乘以此权重;

    • 选择规则和度量有关:

    如果“分数越小越好”(典型是距离类度量),要 提升 某类结果,就用 < 1 的权重; 如果“分数越大越好”,要提升就用 > 1 的权重。

    (2)params.filter(可选)

    一条基础的标量过滤表达式,例如

    • "doctype == 'abstract'"

    • "is_premium == true"

    • "views > 1000 and category == 'tech'"

    (3)params.random_score(可选)

    • 结构:{"seed": 126, "field": "id"};

    • 返回 0~1 的随机值,可与 weight 配合产生轻微扰动;

    • 建议同时设置 seed 与 field,保证多次请求中结果可复现。

    4.3 单 Boost Ranker vs 多 Boost Ranker
    • 单 Boost Ranker

      • 适合只有一条主规则,比如“提升摘要文档”“打压过旧文档”;

      • 直接在search(..., ranker=ranker)里传入即可。

    • 多 Boost Ranker 组合

      • boost_mode:单个函数内部如何组合原始分数与其权重(乘法/加法);

      • function_mode:多个 Boost Ranker 之间如何合并(乘法/加法)。

      • 当业务有多条规则(例:优先有库存 + 轻微打压低评分 + 增加一点随机探索),可以创建多个Function,然后通过FunctionScore组合,配置:

    5 实战:文档检索中提升“官方”文档权重

    5.1 场景设定与数据建模

    假设我们有一个集合milvus_collection,字段如下:

    • id: INT64 主键;

    • embedding: FLOAT_VECTOR,content字段的embeddding数据;

    • content: VARCHAR,文档内容;

    • source: VARCHAR,取值如"official","community","ticket"等。

    • is_official: BOOL, 官方文档(即source是official)为True,否则是False。

    5.2 创建集合与插入示例数据
    from pymilvus import (MilvusClient,DataType,Function,FunctionType,)# 1. 连接 Milvusclient = MilvusClient(uri="http://localhost:19530")collection_name = "milvus_collection"# 如果已存在就先删除,方便反复调试if collection_name in client.list_collections():client.drop_collection(collection_name)# 2. 定义 schemaschema = 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. 创建 Collectionclient.create_collection(collection_name=collection_name,schema=schema,)# 4. 创建索引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. 加载 Collection 到内存client.load_collection(collection_name=collection_name)docs = [{"id": 1,"content": "如何在 Kubernetes 上部署 Milvus(官方手册)","source": "official","is_official": True},{"id": 2,"content": "Milvus 在 Docker Compose 下的快速部署(官方教程)","source": "official","is_official": True},{"id": 3,"content": "社区经验:Milvus部署经验之谈","source": "community","is_official": False},{"id": 4,"content": "工单记录:Milvus 部署问题","source": "ticket","is_official": False},]client.insert(collection_name=collection_name,data=docs,)
    5.3 定义 Boost Ranker 并执行搜索

    我们希望:在语义相关性相近的情况下,Milvus官方文档优先出现。​​​​​​​

    # 6. 基线搜索(不加 Boost Ranker)query_vector = "如何部署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. 定义 Boost Ranker:给 is_official == true 的文档加权boost_official_ranker = Function(name="boost_official",input_field_names=[], # Boost Ranker 要求必须为空列表function_type=FunctionType.RERANK,params={"reranker": "boost", # 指定使用 Boost Ranker"filter": "is_official==true",# 对于 COSINE / IP(分数越大越好),使用 >1 的权重进行提升"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=Trueid=4, score=0.7017, source=ticket, is_official=Falseid=3, score=0.6706, source=community, is_official=Falseid=2, score=0.6435, source=official, is_official=True=== Search with Boost Ranker (official boosted) ===id=1, score=0.8821, source=official, is_official=Trueid=2, score=0.7722, source=official, is_official=Trueid=4, score=0.7017, source=ticket, is_official=Falseid=3, score=0.6706, source=community, is_official=False
    5.4 结果变化背后的逻辑
    • 在原始向量相似度差距不大的前提下,is_official == true 的文档更容易出现在前几名;

    • 社区 / 工单类文档仍会出现在结果中,只是相对靠后。

    • 这正是 Boost Ranker 要解决的问题:把“官方优先”等业务规则叠加到语义检索结果上。

    总结

    Boost Ranker作为Milvus 2.6的新功能,极大地扩展了向量数据库的灵活性,让搜索不再局限于纯向量相似度,而是能融入业务逻辑,实现更精准的排名。

    通过本文的介绍和更真实的实践案例,读者可以快速理解并应用这一功能。在未来,随着AI应用的深化,Boost Ranker将在RAG、推荐和检索系统中发挥更大作用。

    THE END !

    文章结束,感谢阅读。您的点赞,收藏,评论是我继续更新的动力。大家有推荐的公众号可以评论区留言,共同学习,一起进步。

    版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
    网站建设 2026/3/24 1:01:35

    【教育 Agent 学情分析核心算法】:揭秘AI驱动个性化学习的底层逻辑

    第一章&#xff1a;教育 Agent 学情分析的演进与核心价值随着人工智能技术在教育领域的深度渗透&#xff0c;教育 Agent 作为个性化学习系统的核心组件&#xff0c;其学情分析能力经历了从规则驱动到数据驱动的显著演进。早期的学情分析依赖预设的教学逻辑和静态评估模型&#…

    作者头像 李华
    网站建设 2026/3/25 12:37:02

    39、技术与应用综合指南

    技术与应用综合指南 1. 系统基础与安装 1.1 Linux 系统概述 Linux 是一种广泛应用于桌面计算机的操作系统,具有安全性高、开源等优点。其运行需要一定的内存支持,最低要求为 9GB 的 RAM。Linux 系统的文件系统以根目录(/)为基础,包含多个重要文件夹,如 /lib、/media、…

    作者头像 李华
    网站建设 2026/3/24 16:21:48

    常用的3个安全扫描工具从安装到实战用法拆解

    一、OWASP ZAP(Web 应用安全扫描,开源免费) 核心定位 专注 Web 应用漏洞检测,支持自动扫描 + 手动渗透,可发现 SQL 注入、XSS、CSRF 等常见漏洞,适合开发 / 测试人员快速排查 Web 系统风险。 安装流程 下载:访问 OWASP ZAP 官方网站,根据系统选择 Windows/macOS/Linu…

    作者头像 李华
    网站建设 2026/3/24 9:36:15

    延迟优化迫在眉睫,云边 Agent 的5大瓶颈你中了几个?

    第一章&#xff1a;延迟优化迫在眉睫&#xff0c;云边 Agent 的5大瓶颈你中了几个&#xff1f;随着边缘计算与云原生架构的深度融合&#xff0c;云边协同中的 Agent 组件成为影响系统响应延迟的关键节点。然而&#xff0c;在实际部署中&#xff0c;许多团队忽视了 Agent 在资源…

    作者头像 李华
    网站建设 2026/3/25 13:14:38

    【网络安全】全网最全的渗透测试介绍(超详细)

    【网络安全】全网最全的渗透测试介绍&#xff08;超详细&#xff09; 渗透测试介绍 渗透测试就是模拟攻击者入侵系统&#xff0c;对系统进行一步步地渗透&#xff0c;发现系统地脆弱环节和隐藏风险。最后形成测试报告提供给系统所有者。系统所有者可根据该测试报告对系统进行…

    作者头像 李华