feat(rag): modularize knowledge retrieval pipeline

This commit is contained in:
zhuyongxin
2026-07-06 17:06:05 +08:00
parent a375daead7
commit cf3333d607
38 changed files with 2981 additions and 1033 deletions
+8 -6
View File
@@ -1,6 +1,6 @@
# MVP 架构文档
**更新日期**:2026-07-05
**更新日期**:2026-07-06
这里是 MVP 当前架构的唯一入口。旧版设计、早期拆解和已经被新实现替代的方案已归档到:
@@ -17,6 +17,7 @@
| [agent-orchestration.md](agent-orchestration.md) | Agent 编排细节,覆盖 Chat SequentialAgent、AIOps SupervisorAgent、工具边界 |
| [harness-quality-gates.md](harness-quality-gates.md) | Prompt、Hook、Trace、Verifier、评测基线组成的质量门禁 |
| [rag-architecture.md](rag-architecture.md) | RAG/知识检索新架构,覆盖 L0 hint、VectorStore 主路径、SDK fallback、证据追踪 |
| [modular-rag-pipeline.md](modular-rag-pipeline.md) | `lookup_knowledge` 模块化 RAG 落地架构,覆盖 pipeline、fallback、evidence-first contract、trace |
| [retrieval-observability.md](retrieval-observability.md) | 检索运行细节和可观测性,覆盖 L0/L1、去重、分数归一、评测 |
| [feedback-architecture.md](feedback-architecture.md) | 反馈与自评估闭环,覆盖 rule evaluation、Verifier、AIOps rule、用户反馈和案例沉淀 |
| [session-trace-lifecycle.md](session-trace-lifecycle.md) | 会话和 Trace 生命周期,覆盖 sessionId、状态流转、agent_step、tool_invocation、Trace API |
@@ -35,8 +36,9 @@ SuperBizAgent MVP 是一个面向故障诊断的可追踪 Agent 系统:Chat
3. 再读 [agent-orchestration.md](agent-orchestration.md),理解当前 Agent 如何协作。
4. 然后读 [harness-quality-gates.md](harness-quality-gates.md),理解为什么系统可追踪、可验证。
5. 再读 [rag-architecture.md](rag-architecture.md),理解当前 RAG 为什么保留显式 `lookup_knowledge`,以及 Spring AI VectorStore 如何接入。
6. 继续读 [retrieval-observability.md](retrieval-observability.md),看检索细节和质量回归方式。
7. 再读 [feedback-architecture.md](feedback-architecture.md),理解 self_evaluation、用户反馈和案例沉淀。
8. 按需读 [session-trace-lifecycle.md](session-trace-lifecycle.md)、[knowledge-base-authoring.md](knowledge-base-authoring.md)、[data-model.md](data-model.md),补齐运行生命周期、知识库维护和数据关系。
9. 最后读 [evolution-roadmap.md](evolution-roadmap.md),区分后续演进和当前实现。
10. 需要追溯旧方案时,再进入 `archive/2026-07-05-legacy/`。
6. 继续读 [modular-rag-pipeline.md](modular-rag-pipeline.md),看 `lookup_knowledge` 的模块化落地和 evidence-first contract。
7. 然后读 [retrieval-observability.md](retrieval-observability.md),看检索细节和质量回归方式。
8. 再读 [feedback-architecture.md](feedback-architecture.md),理解 self_evaluation、用户反馈和案例沉淀。
9. 按需读 [session-trace-lifecycle.md](session-trace-lifecycle.md)、[knowledge-base-authoring.md](knowledge-base-authoring.md)、[data-model.md](data-model.md),补齐运行生命周期、知识库维护和数据关系。
10. 最后读 [evolution-roadmap.md](evolution-roadmap.md),区分后续演进和当前实现。
11. 需要追溯旧方案时,再进入 `archive/2026-07-05-legacy/`。
+201
View File
@@ -0,0 +1,201 @@
# 模块化 RAG Pipeline 架构
**更新日期**:2026-07-06
**状态**:当前已实现架构
**关联 OpenSpec**:`openspec/changes/archive/2026-07-06-modular-rag-pipeline`
## 1. 定位
本文记录 `lookup_knowledge` 的当前模块化 RAG 实现。它是 [rag-architecture.md](rag-architecture.md) 的落地版,重点说明代码模块、数据契约、降级策略和可观测性边界。
核心目标:
- 保留显式 Agent Tool:`lookup_knowledge(query)`。
- L0 只作为 query understanding / filter / rerank / trace hint。
- L1 向量检索作为事实证据来源。
- filtered L1 低质量时,降级为 raw query unfiltered L1 retry。
- 输出 evidence-first contract,替代旧 `primary/supplement`。
## 2. 当前链路
```mermaid
flowchart TD
Agent["Executor Agent"] --> Tool["LookupKnowledgeTool.lookupKnowledge(query)"]
Tool --> Transform["KnowledgeQueryTransformer"]
Transform --> KQ["KnowledgeQuery"]
KQ --> Retriever["KnowledgeDocumentRetriever"]
Retriever --> Attempt1["FILTERED_VECTOR or UNFILTERED_VECTOR"]
Attempt1 --> Post1["KnowledgeEvidencePostProcessor"]
Post1 --> Quality{"usable evidence?"}
Quality -->|yes| Pack
Quality -->|no and categoryFilter exists| Retry["UNFILTERED_VECTOR_RETRY"]
Retry --> Post2["KnowledgeEvidencePostProcessor"]
Post2 --> Pack["KnowledgeContextPacker"]
Pack --> Assemble["LookupResultAssembler"]
Assemble --> Result["LookupResult"]
Result --> Dedup["RetrievedDocTracker session dedup"]
Dedup --> Recorder["ToolInvocationRecorder"]
Recorder --> Trace["tool_invocation.retrieval_details"]
Result --> Agent
```
对应代码:
| 阶段 | 类 | 职责 |
|---|---|---|
| Tool Boundary | `LookupKnowledgeTool` | 接收 Agent 工具调用,编排 pipeline,处理 session dedup 和 recorder |
| Query Transformation | `KnowledgeQueryTransformer` | 复用 L0,输出 query hints 和可选 category filter |
| Retrieval | `KnowledgeDocumentRetriever` | 调用 `VectorSearchService`,统一 filtered / unfiltered attempt |
| Post-Retrieval | `KnowledgeEvidencePostProcessor` | L2 归一化、证据块构建、source dedup、规则 rerank |
| Context Packing | `KnowledgeContextPacker` | 按字符预算打包 Agent 可消费 context |
| Result Assembly | `LookupResultAssembler` | 统一 evidence result、no-evidence result、dedup result |
| Observability | `ToolInvocationRecorder` | 写入 query transform、retrieval trace、rerank trace、context pack summary |
## 3. L0 与 L1 边界
L0 来源于 `KnowledgeIndexService.analyzeQuery`,输出进入 `KnowledgeQuery`:
```text
originalQuery
rewrittenQuery
domainHints
matchedKeywords
entities
categoryFilter
l0Titles
l0MatchCount
```
L0 可以做:
- 给 L1 提供单一 category filter。
- 给 rerank 提供 domain / keyword / entity boost 信号。
- 给 trace 提供解释信息。
L0 不再做:
- 不因唯一命中直接返回文档正文。
- 不在 L1 无结果时作为事实证据兜底。
- 不进入 `evidenceBlocks`,除非未来明确引入新的 evidence source 规则。
L1 通过 `VectorSearchService.searchSimilarDocuments(query, topK, category)` 执行,内部仍保留 Spring AI VectorStore 优先和 Milvus SDK fallback。
## 4. 降级策略
MVP 降级策略保持简单:
```text
if categoryFilter exists:
run FILTERED_VECTOR
if empty / no evidence / top similarity < referenceThreshold:
run UNFILTERED_VECTOR_RETRY with original query
else:
run UNFILTERED_VECTOR
```
fallback reason:
| reason | 含义 |
|---|---|
| `filtered_vector_no_evidence` | filtered L1 无候选或 post-processing 后无 evidence |
| `filtered_vector_low_quality` | filtered L1 有候选,但 top normalized similarity 低于 `retrieval.normalization.reference-threshold` |
当 retry 后仍无证据:
- `found=false`
- `evidenceStatus=no_evidence`
- 保留 `retrievalTrace`
- 不返回 L0 文档作为事实证据
## 5. Evidence-First Contract
`LookupResult` 当前核心字段:
```text
found
evidenceBlocks
contextPack
retrievalTrace
rerankTrace
relevanceLevel
completenessHint
retrievedDomainsThisSession
message
```
旧字段已删除:
```text
primary
supplement
```
这是一项 L4 breaking interface change。项目内已同步迁移:
- `LookupKnowledgeTool`
- `ToolInvocationRecorder`
- executor prompts
- lookup / recorder tests
- RAG architecture docs
- OpenSpec 主 spec
## 6. Trace 结构
`retrieval_details` 保持 JSON 扩展,不改表结构。关键内容:
```json
{
"query_transform": {},
"retrieval_trace": {
"selected_attempt": "UNFILTERED_VECTOR_RETRY",
"fallback_reason": "filtered_vector_no_evidence",
"attempts": []
},
"context_pack_summary": {},
"rerank_trace": {},
"evidence_blocks": []
}
```
这样 Trace API、Verifier、Eval 可以继续从 `tool_invocation` 读取证据链。
## 7. Review 修正
归档前 review 发现:session dedup 命中时返回 `found=false`,但仍携带 `evidenceBlocks/contextPack`,可能导致 Agent 重复消费证据。
当前行为已修正:
- dedup result 不再返回可消费 evidence/context。
- 保留 message、retrieval trace、relevance hint 和 retrieved domains。
- 测试覆盖:`LookupKnowledgeToolTest.sessionDedupDoesNotReturnConsumableEvidenceAgain`。
## 8. 验证
已执行:
```powershell
mvn -q -DskipTests compile
mvn -q "-Dtest=LookupKnowledgeToolTest,ToolInvocationRecorderTest" test
$env:MILVUS_TOKEN = <application.yml 中的 milvus.token>; mvn -q test
openspec validate --all --strict
git diff --check
```
结果:全部通过。
注意:
- `MilvusConnectionTest` 直接读 `MILVUS_TOKEN` 环境变量,不读 Spring 配置。
- 完整测试需要在 Maven 进程里注入该环境变量。
## 9. 后续演进
建议后续按评测结果推进,而不是先堆复杂能力:
- 增加 RAG eval cases:固定 query、期望 source、期望 fallback path。
- 引入更严格的 evidence grounding 检查。
- 当规则 rerank 不足时,再考虑 model-based rerank。
- 当召回覆盖率不足时,再考虑 BM25/RRF/hybrid retrieval。
+37 -36
View File
@@ -1,6 +1,6 @@
# RAG 新架构
**更新日期**:2026-07-05
**更新日期**:2026-07-06
**状态**:当前主架构 + 后续演进边界
**关联计划**:`mvp/issues/rag-refactor-plan.md`
@@ -44,9 +44,13 @@ flowchart TD
SdkFallback --> Results
SdkOnly --> Results
Results --> Normalize["relevance normalization"]
Normalize --> Dedup["session dedup: RetrievedDocTracker"]
Dedup --> Output["LookupResult"]
Results --> Retry{"filtered result usable?"}
Retry -->|no| RetryL1["raw query unfiltered L1 retry"]
Retry -->|yes| Post["post-retrieval processing"]
RetryL1 --> Post
Post --> Pack["context packing"]
Pack --> Dedup["session dedup: RetrievedDocTracker"]
Dedup --> Output["LookupResult: evidenceBlocks / contextPack / traces"]
Output --> Record["tool_invocation record"]
Output --> Agent
```
@@ -66,10 +70,13 @@ Agent Executor
-> Spring AI VectorStore only
-> mode=sdk
-> Milvus SDK only
-> result normalization
-> post-retrieval processing
-> relevanceLevel
-> completenessHint
-> score/rawScore/scoreLabel
-> evidenceBlocks
-> rerankTrace
-> context packing
-> contextPack
-> session dedup
-> RetrievedDocTracker
-> tool_invocation record
@@ -180,10 +187,11 @@ L0 负责:
- metadata/category filter candidate
- trace 中的 hit reason
L0 不再默认负责:
L0 不再负责:
```text
L0 unique hit -> 直接作为最终检索结果
L1 no result -> 返回 L0 文档作为事实证据
```
当前职责是:
@@ -192,8 +200,10 @@ L0 unique hit -> 直接作为最终检索结果
query / AIOps payload
-> L0 matched keywords / domains / entities
-> category filter candidate
-> L1 semantic retrieval
-> relevance normalization
-> filtered L1 semantic retrieval
-> low-quality? raw query unfiltered L1 retry
-> post-retrieval processing
-> context packing
```
这样既保留精确关键词和领域 hint 的价值,也避免 L0 误召回直接污染最终证据。
@@ -319,33 +329,24 @@ AIOps payload
## 9. Evidence 与去重
当前 evidence 输出仍以 `LookupResult` 和工具返回文本为主,已经具备:
当前 evidence 输出已从旧 `primary/supplement` 迁移为 evidence-first contract,核心字段包括:
- L0/L1 命中数量。
- 检索层记录。
- relevance level。
- completeness hint。
- session 级文档去重。
- domain 行动记忆。
- `tool_invocation` 明细记录。
- `evidenceBlocks`
- `contextPack`
- `retrievalTrace`
- `rerankTrace`
- `relevanceLevel`
- `completenessHint`
- `retrievedDomainsThisSession`
- `tool_invocation.retrieval_details`
后续更完整的 evidence block 目标:
evidence block 结构:
```text
source
docId
chunkIndex
title
breadcrumb
score
rawScore
scoreLabel
hitReason
content
expandedFrom
source / title / breadcrumb / retrievalLayer / content / score / hitReasons
```
这部分应作为下一阶段增强,而不是当前已完全完成能力。
context pack 会按重排后的证据顺序生成 Agent 可消费的紧凑上下文,并保留 included/omitted sources 供 trace 检查。
## 10. 评测与验收
@@ -380,18 +381,18 @@ RAG 架构变更必须先过评测,再认为可合入主链路。
- Markdown chunk 保留 `title` 和 `breadcrumb`。
- embedding 输入包含 `title`、`breadcrumb` 和 `content`。
- AIOps payload 生成推荐知识库 query。
- `tool_invocation` 记录 relevance level 和 dedup reason。
- `tool_invocation` 记录 relevance level、dedup reason、evidence summaries、retrieval trace、rerank trace 和 context pack summary。
- `lookup_knowledge` 输出使用 evidence-first contract,不再暴露旧 `primary/supplement` 字段。
- RAG offline baseline 和 live acceptance 脚本已补齐。
## 12. 后续演进
近期优先:
1. 完整 evidence block 结构化输出。
2. 命中 chunk 的相邻 chunk / 同章节上下文扩展。
3. metadata taxonomy 清理,例如 `database` 与 `infrastructure` 的分类边界。
4. Query Transformer / MultiQuery 的可回退接入。
5. VectorStore 写入路径评估。
1. 命中 chunk 的相邻 chunk / 同章节上下文扩展。
2. metadata taxonomy 清理,例如 `database` 与 `infrastructure` 的分类边界。
3. Query Transformer / MultiQuery 的可回退接入。
4. VectorStore 写入路径评估。
暂不优先:
+24 -16
View File
@@ -1,6 +1,6 @@
# 检索与可观测性架构
**更新日期**:2026-07-05
**更新日期**:2026-07-06
**状态**:当前可运行架构
**参考历史文档**:`archive/2026-07-05-legacy/knowledge-retrieval-architecture.md`
@@ -13,7 +13,7 @@
- 检索结果如何归一化、去重、记录。
- 如何通过 trace 和 eval 判断检索质量。
当前架构与旧版最大的差异是:L0 不再因为唯一命中而默认跳过 L1。L0 是 hint 和解释信号,L1 语义检索是默认召回路径。
当前架构与旧版最大的差异是:L0 不再因为唯一命中而默认跳过 L1,也不在 L1 失败时作为事实证据兜底。L0 是 hint 和解释信号,L1 语义检索是默认召回路径。
## 2. 检索总图
@@ -35,9 +35,13 @@ flowchart TD
Spring --> Candidates["L1 candidates"]
SDK --> Candidates
Candidates --> Normalize["relevance normalization"]
L0Result --> Normalize
Normalize --> Result["LookupResult"]
Candidates --> Quality{"filtered L1 usable?"}
Quality -->|no| Retry["raw query unfiltered L1 retry"]
Quality -->|yes| Post["post-retrieval processing"]
Retry --> Post
L0Result --> Post
Post --> Pack["context packing"]
Pack --> Result["LookupResult evidenceBlocks/contextPack/traces"]
Result --> Dedup["RetrievedDocTracker session dedup"]
Dedup --> Final["final tool output"]
@@ -69,6 +73,7 @@ singleDomainOrNull
```text
matches=1 -> skip L1 -> 直接返回 L0 文档正文
L1 无可用证据 -> 返回 L0 文档正文
```
原因:
@@ -123,12 +128,12 @@ SDK fallback 保留的价值:
| `rawScore` | 底层检索实现原始分数 |
| `scoreLabel` | 原始分数语义,例如 `similarity` 或 `l2_distance` |
工具层再把 L0/L1 情况归一为:
post-retrieval 层再把检索候选归一为:
| relevanceLevel | 含义 |
|---|---|
| `PRECISE` | L0 单命中且 L1 相似度高 |
| `HIGHLY_RELEVANT` | L1 相似度高,或 L0 多命中且 L1 支撑强 |
| `PRECISE` | L1 相似度高且 query hint 与候选证据互相支撑 |
| `HIGHLY_RELEVANT` | L1 相似度高 |
| `REFERENCE` | 可作为参考,但不足以声明强证据 |
| `DEDUPED` | 同 session 中已检索过,不重复注入上下文 |
@@ -169,7 +174,7 @@ title + breadcrumb + content
```mermaid
flowchart LR
LookupResult["LookupResult"] --> Agent["Agent context"]
LookupResult["LookupResult: evidenceBlocks/contextPack/traces"] --> Agent["Agent context"]
LookupResult --> Recorder["ToolInvocationRecorder"]
Recorder --> Invocation["tool_invocation"]
Invocation --> Trace["DiagnosisTraceService"]
@@ -195,10 +200,13 @@ success
`retrieval_details` 承载更细信息,例如:
- L0 命中文档标题和路径。
- L1 分数。
- L1 attempts、fallback reason、分数和 similarity。
- retrieved domains。
- evidence status。
- dedup reason。
- evidence block summaries。
- context pack summary。
- rerank trace。
## 8. 去重与行动记忆
@@ -252,15 +260,15 @@ trace inspection
近期优先:
1. 完整 evidence block 输出。
2. 邻居 chunk / 同章节上下文扩展。
3. metadata taxonomy 清理。
4. Query Transformer / MultiQuery 可回退接入。
5. 更完整的 Recall@K、MRR、nDCG 报告。
1. 邻居 chunk / 同章节上下文扩展。
2. metadata taxonomy 清理。
3. Query Transformer / MultiQuery 可回退接入。
4. 更完整的 Recall@K、MRR、nDCG 报告。
暂不优先:
- 重新引入 L0 直接返回。
- 重新引入 L0 文档作为 L1 失败时的事实证据兜底。
- 一次性迁移所有写入路径。
- 在没有评测收益前引入 rerank / RRF / BM25。
- 在没有评测收益前引入模型 rerank / RRF / BM25。