# RAG 新架构 **更新日期**:2026-07-06 **状态**:当前主架构 + 后续演进边界 **关联计划**:`mvp/issues/rag-refactor-plan.md` ## 1. 架构目标 RAG 重构的目标不是把所有能力交给框架,也不是继续维护一套完全自研检索框架,而是形成: ```text 成熟框架能力 + 业务可观测编排 ``` 具体原则: - 通用向量检索能力交给 Spring AI `VectorStore`。 - 项目保留 Agent Tool 入口、AIOps 业务 query 映射、证据打包、trace 记录。 - `lookup_knowledge` 继续是显式工具,不替换成隐式 Advisor。 - Spring AI 读取路径作为主路径,Milvus SDK 作为 fallback。 - 所有检索行为必须可评测、可回放、可解释。 ## 2. 当前主链路 ```mermaid flowchart TD Agent["Agent Executor"] --> Tool["lookup_knowledge(query)"] Tool --> L0["KnowledgeIndexService.analyzeQuery"] L0 --> Hint["L0 hint: domain / entities / matchedKeywords"] Hint --> Filter["category filter candidate"] Tool --> Search["VectorSearchService.searchSimilarDocuments"] Filter --> Search Search --> Mode{"retrieval.vector-store.mode"} Mode -->|auto| SpringTry["try Spring AI VectorStore"] SpringTry -->|success| Results["SearchResult list"] SpringTry -->|failure| SdkFallback["Milvus SDK fallback"] Mode -->|spring / spring-ai| SpringOnly["Spring AI VectorStore only"] Mode -->|sdk| SdkOnly["Milvus SDK only"] SpringOnly --> Results SdkFallback --> Results SdkOnly --> Results 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 ``` ```text Agent Executor -> lookup_knowledge(query) -> KnowledgeIndexService.analyzeQuery -> L0 domain/entity hint -> matchedKeywords -> category filter candidate -> VectorSearchService.searchSimilarDocuments -> mode=auto -> Spring AI VectorStore -> fallback: Milvus SDK -> mode=spring / spring-ai -> Spring AI VectorStore only -> mode=sdk -> Milvus SDK only -> post-retrieval processing -> relevanceLevel -> completenessHint -> evidenceBlocks -> rerankTrace -> context packing -> contextPack -> session dedup -> RetrievedDocTracker -> tool_invocation record ``` 运行配置: ```properties retrieval.vector-store.mode=auto retrieval.normalization.max-l2-distance=2.0 retrieval.normalization.highly-relevant-threshold=0.75 retrieval.normalization.reference-threshold=0.5 ``` ## 3. 稳定边界 ```mermaid flowchart LR subgraph AgentBoundary["Agent boundary"] Executor["Executor Agent"] Tool["LookupKnowledgeTool"] end subgraph RetrievalBoundary["Retrieval boundary"] Search["VectorSearchService"] Spring["Spring AI VectorStore"] SDK["Milvus SDK"] end subgraph ObservabilityBoundary["Observability boundary"] Invocation["tool_invocation"] Eval["RAG baseline / trace inspection"] end Executor --> Tool Tool --> Search Search --> Spring Search --> SDK Tool --> Invocation Invocation --> Eval ``` ### 3.1 Agent 边界 Agent 只知道自己可以调用 `lookup_knowledge`,不直接关心底层是 Spring AI VectorStore 还是 Milvus SDK。 ```text Executor -> LookupKnowledgeTool -> VectorSearchService ``` 这个边界让 RAG 底层迁移不影响 Agent prompt、工具声明和 trace 数据结构。 ### 3.2 检索边界 `VectorSearchService` 是当前检索门面: - `auto`:优先 Spring AI VectorStore,失败后 fallback 到 SDK。 - `spring` / `spring-ai`:只走 Spring AI VectorStore。 - `sdk`:只走原 Milvus SDK。 这样可以在不改 Agent 工具的情况下切换检索实现,并支持线上验证和回退。 ### 3.3 可观测边界 无论底层检索路径如何变化,都必须写入 `tool_invocation`: ```text sessionId toolName inputParams outputPreview retrievalLayer l0MatchCount l1MatchCount retrievalDetails relevanceLevel dedupReason duration success ``` ## 4. L0 的新职责 旧版 L0 容易承担过重职责,例如唯一匹配后直接跳过 L1。当前架构中 L0 被降级为 hint 层。 ```mermaid flowchart TD Input["query / AIOps payload"] --> L0["L0 hint analysis"] L0 --> Domain["domain detector"] L0 --> Entity["entity extractor"] L0 --> Keyword["matched keyword explanation"] L0 --> Filter["metadata/category filter candidate"] Domain --> Retrieval["L1 semantic retrieval"] Entity --> Retrieval Keyword --> Trace["hit reason in tool_invocation"] Filter --> Retrieval Retrieval --> Normalize["relevance normalization"] Normalize --> Evidence["evidence returned to Agent"] ``` L0 负责: - domain detector - entity extractor - matched keyword explanation - metadata/category filter candidate - trace 中的 hit reason L0 不再负责: ```text L0 unique hit -> 直接作为最终检索结果 L1 no result -> 返回 L0 文档作为事实证据 ``` 当前职责是: ```text query / AIOps payload -> L0 matched keywords / domains / entities -> category filter candidate -> filtered L1 semantic retrieval -> low-quality? raw query unfiltered L1 retry -> post-retrieval processing -> context packing ``` 这样既保留精确关键词和领域 hint 的价值,也避免 L0 误召回直接污染最终证据。 ## 5. L1 向量检索 L1 语义检索通过 `VectorSearchService` 调度。 ```mermaid flowchart TD Search["VectorSearchService"] --> Request["SearchRequest: query / topK / threshold / filter"] Request --> VectorStore["Spring AI VectorStore"] VectorStore --> Docs["Document results"] Docs --> Map["map to SearchResult"] Map --> Score["score compatibility mapping"] Search --> SDK["Milvus SDK fallback"] SDK --> SdkRows["id / content / metadata / L2 distance"] SdkRows --> Map Score --> Output["id / content / metadata / score / rawScore / scoreLabel"] ``` ### Spring AI VectorStore 路径 ```text SearchRequest -> query -> topK -> similarityThresholdAll -> optional filterExpression: category == '...' -> VectorStore.similaritySearch ``` 返回结果会映射为项目兼容结构: ```text id content metadata score rawScore scoreLabel ``` ### Milvus SDK fallback SDK 路径仍保留: - 用于 `auto` 模式兜底。 - 用于与旧链路对比。 - 用于 VectorStore 配置或 collection schema 异常时保证 MVP 可运行。 ## 6. 分数语义 旧 SDK 使用 L2 distance,Spring AI 返回 similarity。两者不能混用为同一个含义。 当前统一输出: | 字段 | 含义 | |---|---| | `score` | 兼容旧逻辑的距离型分数,越小越近 | | `rawScore` | 底层实现的原始分数 | | `scoreLabel` | `l2_distance` 或 `similarity` | SDK 路径: ```text score = L2 distance rawScore = L2 distance scoreLabel = l2_distance ``` VectorStore 路径: ```text rawScore = Spring AI similarity scoreLabel = similarity score = metadata.distance if available else compatible distance ``` ## 7. 文档切片和 embedding 输入 当前保留 Markdown-aware chunking: - 识别 Markdown 标题层级。 - 生成 `title`。 - 生成 `breadcrumb`。 - 保留 `chunkIndex`。 - 使用 token 估算和软/硬上限控制 chunk 大小。 - 尽量不打断列表和代码块。 embedding 输入中已经加强: ```text title + breadcrumb + content ``` 这样可以降低单个 chunk 脱离章节上下文后的召回损失。 ## 8. AIOps query 增强 AIOps payload 中的业务字段不能完全交给通用检索框架隐式理解。 payload 模式会把以下字段拼成推荐知识库 query: - `alertName` - `service` - `severity` - `description` - `timeRange` - `userRequest` Prompt 会明确要求 Agent 在需要知识库证据时,优先使用推荐 query 或保留 alertName/service 的更窄 query。 ```text AIOps payload -> buildKnowledgeRetrievalQuery -> Recommended lookup_knowledge query -> lookup_knowledge -> tool_invocation ``` ## 9. Evidence 与去重 当前 evidence 输出已从旧 `primary/supplement` 迁移为 evidence-first contract,核心字段包括: - `evidenceBlocks` - `contextPack` - `retrievalTrace` - `rerankTrace` - `relevanceLevel` - `completenessHint` - `retrievedDomainsThisSession` - `tool_invocation.retrieval_details` evidence block 结构: ```text source / title / breadcrumb / retrievalLayer / content / score / hitReasons ``` context pack 会按重排后的证据顺序生成 Agent 可消费的紧凑上下文,并保留 included/omitted sources 供 trace 检查。 ## 10. 评测与验收 RAG 架构变更必须先过评测,再认为可合入主链路。 当前评测资产: - `eval/rag-retrieval/cases/golden-cases.json` - `eval/rag-retrieval/fixtures/` - `eval/rag-retrieval/reports/baseline.json` - `eval/rag-retrieval/reports/baseline.md` - `scripts/eval_rag_retrieval.py` - `scripts/eval_rag_live_acceptance.py` 评测层次: | 层次 | 作用 | |---|---| | Offline baseline | 不依赖 MySQL、Redis、Milvus、LLM,用固定 fixtures 检查召回行为 | | Live acceptance | 应用运行并重建索引后,调用 `/api/search/similar` 验证真实检索 | | Trace inspection | 通过 `tool_invocation` 检查 Agent 是否真的使用了证据 | ## 11. 当前已完成 - `lookup_knowledge` 保持显式 Agent Tool。 - L0 降级为 domain/entity hint。 - L1 默认执行语义检索。 - `VectorSearchService` 支持 `auto`、`spring`/`spring-ai`、`sdk` 三种模式。 - Spring AI VectorStore 成为读取主路径。 - Milvus SDK fallback 保留。 - 分数语义拆成 `score`、`rawScore`、`scoreLabel`。 - Markdown chunk 保留 `title` 和 `breadcrumb`。 - embedding 输入包含 `title`、`breadcrumb` 和 `content`。 - AIOps payload 生成推荐知识库 query。 - `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. 命中 chunk 的相邻 chunk / 同章节上下文扩展。 2. metadata taxonomy 清理,例如 `database` 与 `infrastructure` 的分类边界。 3. Query Transformer / MultiQuery 的可回退接入。 4. VectorStore 写入路径评估。 暂不优先: - 把 `lookup_knowledge` 替换成隐式 Advisor。 - 完整自研 RRF 框架。 - 立即引入 Elasticsearch / OpenSearch。 - 立即引入 cross-encoder 或 LLM rerank。 ## 13. 关键代码索引 | 能力 | 代码 | |---|---| | Agent 工具入口 | `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java` | | L0 hint | `src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java` | | 向量检索门面 | `src/main/java/com/superbiz/agent/service/VectorSearchService.java` | | 文档切片 | `src/main/java/com/superbiz/agent/service/DocumentChunkService.java` | | 文档管理 | `src/main/java/com/superbiz/agent/service/DocumentManagementService.java` | | 向量写入 | `src/main/java/com/superbiz/agent/service/VectorIndexService.java` | | AIOps query 增强 | `src/main/java/com/superbiz/agent/service/AiOpsService.java` | | 工具调用记录 | `src/main/java/com/superbiz/agent/service/ToolInvocationRecorder.java` |