51dc8dc4f6
- FastAPI + Qdrant + Redis + Ollama 技术栈 - L1→L2→L3→chunk 四层分层检索(dense + sparse RRF 融合) - 文档三级总结与 2.5 级回退 - query 解析路由与分类 - /admin 管理页面
25 lines
1.0 KiB
Python
25 lines
1.0 KiB
Python
"""检索结果重排: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]
|