You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Milvus向量数据库,如何对不含Slack的检索结果文档进行评分惩罚?

实现Milvus查询结果的评分惩罚方案

针对你遇到的问题——查询"slack onboarding"时,需要对未同时包含这两个关键词的文档进行评分惩罚,以下是几种实用的实现方法:

方法一:向量查询后,本地检查关键词并重打分

这是最直接的方案,先通过Milvus拿到初始向量匹配结果,再在应用层处理分数:

  • 执行向量查询,获取结果集及原始余弦相似度分数(Milvus返回的余弦值为0-1范围,通常转成百分比方便处理)。
  • 遍历每个结果的content字段,检查是否同时包含"slack"和"onboarding"(建议统一转小写避免大小写问题)。
  • 对未同时包含两个关键词的文档,通过固定减分或系数乘法降低其分数,最后重新排序返回。

示例代码(Python SDK):

from pymilvus import connections, Collection

# 连接Milvus并指定集合
connections.connect("default", host="localhost", port="19530")
collection = Collection("your_collection")

# 生成查询向量(假设你有现成的embedding生成函数)
query_emb = generate_embedding("slack onboarding")

# 执行向量查询
raw_results = collection.search(
    data=[query_emb],
    anns_field="embeddings",
    param={"metric_type": "COSINE", "params": {"nprobe": 10}},
    limit=10,
    output_fields=["content"]
)[0]

# 处理评分惩罚
penalized_hits = []
for hit in raw_results:
    content_lower = hit.entity.get("content").lower()
    original_score = hit.score * 100  # 转成百分比(如0.855→85.5)
    # 判断是否同时包含两个关键词
    if "slack" not in content_lower or "onboarding" not in content_lower:
        # 这里用固定减15分,也可替换为乘法系数(如*0.7)
        adjusted_score = original_score - 15
    else:
        adjusted_score = original_score
    penalized_hits.append({
        "content": hit.entity.get("content"),
        "score": round(adjusted_score, 1)
    })

# 按调整后的分数降序排序
penalized_hits.sort(key=lambda x: x["score"], reverse=True)

方法二:预构建倒排索引,混合查询后合并结果

利用Milvus对字符串字段的倒排索引支持,先过滤出符合关键词条件的文档,再对所有候选结果做分数调整:

  1. 提前给content字段创建倒排索引(只需执行一次):
collection.create_index(
    field_name="content",
    index_params={"index_type": "INVERTED", "metric_type": "L2"}
)
  1. 同时执行两种查询:
    • 混合查询:通过倒排索引过滤出同时包含"slack"和"onboarding"的文档,再做向量匹配。
    • 普通向量查询:拿到所有高相似度的候选结果。
  2. 对比两个结果集,对未通过关键词过滤的文档施加惩罚,最后合并排序。

示例代码片段:

# 执行混合查询(仅返回符合关键词条件的结果)
filtered_hits = collection.search(
    data=[query_emb],
    anns_field="embeddings",
    param={"metric_type": "COSINE", "params": {"nprobe": 10}},
    limit=5,
    output_fields=["content"],
    expr='content like "%slack%" and content like "%onboarding%"'
)[0]
# 记录符合条件的文档ID
valid_ids = {hit.id for hit in filtered_hits}

# 执行普通向量查询拿到所有候选
all_hits = collection.search(
    data=[query_emb],
    anns_field="embeddings",
    param={"metric_type": "COSINE", "params": {"nprobe": 10}},
    limit=10,
    output_fields=["content"]
)[0]

# 处理惩罚
penalized_results = []
for hit in all_hits:
    original_score = hit.score * 100
    adjusted_score = original_score * 0.7 if hit.id not in valid_ids else original_score
    penalized_results.append({
        "content": hit.entity.get("content"),
        "score": round(adjusted_score, 1)
    })

penalized_results.sort(key=lambda x: x["score"], reverse=True)

方法三:增强查询向量+重排

通过优化查询向量的生成逻辑,让Milvus初始返回的结果更偏向包含"slack"的文档,再结合关键词检查二次调整:

  • 分别生成"slack onboarding"和"slack"的向量,将两者加权合并(比如0.6主向量 + 0.4slack向量),作为最终查询向量。
  • 对初始查询结果再做关键词检查,对不符合条件的文档施加额外惩罚,进一步筛选精准结果。

注意事项

  • 关键词匹配时可考虑用分词工具(如Jieba、NLTK)处理,避免部分匹配的问题(比如"slackbot"被误判为包含"slack")。
  • 惩罚幅度需根据业务场景调整,建议测试不同的减分/系数值,确保符合条件的文档始终排在前列。
  • 如果使用Milvus 2.2+版本,可结合集成的CrossEncoder重排功能,将关键词匹配作为重排特征,实现更精准的分数调整。

内容的提问来源于stack exchange,提问作者James K J

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 17:53:19