"""检索结果重排:RRF 融合与最终截断""" from qdrant_client import models def rrf_fuse(result_lists: list[list[models.ScoredPoint]], k: int = 60) -> list[models.ScoredPoint]: """标准 RRF(Reciprocal Rank Fusion)融合 融合分 = Σ 1/(k + rank)(rank 从 1 开始),按 point id 去重合并, 返回按融合分降序的列表,score 字段写回融合分。空输入返回 []。 """ scores: dict[str | int, float] = {} points: dict[str | int, models.ScoredPoint] = {} for results in result_lists: for rank, point in enumerate(results, start=1): scores[point.id] = scores.get(point.id, 0.0) + 1.0 / (k + rank) points.setdefault(point.id, point) ordered = sorted(points, key=lambda pid: scores[pid], reverse=True) return [points[pid].model_copy(update={"score": scores[pid]}) for pid in ordered] def finalize(points: list[models.ScoredPoint], final_k: int) -> list[models.ScoredPoint]: """截断为最终返回的 top final_k""" return points[:final_k]