docs(issues): add ISS-017 L0 filter fallback hardening

Track L0 hard-filter + unfiltered retry brittleness. Keep current
behavior; prefer A+C later and defer soft-constraint redesign (D).
This commit is contained in:
zhuyongxin
2026-07-29 10:48:47 +08:00
parent 7ae9707a3b
commit bdac35567c
2 changed files with 161 additions and 1 deletions
+2 -1
View File
@@ -1,6 +1,6 @@
# MVP Issues 索引 # MVP Issues 索引
**更新日期**:2026-07-27 **更新日期**:2026-07-28
**状态**:按活跃问题、设计笔记、RAG 问题集和已归档问题整理 **状态**:按活跃问题、设计笔记、RAG 问题集和已归档问题整理
## 目录约定 ## 目录约定
@@ -18,6 +18,7 @@
|---|---|---|---|---| |---|---|---|---|---|
| ISS-015 | 诊断运行质量与 Reasoning 审计收敛 | 高 | 部分实施 | [active/ISS-015-diagnosis-runtime-quality-and-reasoning-audit.md](active/ISS-015-diagnosis-runtime-quality-and-reasoning-audit.md) | | ISS-015 | 诊断运行质量与 Reasoning 审计收敛 | 高 | 部分实施 | [active/ISS-015-diagnosis-runtime-quality-and-reasoning-audit.md](active/ISS-015-diagnosis-runtime-quality-and-reasoning-audit.md) |
| ISS-016 | 诊断 Agent 缺少基于信息增益的停止契约 | 高 | 已实施,待归档 | [active/ISS-016-diagnosis-information-gain-stop-contract.md](active/ISS-016-diagnosis-information-gain-stop-contract.md) | | ISS-016 | 诊断 Agent 缺少基于信息增益的停止契约 | 高 | 已实施,待归档 | [active/ISS-016-diagnosis-information-gain-stop-contract.md](active/ISS-016-diagnosis-information-gain-stop-contract.md) |
| ISS-017 | RAG L0 过滤收窄与 Fallback 加固 | 中 | 开放,暂缓实施(保持现网) | [active/ISS-017-rag-l0-filter-fallback-hardening.md](active/ISS-017-rag-l0-filter-fallback-hardening.md) |
## 设计笔记 ## 设计笔记
@@ -0,0 +1,159 @@
# ISS-017 RAG L0 过滤收窄与 Fallback 加固
**状态**:开放,暂缓实施(保持现网行为)
**严重程度**:中
**发现时间**:2026-07-28
**更新日期**:2026-07-28
**来源**:hybrid + qualityScore 收口后的评测/设计讨论;`chat-l0-filter-fallback` golden case
**关联**:`LookupKnowledgeTool`、`KnowledgeQueryTransformer`、`KnowledgeEvidencePostProcessor`、`eval/rag-retrieval`、历史 `rag/rag-l0-domain-entity-hint.md`
---
## 1. 背景
当前 `lookup_knowledge` 在 L0 命中唯一 domain 时会生成 `categoryFilter`,第一次只在该 category 内检索(`FILTERED_VECTOR`),意图是 **缩小边界、降噪声**。若后处理判定低质,则去掉 filter 用原 query 再搜一次(`UNFILTERED_VECTOR_RETRY`),并记录 `filtered_vector_low_quality` / `filtered_vector_no_evidence`。
该设计方向正确,但机制偏「硬过滤赌一把 + 失败整页替换」:
```text
唯一 domain → 硬 categoryFilter
→ isLowQuality?
→ 是:全库 retry,selectedEvidence 直接换成 retry 结果
→ 否:采用过滤结果
```
hybrid 与统一 `qualityScore` 上线后,单点 `isLowQuality` 阈值更敏感;中间评测快照曾出现「该 retry 未 retry、decoy 占 top」。随后 fixture/baseline 已在特定种子下恢复 7/7 全绿,**不代表路径已稳健**,只说明当前快照可过。
**本 Issue 决策(2026-07-28)**:
- **先保留原样**,不改生产行为。
- 记录改进方向,待 RAG 主干稳定、有明确回归动机时再实施。
- **不采用**全面「软约束替代硬过滤」(原讨论方案 D)作为近期目标(复杂度高、与 RRF 权威排序边界纠缠)。
---
## 2. 用户 / 系统体验问题
1. L0 指错 category 时,诊断可能只看到 decoy 或窄池噪声,正确 runbook 进不了上下文。
2. 即使触发 retry,第一次过滤结果整页丢弃,窄路里偶然有用的 chunk 无法保留。
3. fallback 是否触发高度依赖单一质量闸门,阈值或分数语义一变,行为抖动,golden case 脆弱。
4. 审计上 `selectedAttempt` 二元切换,难以表达「窄路 + 宽路共同贡献」。
---
## 3. 现状与验证基线
### 3.1 实现位置
| 组件 | 职责 |
|---|---|
| `KnowledgeQueryTransformer` | L0 hint;唯一 domain → `categoryFilter` |
| `LookupKnowledgeTool` | `FILTERED_VECTOR` → 可选 `UNFILTERED_VECTOR_RETRY`;retry 时覆盖 `selectedEvidence` |
| `KnowledgeEvidencePostProcessor#isLowQuality` | 是否触发 fallback 的主闸门 |
| `RetrievalTrace` | `selectedAttempt` / `fallbackReason` / attempts |
### 3.2 评测
- Golden:`eval/rag-retrieval/cases/golden-cases.json` → `chat-l0-filter-fallback`
- 期望:`UNFILTERED_VECTOR_RETRY` + fallbackReason 之一 + top/source = `rag-l0-filter-fallback`
- 种子:`rag-l0-filter-fallback`(真文档)、`rag-l0-filter-decoy`(`category: overfilter-decoy`)
- 当前 **accepted baseline**(约 2026-07-28T06:55Z)对该 case 为 pass;仓库内更早的 `baseline-diff.*` 可能仍是中间失败快照,**不以陈旧 diff 为现状**。
### 3.3 非目标(本 Issue 不解决)
- 重做 hybrid / RRF / qualityScore 统一(已收口)。
- EvidenceGuard / Agent 如何用证据写结论。
- 全面取消 L0 或永远全库检索。
- **方案 D**:弱化 category 硬过滤、改为 domain 软加权全面替代(明确搁置)。
---
## 4. 目标(实施时)
在 **保留「缩小边界」先验** 的前提下,降低 over-filter 脆性:
1. 只有 **高置信** L0 才使用硬 `categoryFilter`;中/低置信不锁门。
2. 一旦触发宽路 rescue,**合并** 窄路与宽路候选后再后处理,禁止无条件整页替换。
3. fallback 触发使用 **多信号**(空/不可用、过少候选、低质且实体重叠差等),避免单阈值独裁。
4. Trace/golden 能表达 rescue/merge,而不只绑死某一个 attempt 字符串。
5. `chat-l0-filter-fallback` 与主路径 case 在改动后仍可回归;允许演进断言语义(见 §6)。
---
## 5. 推荐方案(实施优先级)
### 5.1 方案 A — 置信度分级收窄(优先,低复杂度)
| L0 置信 | 行为 |
|---|---|
| 高(唯一 domain + 强关键词/标题等可标定信号) | 硬 `categoryFilter`(保持收窄) |
| 中 | 不硬过滤;domain 仅 hint/审计 |
| 低/无 | 直接全库 hybrid |
可选:多信号触发 retry(空结果、candidateCount 过低、低质等)。
### 5.2 方案 C — Retry 后 merge(优先,低~中复杂度)
触发 `UNFILTERED_VECTOR_RETRY` 后:
- 合并两次候选(按 `evidenceKey` dedup)
- 再跑统一 `EvidencePostProcessor` / pack
- 不要 `selectedEvidence = retryEvidence` 直接覆盖
Trace 可增加 `rescue_used` / `merged` 类字段,或扩展 `selectedAttempt` 语义。
### 5.3 方案 B — 两路并行(可选,中复杂度)
高置信硬过滤时同时跑窄路 + 较小 topK 宽路,merge 后处理。用延迟换稳定;可在 A+C 之后视延迟预算决定。
### 5.4 方案 D — 全面软约束(搁置)
不作为本 Issue 实施范围。仅当知识库噪声结构变化、证明硬过滤长期帮倒忙时再单独立项。
---
## 6. 验收标准(实施阶段)
- [ ] 默认/高置信路径仍体现「可收窄」;中低置信不再误锁唯一 category。
- [ ] Over-filter 构造下,最终 context **包含** 期望文档(如 `rag-l0-filter-fallback`),且存在可审计的 rescue/merge 痕迹。
- [ ] Retry/merge 不丢弃窄路中仍有价值的 `evidenceKey`(在宽路未覆盖时)。
- [ ] Offline eval:`chat-l0-filter-fallback` 与其它 golden 全绿或仅含已文档化的 intentional diff。
- [ ] 断言可演进为「发生过 rescue + 最终命中真文档」,不必永久绑定旧 attempt 枚举字面量。
- [ ] 普通 SUCCESS 诊断路径无回归(时延、top 证据、token 量级可接受)。
- [ ] **不**重新引入 keyword boost 颠覆 RRF/qualityScore 主序。
---
## 7. 实施阶段建议(未开工)
| 阶段 | 内容 | 状态 |
|---|---|---|
| 0 | 本 Issue 记录;**保持现网原样** | 已完成 |
| 1 | 方案 A:高置信才硬过滤 + 触发条件澄清 | 未开始 |
| 2 | 方案 C:retry merge + Trace 字段 | 未开始 |
| 3 | 更新 golden/fixture/baseline;可选方案 B | 未开始 |
| — | 方案 D | 明确不做(本 Issue) |
每阶段独立 focused tests + offline eval;不与 ISS-015 Repair Schema 捆绑。
---
## 8. 风险与约束
- 放宽硬过滤可能增加噪声进入 pack → 需靠 topK/pack 预算与现有 quality 闸门兜住。
- Merge 可能略增后处理成本;双路并行增加一次检索延迟。
- 改 attempt 语义会动审计/文档/eval,需同步 `RagLookupAuditEnricher` 与 MVP 检索文档。
- 在未实施前,运维上依赖:eval 种子 category 正确、decoy 隔离、baseline 以最新 accepted 报告为准。
---
## 9. 决议摘要
| 项 | 决议 |
|---|---|
| 现网行为 | **保持原样** |
| 近期实施 | **否**(开放跟踪) |
| 首选方向 | **A + C** |
| 可选后续 | B |
| 不做 | D(全面软约束) |
| 严重程度 | 中(路径敏感,非主链路阻断) |