docs(mvp): update RAG docs for py-rag extraction

- rewrite RAG architecture doc for py-rag service contract mapping, ingest and rebuild ops
- refresh observability/trace doc for post-L0 single-attempt semantics
- add py-rag chain exploration note; mark superseded Milvus/L0 notes with status banners
- close ISS-017 (superseded by L0 sinking); mark knowledge_domain table orphaned
- refresh architecture/mvp/engineering indexes
This commit is contained in:
zhuyongxin
2026-09-30 17:03:50 +08:00
parent 9cf162482d
commit 473bb5d004
16 changed files with 597 additions and 343 deletions
@@ -1,8 +1,14 @@
# RAG 检索可观测性、审计与 Trace(现行)
**更新日期**:2026-07-28
**更新日期**:2026-09-29
**状态**:当前可运行
**关联**:`lookup_knowledge`、Harness `ToolBoundary`、`tool_invocation`、`DiagnosisTraceService`、离线 eval
**关联**:`lookup_knowledge`、Harness `ToolBoundary`、`tool_invocation`、`DiagnosisTraceService`、离线 eval
> **2026-09-29 RAG 抽离影响**:检索后端切换为 py-rag 服务(见 [RAG知识检索架构.md](./RAG知识检索架构.md))。
> Trace / 审计的三层边界与读写接口**不变**;变化仅在内容语义:
> L0 已下沉(`queryHints` 恒为空结构、`categoryFilter` 恒为 null、attempt 只剩 `UNFILTERED_VECTOR`),
> 质量分统一为 py-rag rerank 绝对分(scoreLabel=RERANK)。
> 文中涉及 FILTERED/RETRY attempt 的示例为历史数据读法,保留供回放旧 Run。
---
@@ -119,21 +125,21 @@ flowchart TB
| 字段 | 含义 |
|------|------|
| `originalQuery` | 原始查询 |
| `rewrittenQuery` | L0/变换后用于检索的 query |
| `categoryFilter` | 首次过滤的 category(可 null) |
| `rewrittenQuery` | 用于检索的 query(L0 下沉后恒等于 originalQuery) |
| `categoryFilter` | 首次过滤的 category(L0 下沉后恒为 null) |
| `selectedAttempt` | 最终采用的 attempt 名 |
| `fallbackReason` | 如 `filtered_vector_low_quality`;未降级为 null |
| `evidenceStatus` | 内部:`supported` / `no_evidence` 等 |
| `queryHints` | L0:domains、keywords、entities、l0_match_count… |
| `queryHints` | L0 提示(下沉后恒为空 domains/keywords/entities 与 l0_match_count=0) |
| `attempts[]` | 每次检索尝试快照 |
**常见 `selectedAttempt`:**
**`selectedAttempt` 取值:**
| 值 | 含义 |
|----|------|
| `FILTERED_VECTOR` | 带 category 的首次检索即采用 |
| `UNFILTERED_VECTOR` | 无 category,直接全库检索 |
| `UNFILTERED_VECTOR_RETRY` | filtered 低质/无证据后去掉 category 重试 |
| `UNFILTERED_VECTOR` | **当前唯一会出现**:无 category,直传 py-rag 检索 |
| `FILTERED_VECTOR` | (历史)带 category 的首次检索即采用;L0 下沉后不再产生 |
| `UNFILTERED_VECTOR_RETRY` | (历史)filtered 低质/无证据后去掉 category 重试;分支保留但不可达,仅见于旧 Run 回放 |
**单次 `attempts[]` 元素:**
@@ -148,21 +154,18 @@ flowchart TB
| `durationMs` | 耗时 |
| `errorMessage` | 失败时 |
### 3.3 一次典型路径(含 filter fallback)
### 3.3 一次典型路径(当前:单 attempt 直传)
```mermaid
flowchart TB
Q[query] --> L0[L0 hint → 可选 categoryFilter]
L0 --> A1[attempt FILTERED_VECTOR]
A1 --> PQ{isLowQuality?}
PQ -->|否| USE1[selectedAttempt = FILTERED_VECTOR]
PQ -->|是| A2[attempt UNFILTERED_VECTOR_RETRY]
A2 --> USE2[selectedAttempt = RETRY<br/>fallbackReason = low_quality / no_evidence]
USE1 --> POST[PostProcess · evidenceBlocks · relevanceLevel]
USE2 --> POST
Q[query 原始句直传] --> A1[attempt UNFILTERED_VECTOR<br/>PyRagKnowledgeSearchAdapter → py-rag]
A1 --> POST[PostProcess · evidenceBlocks · relevanceLevel]
POST --> LR[LookupResult 完整 Trace]
```
> 历史 filter fallback 路径(L0 → FILTERED_VECTOR → 低质 → UNFILTERED_VECTOR_RETRY)的流程图已随 L0 下沉移除;
> 旧 Run 的 Trace 回放仍可见该结构,字段含义见 §3.2。
### 3.4 与 Agent 投影的关系
```mermaid
@@ -208,35 +211,27 @@ flowchart LR
| `output_preview` | level/attempt 摘要 | status=… |
| `duration_ms` / `success` | 有 | 有 |
### 4.3 `retrieval_details`(rag_lookup_v1)示例
### 4.3 `retrieval_details`(rag_lookup_v1)示例(当前形态)
```json
{
"audit_schema": "rag_lookup_v1",
"search_mode": "hybrid",
"selected_attempt": "UNFILTERED_VECTOR_RETRY",
"fallback_reason": "filtered_vector_low_quality",
"category_filter": "overfilter-decoy",
"evidence_keys": ["doc#chunk-0"],
"sources": ["doc"],
"evidence_candidate_count": 8,
"selected_attempt": "UNFILTERED_VECTOR",
"fallback_reason": null,
"category_filter": null,
"evidence_keys": ["e2e-gateway-b9c1fa12-md-34223174#chunk-1"],
"sources": ["e2e-gateway-b9c1fa12-md"],
"evidence_candidate_count": 5,
"evidence_block_count": 2,
"l0_hints": { "domains": ["mysql"], "matched_keywords": ["pool"] },
"l0_hints": { "domains": [], "matched_keywords": [] },
"attempts": [
{
"name": "FILTERED_VECTOR",
"category_filter": "overfilter-decoy",
"candidate_count": 2,
"usable": false,
"top_similarity": 0.3,
"duration_ms": 12
},
{
"name": "UNFILTERED_VECTOR_RETRY",
"name": "UNFILTERED_VECTOR",
"candidate_count": 5,
"usable": true,
"top_similarity": 0.9,
"duration_ms": 20
"top_similarity": 0.91,
"duration_ms": 640
}
],
"truncated": false,
@@ -247,7 +242,8 @@ flowchart LR
}
```
**默认不落库:** 原始 query 全文、chunk 正文 excerpt、完整 rerankTrace(体积与隐私)。
**默认不落库:** 原始 query 全文、chunk 正文 excerpt、完整 rerankTrace(体积与隐私)。
历史 Run 中 `selected_attempt=FILTERED_VECTOR` / `UNFILTERED_VECTOR_RETRY` 与非空 `l0_hints` 为 L0 下沉前的旧数据形态。
### 4.4 Trace API:人怎么读 RAG
@@ -304,12 +300,12 @@ flowchart TB
| 现象 | 优先看 |
|------|--------|
| 为何走了 retry | `fallback_reason` + 两次 `attempts` |
| 是否 hybrid | `search_mode` |
| 滤错域 | `category_filter` + L0 domains |
| 是否 hybrid | `search_mode`(hybrid/semantic 对应 py-rag 融合/纯向量) |
| 滤错域 | (历史)`category_filter` + L0 domains;L0 下沉后恒为 null |
| 相关度档 | 列 `relevanceLevel`(PRECISE/REFERENCE) |
| 返回了哪些块 | `evidence_keys` / `sources`(无正文) |
| Agent 是否被截断 | `truncated` / `returned_count` |
| 为何走了 retry | (历史)`fallback_reason` + 两次 `attempts`;L0 下沉后单 attempt,不再产生 |
### 4.6 diagnosis_trace 事件 vs tool_invocation 行
@@ -352,10 +348,11 @@ flowchart LR
| 旧(archive `retrieval-observability`) | 现 |
|----------------------------------------|-----|
| `vector-store.mode` 多后端 | `search_mode` dense\|hybrid,单一 V2 store |
| `vector-store.mode` 多后端 | `search_mode` dense\|hybrid(现映射 py-rag semantic\|hybrid) |
| sink 理想化未落地 | `RagLookupAuditEnricher` + 列回填 |
| `relevance_level` 混用 evidence_status | **列仅 RAG 等级**;契约状态在 details |
| 未写清 Trace API 读法 | 本文 §4.4–4.5 |
| L0 hint / FILTERED-RETRY attempt(2026-07-28 形态) | 2026-09-29 L0 下沉 py-rag:单 attempt、queryHints 恒空、质量分 RERANK 直传 |
---