# Change: Unify RAG quality score (dense/hybrid labels) and stop keyword boost re-rank ## Why BM25 hybrid 已在库内完成 dense + BM25 + RRF 融合,但后处理仍: 1. 把 hybrid 结果**伪装成 L2** 再 `normalizeL2`(含 `bm25_only_no_dense` 弱分占位); 2. 用 L0 domain/entity/keyword **contains 加分改主序**。 这导致:排序信号与质量闸门分裂;词面信号被 BM25 与后处理**双重计分**;「词面热、语义冷」的片段可能被抬到前面;hybrid 的 RRF 序被冲掉。 需要统一:**检索负责序,后处理只做 quality 归一化 + 裁剪装配**。 ## What Changes ### 检索层(`MilvusHybridKnowledgeStore` / `VectorSearchService`) - 一级 `scoreLabel` 仅两种:`dense` | `hybrid`(与 `retrieval.search.mode` 对齐)。 - **废弃**正式一级 label:`l2_distance` / `rrf_fused` / `bm25_only_no_dense`(可读兼容映射到 dense/hybrid)。 - `mode=dense`:`score` = L2 距离,`label=dense`,`originalRank` = ANN 序。 - `mode=hybrid`:`label=hybrid`;**不再**用 dense L2 覆盖主 `score`;**不再**对 BM25-only 伪造 maxL2;`originalRank` = RRF 返回序;`rawScore` 可保留引擎融合分。 - `mode=dense|hybrid` **保留**:hybrid 为线上主路径;dense 为同库对照/评测(已写入架构 §6.0)。 ### 归一化(新) - 新增唯一转换点 `RetrievalScoreNormalizer.toQualityScore(label, score, rank, batchSize, maxL2)` → `qualityScore ∈ [0,1]`(越大越好)。 - `dense`:`1 - clamp(L2)/maxL2Distance` - `hybrid`:按 **rank** 映射(本轮 batch 线性),不把 RRF 原分当 L2 套公式。 - Label 差异**只**在此消化。 ### 后处理(`KnowledgeEvidencePostProcessor`) - **统一流程**,只消费 `qualityScore` + `originalRank`(label-agnostic)。 - **排序主序 = `originalRank` 升序**(保检索序);去掉 domain/entity/keyword/source_type **加分改序**。 - L0 contains 匹配若保留,仅写入 `hitReasons` / trace 解释,**不参与 sort key、不加 finalScore**。 - `relevance_level` / `isLowQuality` / category unfiltered retry:只看 top `qualityScore` 与既有阈值;**不再**要求 `hasHintSupport` 才能 PRECISE。 - 保留:evidenceKey 去重、`max-chunks-per-document`、`return-n`、excerpt 截断、EvidenceBlock 装配。 ### 文档 / 测试 - 更新 `mvp/architecture/RAG知识检索架构.md` §6 分数与后处理约定。 - 单测:dense 路径 quality 与现 L2 归一化一致;hybrid 保序且不被 keyword 打乱;无 `bm25_only` 一级 label;旧 label 别名可 canonicalize。 ## Non-goals - Cross-encoder / listwise 精排、query rewrite、邻块扩展。 - 删除 `mode=dense` 对照开关。 - 改变 Agent 可见 ACI 字段结构(`evidence[]` / `relevance_level` 枚举名可不变;**分布会变**)。 - 修改 Milvus schema / 强制全量 rebuild(本 change 不改 collection 结构)。 - 上线可配 `max(rank, denseSim)` 混合 quality(可后续迭代;本 change 切片 1 用纯 rank 映射 hybrid)。 ## Context constraints (from devflow) - 承接 archived:`rag-chunk-evidence-identity-dedup`、`rag-bm25-hybrid-drop-sdk`、`rag-hybrid-search-rrf`、`modular-rag-pipeline`。 - 单一知识后端仍为 `MilvusHybridKnowledgeStore`(V2);不得恢复 sdk/spring 主路径路由。 - Agent 投影仍不暴露 raw fused score / 完整 contextPack 作为主契约(内部 LookupResult/trace 可保留调试字段)。 - 历史 decision「Dense L2 enrichment for threshold compatibility」**本 change 有意废止**,改为 qualityScore 统一闸门。 ## Impact - **行为变化(对内检索质量语义)**: - hybrid 下证据顺序更贴近 RRF; - 词面命中不再被后处理 contains 二次抬序; - `relevance_level` 与 unfiltered retry 触发分布可能变化; - BM25-only 命中不再被标成 quality≈0。 - **接口影响**:L2(内部 DTO/注释/scoreLabel 字符串约定);Agent ACI 字段名不变。 - **风险**:hybrid rank→quality 为序数映射,绝对值不跨 query 可比;阈值 0.75/0.5 可能需后续观测再调(本 change 先沿用配置项)。 ## Scale - **standard**(多文件、有意行为变化、需 design + specs + tasks + 测试)。 ## Depends on - 已落地 hybrid schema + chunk evidenceKey(archived changes 如上)。 - 对话已确认的设计口径(见 change `decisions.md`)。 ## WIP note - 工作区可能已有未接线的 `RetrievalScoreLabels` / `RetrievalScoreNormalizer` 草稿文件;apply 阶段以 **Committed OpenSpec** 为准接入或改写,不视为已完成实现。