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
+1
View File
@@ -5,6 +5,7 @@
| 日期 | slug | 领域 | 关键词 | 状态 |
|---|---|---|---|---|
| 2026-07-05 | diagnosis-playbook-skills | Agent Skill/Playbook | read_skill, diagnosis playbook, progressive disclosure, payment timeout, MySQL pool, Redis timeout | openspec/changes/diagnosis-playbook-skills | implemented |
| 2026-07-06 | modular-rag-pipeline | RAG/Agent工具/证据链 | modular RAG, lookup_knowledge, evidenceBlocks, contextPack, rerank, retrievalTrace, L0 hint, unfiltered retry | openspec/changes/archive/2026-07-06-modular-rag-pipeline | archived |
| 2026-07-05 | mvp-demo-interview-runbook | MVP Demo/Interview | Plan C, payment timeout, runbook, trace checklist, demo script | openspec/changes/archive/2026-07-05-mvp-demo-interview-runbook | archived |
| 2026-07-05 | diagnosis-eval-baseline-diff | Agent 评测/回归 Diff | baseline diff, regression detection, evidence coverage, cost signal, markdown report | openspec/changes/archive/2026-07-05-diagnosis-eval-baseline-diff | archived |
| 2026-07-04 | expand-diagnosis-eval-fixtures | Agent 评测/回归 Baseline | fixture coverage, baseline report, redis timeout, slow response, jvm memory risk | openspec/changes/archive/2026-07-05-expand-diagnosis-eval-fixtures | archived |
@@ -0,0 +1,101 @@
# Modular RAG Pipeline — Acceptance
## 验收状态
状态:通过,OpenSpec 已归档。
任务完成:
- OpenSpec tasks:31/31 完成。
- Review 后新增去重边界修复和回归测试。
- OpenSpec archive:`openspec/changes/archive/2026-07-06-modular-rag-pipeline`。
## 静态验证
```powershell
openspec validate modular-rag-pipeline --strict
```
结果:
```text
Change 'modular-rag-pipeline' is valid
```
```powershell
git diff --check
```
结果:
```text
PASS
```
说明:仅出现 Windows LF/CRLF warning,无 whitespace error。
## 脚本验证
```powershell
mvn -q -DskipTests compile
```
结果:PASS。
```powershell
mvn -q "-Dtest=LookupKnowledgeToolTest,ToolInvocationRecorderTest" test
```
结果:PASS。
覆盖:
- filtered L1 成功不 retry。
- filtered L1 低质量触发 raw unfiltered retry。
- filtered L1 无 evidence 触发 raw unfiltered retry。
- L0 hint 不作为 standalone fact evidence。
- 无 L0 hint 时直接 unfiltered vector search。
- rerank 使用 hint match 并记录 trace。
- context pack 保留 source/title/breadcrumb/hit reasons。
- evidence blocks 按 source 去重。
- session dedup 不再返回可消费 evidence/context。
- recorder 记录 retrieval trace、rerank trace、context pack summary 和 evidence summaries。
```powershell
$env:MILVUS_TOKEN = <application.yml 中的 milvus.token>; mvn -q test
```
结果:PASS。
说明:
- `MilvusConnectionTest` 需要 `MILVUS_TOKEN` 环境变量,直接读 `System.getenv`,不会自动读 `application.yml`。
- 注入该环境变量后完整测试通过。
## 实现验收
已验证行为:
- `LookupKnowledgeTool` 已变为 pipeline orchestrator。
- `LookupResult` 新契约包含 `evidenceBlocks`、`contextPack`、`retrievalTrace`、`rerankTrace`。
- 旧 `primary/supplement` 字段和 DTO 已删除。
- `ToolInvocationRecorder` 不再依赖 `result.getPrimary()`。
- filtered retrieval 失败时会记录 `filtered_vector_no_evidence` 或 `filtered_vector_low_quality`。
- no-evidence 情况返回 `found=false` 且保留 retrieval trace。
- session dedup 情况返回 `found=false` 且 evidence/context 为空。
## 未验证项
人工 Demo 未执行:
- 还没有通过真实 Chat/AIOps 会话观察 Agent 是否稳定按 `contextPack.packedText` 和 `evidenceBlocks` 引用证据。
风险:
- 工具 JSON 契约是 L4 breaking change,prompt 已更新,但真实对话行为仍建议做一次端到端 demo。
## 后续建议
- 增加一组 RAG eval cases,固定 query、期望 evidence source、期望 fallback path。
- 将 `MilvusConnectionTest` 改成 Spring 配置驱动或 integration profile,避免配置源混用。
- 后续可在评测数据足够后再考虑 model-based rerank 或 hybrid retrieval。
@@ -0,0 +1,54 @@
# Modular RAG Pipeline — Brief
## 背景
`lookup_knowledge` 已经能返回知识库证据,但实现集中在 `LookupKnowledgeTool` 内部:L0 查询分析、L1 向量召回、相关性归一化、证据组装、会话去重和 trace 入库耦合在一起。
旧返回契约 `primary/supplement` 也延续了“L0 是主结果、L1 是补充”的语义,和当前设计目标不一致。新的目标是让 L0 只作为 query understanding / filter / rerank / trace 信号,让 L1 向量检索成为事实证据来源。
## 目标
- 将 `lookup_knowledge` 改造成模块化 RAG pipeline。
- 保留显式 Agent tool 边界,不改工具名和 query 参数。
- L0 只提供领域、关键词、实体、category filter 和 trace hint。
- L1 filtered vector retrieval 失败或低质量时,降级为 raw query unfiltered L1 retry。
- 输出 evidence-first contract:`evidenceBlocks`、`contextPack`、`retrievalTrace`、`rerankTrace`。
- 保持 `tool_invocation` 表结构稳定,把新 trace 写入 `retrieval_details` JSON。
## 范围
已完成:
- 新增 pipeline DTO:`KnowledgeQuery`、`RetrievedEvidenceCandidate`、`ContextPack`、`RetrievalTrace`、`RerankTrace`、`EvidencePostprocessResult`。
- 新增 pipeline service:`KnowledgeQueryTransformer`、`KnowledgeDocumentRetriever`、`KnowledgeEvidencePostProcessor`、`KnowledgeContextPacker`、`LookupResultAssembler`。
- 重构 `LookupKnowledgeTool` 为薄 orchestration 层。
- 迁移 `LookupResult`,删除 `primary/supplement` 字段和 `PrimaryResult` / `SupplementResult` 类。
- 更新 `ToolInvocationRecorder`,记录 query transform、retrieval trace、context pack summary、rerank trace、fallback reason 和 evidence summaries。
- 更新 executor prompt 和 RAG 架构文档。
- 补充 lookup、recorder、fallback、rerank、context pack、session dedup 测试。
非目标:
- 不引入 implicit Advisor。
- 不引入 cross-encoder、BM25、RRF、Elasticsearch、OpenSearch。
- 不改文档上传、chunk、embedding 写入、Milvus schema。
- 不改变 Agent 何时调用 `lookup_knowledge`。
## 关联 OpenSpec
- `openspec/changes/archive/2026-07-06-modular-rag-pipeline`
## 接口影响
级别:L4 breaking interface。
原因:
- 删除旧 `LookupResult.primary` / `LookupResult.supplement`。
- `lookup_knowledge` tool JSON 输出形状变化。
缓解:
- 工具名和输入参数保持不变。
- in-repo 消费方、测试和 prompt 同步迁移。
- `tool_invocation` 表结构不变。
@@ -0,0 +1,72 @@
# Modular RAG Pipeline — Decisions
## D1: `lookup_knowledge` 保持显式工具
不把知识检索做成隐式 Advisor。Agent 仍显式调用 `lookup_knowledge(query)`,这样 trace、Verifier、Eval 都能看到工具调用边界。
## D2: L0 只做 query understanding
L0 产出:
- `domainHints`
- `matchedKeywords`
- `entities`
- `categoryFilter`
- `l0Titles`
- `l0MatchCount`
L0 不再直接转成 fact evidence。L0 hint 可以影响 filter、rerank、trace,但不能在 L1 失败时冒充知识证据。
## D3: MVP 降级策略采用 unfiltered L1 retry
流程:
```text
filtered L1 with L0 category filter
-> empty / no final evidence / below reference threshold
-> raw query unfiltered L1 retry
-> still no evidence => no_evidence
```
取舍:
- 简单、可解释、适合 MVP。
- 避免引入 BM25/RRF/multi-query/cross-encoder 的复杂度。
- 代价是低质量场景多一次向量查询,已通过 trace 记录 attempt duration。
## D4: 删除 `primary/supplement`
这是一次 L4 breaking interface change。
删除原因:
- `primary/supplement` 绑定旧语义:L0 primary、L1 supplement。
- 新设计中事实证据来自 `evidenceBlocks/contextPack`。
迁移结果:
- `LookupResult` 暴露 evidence-first 字段。
- `PrimaryResult` / `SupplementResult` 已删除。
- 生产代码和测试不再引用 `getPrimary()` / `getSupplement()`。
## D5: Trace 表结构保持稳定
`tool_invocation` 表不新增列。新增信息写入 `retrieval_details` JSON:
- `query_transform`
- `retrieval_trace`
- `context_pack_summary`
- `rerank_trace`
- `fallback_reason`
- `evidence_blocks`
原因:当前 trace、Verifier、Eval 已经以 `tool_invocation` 为证据入口,JSON details 足够承载 RAG 细节,避免 schema churn。
## D6: 会话去重不返回可消费证据
Review 后修正:
- dedup result 的 `found=false` 必须和 evidence/context 语义一致。
- 返回消息说明文档已检索过。
- 不再返回 `evidenceBlocks/contextPack`,避免 Agent 重复使用同一证据。
- 保留 `retrievalTrace` 和 `retrievedDomainsThisSession` 便于可观测。
@@ -0,0 +1,56 @@
# Modular RAG Pipeline — Evidence
## 代码证据
关键入口:
- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java`
- `src/main/java/com/superbiz/agent/service/ToolInvocationRecorder.java`
- `src/main/java/com/superbiz/agent/dto/LookupResult.java`
新增模块:
- `KnowledgeQueryTransformer`:复用 `KnowledgeIndexService.analyzeQuery`,把 L0 转成 query hints 和可选 `categoryFilter`。
- `KnowledgeDocumentRetriever`:封装 `VectorSearchService.searchSimilarDocuments(query, topK, category)`,统一 filtered / unfiltered attempt。
- `KnowledgeEvidencePostProcessor`:归一化 L2、创建 evidence blocks、source dedup、规则 rerank、输出 `RerankTrace`。
- `KnowledgeContextPacker`:按字符预算打包 evidence,保留 source/title/breadcrumb/hit reasons。
- `LookupResultAssembler`:统一组装 evidence-first result、no-evidence result、session dedup result。
## 设计证据
已有文档约束:
- `mvp/architecture/rag-architecture.md`:RAG 应表达为可解释 pipeline,而不是一坨工具逻辑。
- `mvp/architecture/retrieval-observability.md`:L0 是 hint/explainability 层,L1 是语义检索主路径。
- `devflow/glossary/CONTEXT.md`:`lookup_knowledge` 是显式 Agent evidence tool,`tool_invocation` 是 trace / verifier / eval 的证据来源。
OpenSpec 对齐:
- `openspec/changes/modular-rag-pipeline/proposal.md`
- `openspec/changes/modular-rag-pipeline/design.md`
- `openspec/changes/modular-rag-pipeline/specs/rag-knowledge-retrieval/spec.md`
- `openspec/changes/modular-rag-pipeline/tasks.md`
## 用户确认
- 一次到位做模块化 RAG,而不是只做小补丁。
- L0 不再作为事实证据兜底。
- filtered L1 不准时,MVP 降级为 raw query unfiltered L1 retry。
- 可以新增字段,并删除旧字段以换取后续流程清晰。
## Review 发现
Review 中发现一个非阻塞但应修复的问题:
- 会话去重命中时,返回 `found=false` 但仍带 `evidenceBlocks/contextPack`,可能导致 Agent 重复消费同一份证据。
修复:
- `LookupResultAssembler.deduped` 清空可消费 evidence/context,只保留 message、trace、relevance hint 和 session domain memory。
- 新增 `LookupKnowledgeToolTest.sessionDedupDoesNotReturnConsumableEvidenceAgain`。
## 非阻塞观察
- `MilvusConnectionTest` 仍直接依赖 `MILVUS_TOKEN` 环境变量;主配置中已有 token,但测试不读 Spring 配置。
- 测试日志仍有 ANTLR 版本 warning,不影响测试通过。
- 控制台在部分命令输出中仍会出现中文编码显示问题,但源码按 UTF-8 读取时关键用户提示文本正常。