feat(harness,rag): dual LLM audit fields, run conclusion, and hybrid quality

Persist provider reasoning and assistant text separately on agent_reasoning_audit
(DeepSeekAssistantMessage path), extract diagnosis_run.conclusion, enrich RAG
tool audit (step_id/query/qualityScore), gate empty mysql tools, drop devtools,
and align MVP docs after live E2E verification.
This commit is contained in:
zhuyongxin
2026-07-28 19:43:13 +08:00
parent 2f40536248
commit 7ae9707a3b
116 changed files with 8364 additions and 1141 deletions
@@ -0,0 +1,80 @@
# 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** 为准接入或改写,不视为已完成实现。