diff --git a/mvp/issues/README.md b/mvp/issues/README.md index a98a0b0..fae233d 100644 --- a/mvp/issues/README.md +++ b/mvp/issues/README.md @@ -6,3 +6,32 @@ | ISS-002 | Executor 无约束重复调用 lookup_knowledge | 中 | 已修复 | [ISS-002-executor-unconstrained-lookup.md](ISS-002-executor-unconstrained-lookup.md) | | ISS-003 | MVP 设计与实现 Review 收敛 | 高 | 待规划 | [ISS-003-mvp-design-implementation-review.md](ISS-003-mvp-design-implementation-review.md) | | ISS-004 | Executor 域级检索水位控制(Phase 2) | 低 | 待规划 | [ISS-004-executor-domain-hard-limit.md](ISS-004-executor-domain-hard-limit.md) | + +## RAG 重构计划 + +| 名称 | 标题 | 严重程度 | 状态 | 文件 | +|---|---|---|---|---| +| rag-refactor-plan | RAG 检索重构计划 | 高 | 待规划 | [rag-refactor-plan.md](rag-refactor-plan.md) | + +## RAG 检索问题 + +| 名称 | 标题 | 严重程度 | 状态 | 文件 | +|---|---|---|---|---| +| chunk-context-reconstruction | RAG 切片上下文重建缺失 | 高 | 已合并到重构计划 | [rag-chunk-context-reconstruction.md](rag-chunk-context-reconstruction.md) | +| breadcrumb-embedding-gap | RAG breadcrumb 未参与向量语义 | 高 | 已合并到重构计划 | [rag-breadcrumb-embedding-gap.md](rag-breadcrumb-embedding-gap.md) | +| l0-l1-fusion-ranking | RAG L0 和 L1 未真正融合排序 | 中 | 已合并到重构计划 | [rag-l0-l1-fusion-ranking.md](rag-l0-l1-fusion-ranking.md) | +| l0-keyword-matching-quality | RAG L0 关键词匹配质量不足 | 中 | 已合并到重构计划 | [rag-l0-keyword-matching-quality.md](rag-l0-keyword-matching-quality.md) | +| l1-score-calibration | RAG L1 分数阈值未校准 | 中 | 已合并到重构计划 | [rag-l1-score-calibration.md](rag-l1-score-calibration.md) | +| context-packing-and-reranking | RAG 缺少上下文打包和 Rerank | 中 | 已合并到重构计划 | [rag-context-packing-and-reranking.md](rag-context-packing-and-reranking.md) | +| upload-chunk-parameter-drift | RAG 上传切片参数未真正生效 | 低 | 已合并到重构计划 | [rag-upload-chunk-parameter-drift.md](rag-upload-chunk-parameter-drift.md) | +| query-rewrite-gap | RAG 查询改写能力薄弱 | 中 | 已合并到重构计划 | [rag-query-rewrite-gap.md](rag-query-rewrite-gap.md) | + +## RAG 框架化改造 + +| 名称 | 标题 | 严重程度 | 状态 | 文件 | +|---|---|---|---|---| +| spring-ai-vectorstore-migration | RAG 迁移到 Spring AI VectorStore 检索抽象 | 高 | 已合并到重构计划 | [rag-spring-ai-vectorstore-migration.md](rag-spring-ai-vectorstore-migration.md) | +| spring-ai-query-transformer | RAG 接入 Spring AI Query Transformer | 中 | 已合并到重构计划 | [rag-spring-ai-query-transformer.md](rag-spring-ai-query-transformer.md) | +| spring-ai-document-postprocessor | RAG 使用 DocumentPostProcessor 做后处理 | 中 | 已合并到重构计划 | [rag-spring-ai-document-postprocessor.md](rag-spring-ai-document-postprocessor.md) | +| l0-domain-entity-hint | RAG 将 L0 降级为领域和实体 Hint | 中 | 已合并到重构计划 | [rag-l0-domain-entity-hint.md](rag-l0-domain-entity-hint.md) | +| spring-ai-advisor-boundary | RAG 明确 Spring AI Advisor 与 Agent Tool 的边界 | 中 | 已合并到重构计划 | [rag-spring-ai-advisor-boundary.md](rag-spring-ai-advisor-boundary.md) | diff --git a/mvp/issues/rag-breadcrumb-embedding-gap.md b/mvp/issues/rag-breadcrumb-embedding-gap.md new file mode 100644 index 0000000..ee6c30e --- /dev/null +++ b/mvp/issues/rag-breadcrumb-embedding-gap.md @@ -0,0 +1,58 @@ +# RAG breadcrumb 未参与向量语义 + +**状态**:待规划 +**严重程度**:高 +**发现时间**:2026-07-04 +**范围**:向量化输入、检索相关性、知识库 metadata 使用 + +--- + +## 现象 + +当前 chunk metadata 中保存了 `title` 和 `breadcrumb`,但向量化时主要使用 `chunk.getContent()`。这意味着标题层级、所属模块、章节路径没有进入 embedding 语义空间。 + +当用户问题依赖章节语境时,例如“诊断流程里的验证步骤是什么”,如果 chunk 正文里没有重复出现完整标题语义,向量召回可能无法稳定命中正确片段。 + +--- + +## 当前实现 + +- `DocumentChunkService` 会生成 `breadcrumb`。 +- `VectorIndexService` 会把 `breadcrumb` 写入 metadata。 +- `VectorEmbeddingService` 接收的 embedding 内容来自 chunk 正文。 +- `VectorSearchService` 只基于 query embedding 和 chunk embedding 做向量搜索。 + +metadata 目前更像是展示和追踪字段,不是检索相关性的一部分。 + +--- + +## 影响 + +- 标题语义丢失,尤其影响短段落、步骤列表、配置表格类 chunk。 +- 同名概念出现在不同章节时,缺少章节路径帮助 disambiguation。 +- 用户问的是“某个模块下的问题”,检索可能只看正文关键词,忽略模块归属。 + +--- + +## 建议修复 + +构建面向 embedding 的增强文本: + +```text +标题: {title} +路径: {breadcrumb} +正文: +{content} +``` + +落库时仍保留原始 `content`,避免展示内容被污染。可以新增 `embeddingText` 构造逻辑,只用于向量化。 + +后续还可以在 rerank 阶段把 `breadcrumb` 作为加权信号,例如同域、同章节、同文档优先。 + +--- + +## 相关文件 + +- `src/main/java/com/superbiz/agent/service/DocumentChunkService.java` +- `src/main/java/com/superbiz/agent/service/VectorIndexService.java` +- `src/main/java/com/superbiz/agent/service/VectorEmbeddingService.java` diff --git a/mvp/issues/rag-chunk-context-reconstruction.md b/mvp/issues/rag-chunk-context-reconstruction.md new file mode 100644 index 0000000..e55dcfb --- /dev/null +++ b/mvp/issues/rag-chunk-context-reconstruction.md @@ -0,0 +1,55 @@ +# RAG 切片上下文重建缺失 + +**状态**:待规划 +**严重程度**:高 +**发现时间**:2026-07-04 +**范围**:知识库上传、切片、向量召回、Agent 上下文组装 + +--- + +## 现象 + +同一个 Markdown 章节在内容较长时会被拆成多个 chunk。当前检索命中其中一个 chunk 后,返回给 Agent 的主要是单个 chunk 内容,不会自动把同章节的前后片段、章节标题链路、相邻 chunk 一起恢复出来。 + +这会导致两个问题: + +1. 命中片段只包含局部语义,缺少前置定义、约束条件或后续步骤。 +2. 同章节被分段后,检索结果之间缺少可追溯的关联,Agent 不一定知道它们属于同一章节。 + +--- + +## 当前实现 + +- `DocumentChunkService` 会按 Markdown 标题建立 `title` 和 `breadcrumb`,再按段落累积切片。 +- 超过阈值时仍会切断同一章节,只是尽量避免打断代码块和列表。 +- `VectorIndexService` 会把 `chunkIndex`、`totalChunks`、`title`、`breadcrumb` 放入 metadata。 +- `VectorSearchService` 查询 Milvus 后直接返回命中的 chunk,没有做相邻 chunk 扩展或 section 级聚合。 +- `LookupKnowledgeTool` 消费 L1 结果时,也没有根据 `docId + chunkIndex + breadcrumb` 回补上下文。 + +--- + +## 影响 + +- RAG 回答容易漏掉同章节中的约束条件。 +- 长流程类文档会被拆散,Agent 看到的是“片段证据”,不是“完整流程”。 +- 面试解释中需要承认:当前系统有 metadata 基础,但还没有把它用于上下文重建。 + +--- + +## 建议修复 + +优先做命中后的上下文扩展: + +1. L1 命中 chunk 后,按 `docId + chunkIndex` 拉取前后 N 个相邻 chunk。 +2. 如果 metadata 中 `breadcrumb` 相同,允许扩展到同章节的多个 chunk。 +3. 上下文打包时标记 `命中片段`、`前文`、`后文`,避免 Agent 把扩展内容误认为全部都是高置信命中。 +4. 增加 token budget 控制,超过预算时优先保留命中 chunk 和标题链路。 + +--- + +## 相关文件 + +- `src/main/java/com/superbiz/agent/service/DocumentChunkService.java` +- `src/main/java/com/superbiz/agent/service/VectorIndexService.java` +- `src/main/java/com/superbiz/agent/service/VectorSearchService.java` +- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java` diff --git a/mvp/issues/rag-context-packing-and-reranking.md b/mvp/issues/rag-context-packing-and-reranking.md new file mode 100644 index 0000000..c082720 --- /dev/null +++ b/mvp/issues/rag-context-packing-and-reranking.md @@ -0,0 +1,48 @@ +# RAG 缺少上下文打包和 Rerank + +**状态**:待规划 +**严重程度**:中 +**发现时间**:2026-07-04 +**范围**:检索后处理、证据排序、Agent 输入质量 + +--- + +## 现象 + +当前 RAG 检索主要依赖 L0/L1 的原始召回顺序,没有独立的 reranker、cross-encoder 或 LLM rerank 阶段。召回结果进入 Agent 前,也缺少统一的上下文打包策略。 + +这意味着“检索到”不等于“以最适合推理的形式喂给 Agent”。 + +--- + +## 当前实现 + +- L0 和 L1 结果由 `LookupKnowledgeTool` 拼装后返回。 +- 没有候选级 rerank。 +- 没有明确的 token budget 分配策略,例如每个文档最多占多少、命中片段和扩展片段如何排序。 +- 没有把 `title`、`breadcrumb`、score、source 统一包装成证据块。 + +--- + +## 影响 + +- 相关结果可能被排在不理想的位置。 +- 多个候选内容相近时,Agent 可能读到重复信息。 +- 证据结构不清晰,后续 verifier 或 trace 解释成本较高。 + +--- + +## 建议修复 + +1. 引入 `RetrievedEvidence` 这样的内部结构,统一承载 source、title、breadcrumb、score、hitReason、content。 +2. 做简单 rerank:关键词命中、向量分、breadcrumb 匹配、文档去重、相邻片段扩展一起排序。 +3. 上下文打包时按证据块输出,明确来源和置信度。 +4. 面试版可以先实现规则 rerank,后续再替换为 cross-encoder 或 LLM rerank。 + +--- + +## 相关文件 + +- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java` +- `src/main/java/com/superbiz/agent/service/VectorSearchService.java` +- `src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java` diff --git a/mvp/issues/rag-l0-domain-entity-hint.md b/mvp/issues/rag-l0-domain-entity-hint.md new file mode 100644 index 0000000..60f4fec --- /dev/null +++ b/mvp/issues/rag-l0-domain-entity-hint.md @@ -0,0 +1,71 @@ +# RAG 将 L0 降级为领域和实体 Hint + +**状态**:待规划 +**严重程度**:中 +**发现时间**:2026-07-05 +**范围**:L0 检索、metadata filter、业务可解释性 + +--- + +## 背景 + +当前 L0 是基于 frontmatter / keyword 的轻量检索。它具备可解释性,但不适合作为最终相关性判断。 + +在引入 Spring AI VectorStore / Retriever 后,L0 更适合从“召回主链路”调整为“检索前处理和解释信号”。 + +--- + +## 问题 + +当前 L0 如果唯一命中,容易被过度信任: + +```text +L0 unique hit -> 直接返回 / 优先采信 +``` + +这会带来误召回风险,尤其是关键词过泛、frontmatter 质量不稳定时。 + +--- + +## 改造方向 + +L0 保留,但职责调整为: + +1. **Domain detector** + - 识别 query 所属 category/domain。 + - 用于 Spring AI retriever metadata filter。 + +2. **Entity extractor** + - 识别组件名、服务名、指标名、错误码、接口名。 + - 用于 query augmentation。 + +3. **Explainability signal** + - 记录 matched keywords。 + - 解释为什么进入某个知识域。 + +目标链路: + +```text +query / payload + -> L0 domain/entity hint + -> metadata filter + query augmentation + -> vector retriever + -> post processor +``` + +--- + +## 验收标准 + +- L0 不再默认作为最终检索结果直接返回。 +- L0 命中的 domain/category 能传给 retriever filter。 +- L0 命中的实体能进入增强 query 或工具调用记录。 +- `tool_invocation` 能展示 L0 matched keywords 和使用方式。 + +--- + +## 相关文件 + +- `src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java` +- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java` +- `src/main/java/com/superbiz/agent/service/VectorSearchService.java` diff --git a/mvp/issues/rag-l0-keyword-matching-quality.md b/mvp/issues/rag-l0-keyword-matching-quality.md new file mode 100644 index 0000000..c640cba --- /dev/null +++ b/mvp/issues/rag-l0-keyword-matching-quality.md @@ -0,0 +1,53 @@ +# RAG L0 关键词匹配质量不足 + +**状态**:待规划 +**严重程度**:中 +**发现时间**:2026-07-04 +**范围**:L0 索引、frontmatter、精确召回 + +--- + +## 现象 + +L0 当前依赖文档 frontmatter 中的关键词,并使用较粗的字符串包含逻辑做匹配。关键词质量越依赖人工维护,召回稳定性越容易波动。 + +如果 frontmatter 填写不完整、同义词缺失、关键词过短或过泛,L0 就可能误召回或漏召回。 + +--- + +## 当前实现 + +- `KnowledgeIndexService` 从 `ApiDocument` metadata/frontmatter 加载关键词。 +- exact match 的判断类似: + +```java +query.contains(keywordLower) || keywordLower.contains(query) +``` + +- 没有分词、同义词归一、字段权重、关键词质量校验。 + +--- + +## 影响 + +- 短关键词容易误命中。 +- 用户换一种说法时,L0 无法命中。 +- 文档 frontmatter 质量变成检索质量的隐性前提。 + +--- + +## 建议修复 + +1. 为关键词增加最小长度、停用词、领域前缀等基础规则。 +2. 区分 `exactKeywords`、`aliases`、`domainTags`,避免所有词混在一个匹配池。 +3. 引入轻量中文分词或归一化策略,先不必上复杂搜索引擎。 +4. 上传文档时校验 frontmatter 质量,缺失关键词时给出警告。 +5. 在 issue 修复前,至少补一份知识库文档 frontmatter 编写规范。 + +--- + +## 相关文件 + +- `src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java` +- `src/main/java/com/superbiz/agent/service/DocumentManagementService.java` +- `src/main/java/com/superbiz/agent/controller/DocumentController.java` diff --git a/mvp/issues/rag-l0-l1-fusion-ranking.md b/mvp/issues/rag-l0-l1-fusion-ranking.md new file mode 100644 index 0000000..dd8afee --- /dev/null +++ b/mvp/issues/rag-l0-l1-fusion-ranking.md @@ -0,0 +1,55 @@ +# RAG L0 和 L1 未真正融合排序 + +**状态**:待规划 +**严重程度**:中 +**发现时间**:2026-07-04 +**范围**:知识检索工具、召回排序、Agent 证据质量 + +--- + +## 现象 + +当前 `lookup_knowledge` 的 L0 和 L1 更像是串行兜底关系,不是真正的多路召回融合: + +- L0 命中唯一结果时,直接返回 L0。 +- L0 不唯一或不足时,才进入 L1。 +- L1 查询 `topK=3`,但最终主要把第一条结果作为补充证据。 + +这会导致关键词召回和语义召回没有充分互补。 + +--- + +## 当前实现 + +- `LookupKnowledgeTool` 先调用 `KnowledgeIndexService.exactMatch` 做 L0。 +- 再按条件调用 `VectorSearchService.search` 做 L1。 +- L0 和 L1 结果没有统一进入候选池做 fusion ranking。 +- L1 多结果没有充分利用,相关性接近的候选可能被丢弃。 + +--- + +## 影响 + +- L0 命中但质量一般时,会压过更好的 L1 语义结果。 +- L1 找到多个相近片段时,只有 top1 被 Agent 看到,降低召回覆盖率。 +- 难以解释检索排序,因为当前更像规则分支,不是可调的排序模型。 + +--- + +## 建议修复 + +建立统一候选池: + +1. L0 和 L1 都返回候选列表。 +2. 按 `docId/chunkId` 去重。 +3. 为候选计算综合分:`keywordScore`、`vectorScore`、`domainScore`、`freshness`、`breadcrumbMatch`。 +4. 取 topN 进入上下文打包,而不是只取 L1 top1。 +5. 在 `tool_invocation` 中记录每个候选的分数组成,方便调试。 + +--- + +## 相关文件 + +- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java` +- `src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java` +- `src/main/java/com/superbiz/agent/service/VectorSearchService.java` diff --git a/mvp/issues/rag-l1-score-calibration.md b/mvp/issues/rag-l1-score-calibration.md new file mode 100644 index 0000000..8aaf866 --- /dev/null +++ b/mvp/issues/rag-l1-score-calibration.md @@ -0,0 +1,49 @@ +# RAG L1 分数阈值未校准 + +**状态**:待规划 +**严重程度**:中 +**发现时间**:2026-07-04 +**范围**:向量搜索、相关性判断、工具调用记录 + +--- + +## 现象 + +L1 语义检索使用 Milvus 向量距离后,会做相关性归一和阈值判断。但当前阈值更偏经验值,没有基于真实查询集和真实分数分布做校准。 + +由于当前使用 L2 距离,不同 embedding 模型、不同语料密度、不同 query 长度都会影响分数分布。 + +--- + +## 当前实现 + +- `VectorSearchService` 使用 query embedding 搜索 Milvus。 +- Milvus metric type 为 `L2`。 +- `LookupKnowledgeTool` 会把 L2 score 转成 normalized relevance。 +- 阈值没有配套评测集或分布统计。 + +--- + +## 影响 + +- 阈值过松时,低相关片段会进入 Agent 上下文。 +- 阈值过紧时,正确片段可能被过滤掉。 +- 面试中如果被追问“为什么这个阈值合理”,当前只能回答是 MVP 经验值。 + +--- + +## 建议修复 + +1. 固化一组 RAG 回归查询集,覆盖告警、数据库、流程规范、AIOps 诊断等场景。 +2. 记录每次 topK 的原始 L2 score、归一化分数、最终是否采纳。 +3. 统计正例和负例分布,确定阈值区间。 +4. 将阈值配置化,并在 README 或 issue 中记录选择依据。 +5. 后续引入 reranker 后,L1 阈值可以从“最终判断”退化为“粗召回过滤”。 + +--- + +## 相关文件 + +- `src/main/java/com/superbiz/agent/service/VectorSearchService.java` +- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java` +- `src/main/resources/application.yml` diff --git a/mvp/issues/rag-query-rewrite-gap.md b/mvp/issues/rag-query-rewrite-gap.md new file mode 100644 index 0000000..7a1aa85 --- /dev/null +++ b/mvp/issues/rag-query-rewrite-gap.md @@ -0,0 +1,48 @@ +# RAG 查询改写能力薄弱 + +**状态**:待规划 +**严重程度**:中 +**发现时间**:2026-07-04 +**范围**:检索工具、Agent 查询生成、召回稳定性 + +--- + +## 现象 + +当前检索主要使用 Agent 传入 `lookup_knowledge` 的原始 query。工具层没有显式的 query rewrite、同义词扩展、领域词补全或多 query 检索。 + +当用户问题口语化、上下文依赖强,或缺少领域关键词时,L0 和 L1 的召回都可能不稳定。 + +--- + +## 当前实现 + +- Agent 决定何时调用 `lookup_knowledge` 和传入什么 query。 +- `LookupKnowledgeTool` 接收 query 后直接进入 L0/L1 检索。 +- 工具层没有把用户问题改写成多个检索 query。 +- 也没有把当前任务域、Planner step、告警 payload 等上下文显式拼入检索 query。 + +--- + +## 影响 + +- Agent query 写得好时召回正常,query 写得差时检索链路缺少兜底。 +- AIOps 场景里,告警名称、服务名、指标名、故障类型之间的别名关系没有被充分利用。 +- 很难稳定复现同一类问题的检索质量。 + +--- + +## 建议修复 + +1. 在工具层增加轻量 query rewrite:原始问题、领域词增强问题、关键词查询并行召回。 +2. 对 AIOps 场景,把 alertName、service、metric、symptom 显式构造成检索 query。 +3. 记录 rewrite 前后的 query 到 `tool_invocation`,便于分析。 +4. 后续可以引入 LLM query rewrite,但 MVP 先用规则模板更可控。 + +--- + +## 相关文件 + +- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java` +- `src/main/java/com/superbiz/agent/service/KnowledgeIndexService.java` +- `src/main/java/com/superbiz/agent/service/VectorSearchService.java` diff --git a/mvp/issues/rag-refactor-plan.md b/mvp/issues/rag-refactor-plan.md new file mode 100644 index 0000000..edde42a --- /dev/null +++ b/mvp/issues/rag-refactor-plan.md @@ -0,0 +1,376 @@ +# RAG 检索重构计划 + +**状态**:待规划 +**严重程度**:高 +**发现时间**:2026-07-05 +**范围**:RAG、检索、知识库、Agent Tool、AIOps 诊断证据链 + +--- + +## 目标 + +将当前自研 RAG MVP 重构为“成熟框架能力 + 业务可观测编排”的架构: + +```text +Agent + -> lookup_knowledge Tool + -> L0 domain/entity hint + -> query augmentation / transformer + -> Spring AI Retriever / VectorStore + -> metadata filter + -> document postprocess + -> neighbor / section expansion + -> evidence packing + -> tool_invocation record +``` + +核心原则: + +1. 通用 RAG 基础设施尽量交给 Spring AI / Spring AI Alibaba。 +2. Agent 工具入口、AIOps 业务语义、证据追踪继续保留在项目内。 +3. 不把系统改成隐式 Chat RAG,仍然保留显式 `lookup_knowledge` 工具调用。 +4. 分阶段迁移,避免一次性推倒当前可运行链路。 + +--- + +## 当前问题汇总 + +当前 RAG 已经打通上传、切片、向量化、L0/L1 召回和工具调用记录,但主要问题集中在: + +1. **检索基础设施偏自研** + - Milvus 写入和查询直接使用 SDK。 + - topK、threshold、metadata filter、结果结构由业务代码维护。 + - 后续接入 Spring AI RAG 能力会有重复适配成本。 + +2. **L0 职责过重** + - 当前 L0 可能被当成最终召回决策。 + - 关键词质量不稳定时容易误召回。 + - 更适合作为 domain/entity hint,而不是最终答案来源。 + +3. **query 构造不稳定** + - 主要依赖 Agent 传入原始 query。 + - AIOps payload 中的 alertName、service、metric、symptom 没有稳定进入检索 query。 + +4. **上下文重建不足** + - 同章节被切成多个 chunk 后,命中片段不会自动扩展前后文。 + - `breadcrumb` 存在 metadata 中,但没有充分参与 embedding、filter 或 context packing。 + +5. **缺少检索后处理** + - 缺少统一 evidence block。 + - 缺少去重、token budget、hitReason、source 结构化输出。 + +6. **缺少量化评测** + - 目前主要靠接口回放、日志和 `tool_invocation` 人工判断。 + - 还没有 golden query set、Recall@K、MRR、NDCG 等检索评测。 + +--- + +## 保留设计 + +这些设计值得保留,并作为重构后的项目亮点: + +### 1. `lookup_knowledge` 显式 Agent Tool + +保留显式工具调用,不直接用隐式 Advisor 取代。 + +原因: + +- 面试项目重点是 Agent 工程,不是普通 Chat RAG。 +- 显式工具调用能展示 Agent 何时检索、检索了什么、证据如何支撑诊断。 +- `tool_invocation`、evidence score、diagnosis session 都依赖这条链路。 + +### 2. L0 + +保留 L0,但降级为: + +- domain detector +- entity extractor +- metadata filter generator +- explainability signal + +不再默认执行: + +```text +L0 unique hit -> 直接返回 +``` + +目标职责: + +```text +query / payload + -> L0 matched keywords/entities/domain + -> metadata filter + query augmentation + -> retriever +``` + +### 3. metadata + +保留并加强 metadata: + +```text +docId +chunkIndex +totalChunks +title +breadcrumb +category +source +``` + +后续可扩展: + +```text +sectionId +parentSection +documentType +domain +tags +version +``` + +metadata 是 filter、上下文扩展、证据追踪、可解释性的基础。 + +### 4. Markdown-aware chunking + +保留当前 Markdown 结构化切片思路: + +- 识别标题层级 +- 生成 `title` +- 生成 `breadcrumb` +- 保留 `chunkIndex` +- 尽量不打断列表和代码块 + +可以替换或复用框架能力的是底层 token 长度控制和 overlap 策略,而不是完全抛弃结构化切片。 + +### 5. `tool_invocation` 证据追踪 + +保留并增强: + +```text +sessionId +query +rewrittenQuery +matchedKeywords +domain/entities +retrievedDocs +scores +hitReasons +evidence +duration +relevanceLevel +``` + +这是后续检索评测、诊断质量评估、面试讲解的基础。 + +### 6. AIOps payload 到 query 的业务映射 + +保留 AIOps 场景逻辑: + +- alertName +- service +- metric +- symptom +- category/domain + +这些是业务语义,不能完全交给通用框架隐式处理。 + +--- + +## 替换设计 + +这些能力适合逐步交给 Spring AI / Spring AI Alibaba: + +| 当前能力 | 目标能力 | 说明 | +|---|---|---| +| Milvus SDK 直接写入/查询 | Spring AI `VectorStore` | 减少基础设施代码 | +| 自研 `VectorSearchService` 检索细节 | `VectorStoreDocumentRetriever` | 标准化 topK、threshold、filter | +| 手写 query 拼接 | Query Transformer / 模板化 query augmentation | 先规则化,后框架化 | +| 手写结果拼接 | DocumentPostProcessor / evidence postprocess | 做去重、压缩、证据块 | +| L0 最终召回判断 | L0 domain/entity hint | 降低误召回风险 | + +--- + +## 分阶段计划 + +### Phase 0:重构前基线 + +目标:先固定当前行为,避免重构后不知道是否变好。 + +任务: + +- 固化 10-20 条 golden queries。 +- 覆盖 Chat 和 AIOps 场景。 +- 每条 query 标注 expected doc、breadcrumb、关键 chunk 或 evidence。 +- 用当前链路跑一遍,记录 baseline。 + +验收: + +- 有可重复运行的检索回放清单。 +- 能记录当前 Recall@K、first hit rank 或人工 hit level。 + +### Phase 1:L0 降级为 domain/entity hint + +目标:保留 L0 价值,降低 L0 误决策风险。 + +任务: + +- `KnowledgeIndexService` 输出 matched keywords、domain、entities。 +- `LookupKnowledgeTool` 不再把 L0 unique hit 作为默认最终结果。 +- 将 L0 结果用于 query augmentation 和 metadata filter。 +- `tool_invocation` 记录 L0 hit reason。 + +验收: + +- L0 命中不会绕过向量检索直接返回。 +- 检索记录能看到 domain/entities/matchedKeywords。 +- AIOps payload 能生成稳定领域 hint。 + +### Phase 2:Evidence Postprocess 和上下文打包 + +目标:先提升 Agent 实际拿到的证据质量。 + +任务: + +- 定义 evidence block: + +```text +source +docId +chunkIndex +title +breadcrumb +score +hitReason +content +expandedFrom +``` + +- 对检索结果做去重。 +- 支持命中 chunk 的相邻 chunk / 同章节扩展。 +- 加 token 或字符预算控制。 +- 返回给 Agent 的内容按 evidence block 组织。 + +验收: + +- 同一 docId/chunkIndex 不重复进入上下文。 +- 命中 chunk 可以补充前后文。 +- `tool_invocation` 记录 postprocess 前后候选数量和最终 evidence 数量。 + +### Phase 3:Spring AI VectorStore 旁路验证 + +目标:验证框架能力,不直接替换主链路。 + +任务: + +- 引入 Spring AI Milvus VectorStore。 +- 建立旁路 `SpringAiVectorSearchService` 或适配层。 +- 同一批 golden queries 同时跑旧链路和新链路。 +- 对比 topK、metadata、score、filter 行为。 + +验收: + +- 旁路检索可跑通。 +- metadata 不丢失。 +- 查询结果与当前链路差异可解释。 +- 不影响现有 Chat / AIOps 主链路。 + +### Phase 4:替换底层 VectorSearchService + +目标:对外接口不变,内部检索切到 Spring AI VectorStore / Retriever。 + +任务: + +- 保持 `LookupKnowledgeTool` 调用方式不变。 +- `VectorSearchService` 内部迁移到 Spring AI 检索抽象。 +- 支持 topK、similarity threshold、category metadata filter。 +- 保留旧实现一段时间作为 fallback。 + +验收: + +- Chat / AIOps 检索链路行为兼容。 +- golden queries 不低于 baseline。 +- 检索结果仍能完整记录到 `tool_invocation`。 + +### Phase 5:Query Transformer 和框架化 PostProcessor + +目标:在稳定的 VectorStore 基础上接入更成熟 RAG 能力。 + +任务: + +- AIOps 场景优先使用模板化 query augmentation。 +- 需要时接入 Spring AI Query Transformer / MultiQuery。 +- 将现有 evidence postprocess 抽象成 DocumentPostProcessor 风格。 +- 可选接入 rerank,但不作为第一优先级。 + +验收: + +- 原始 query 和 rewritten query 都可追踪。 +- query rewrite 失败可以 fallback。 +- postprocess 行为可配置、可记录、可回放。 + +--- + +## 暂不做 + +以下能力暂不进入近期重构: + +1. 不做完整自研 RRF 框架。 +2. 不直接把 `lookup_knowledge` 替换成隐式 Advisor。 +3. 不一口气迁移所有 RAG ETL。 +4. 不先引入 Elasticsearch / OpenSearch,除非评测证明 BM25 必须。 +5. 不先上 cross-encoder / LLM rerank,先做规则型 evidence postprocess。 + +--- + +## 风险 + +### 1. Milvus schema 兼容风险 + +当前 collection 是项目自建,Spring AI VectorStore 可能有自己的 schema 假设。需要旁路验证。 + +### 2. 检索行为变化风险 + +框架检索分数和当前 L2 score 可能不完全一致,需要 golden queries 对比。 + +### 3. 可观测性丢失风险 + +如果迁移到隐式 Advisor,可能丢失工具调用证据链。因此 Spring AI RAG 能力应优先封装在 `lookup_knowledge` 内部。 + +### 4. 重构范围膨胀风险 + +RAG、Agent、AIOps、数据库记录互相关联,必须分阶段推进,每阶段都保持可运行。 + +--- + +## 合并来源 + +本计划合并以下问题和改造方向: + +- [rag-chunk-context-reconstruction.md](rag-chunk-context-reconstruction.md) +- [rag-breadcrumb-embedding-gap.md](rag-breadcrumb-embedding-gap.md) +- [rag-l0-l1-fusion-ranking.md](rag-l0-l1-fusion-ranking.md) +- [rag-l0-keyword-matching-quality.md](rag-l0-keyword-matching-quality.md) +- [rag-l1-score-calibration.md](rag-l1-score-calibration.md) +- [rag-context-packing-and-reranking.md](rag-context-packing-and-reranking.md) +- [rag-upload-chunk-parameter-drift.md](rag-upload-chunk-parameter-drift.md) +- [rag-query-rewrite-gap.md](rag-query-rewrite-gap.md) +- [rag-spring-ai-vectorstore-migration.md](rag-spring-ai-vectorstore-migration.md) +- [rag-spring-ai-query-transformer.md](rag-spring-ai-query-transformer.md) +- [rag-spring-ai-document-postprocessor.md](rag-spring-ai-document-postprocessor.md) +- [rag-l0-domain-entity-hint.md](rag-l0-domain-entity-hint.md) +- [rag-spring-ai-advisor-boundary.md](rag-spring-ai-advisor-boundary.md) + +--- + +## 相关文件 + +- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java` +- `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/VectorIndexService.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/AiOpsService.java` +- `src/main/java/com/superbiz/agent/service/ToolInvocationRecorder.java` +- `src/main/resources/application.yml` +- `pom.xml` diff --git a/mvp/issues/rag-spring-ai-advisor-boundary.md b/mvp/issues/rag-spring-ai-advisor-boundary.md new file mode 100644 index 0000000..9187991 --- /dev/null +++ b/mvp/issues/rag-spring-ai-advisor-boundary.md @@ -0,0 +1,66 @@ +# RAG 明确 Spring AI Advisor 与 Agent Tool 的边界 + +**状态**:待规划 +**严重程度**:中 +**发现时间**:2026-07-05 +**范围**:Agent 编排、RAG Advisor、工具调用可观测性 + +--- + +## 背景 + +Spring AI 提供 `QuestionAnswerAdvisor`、`RetrievalAugmentationAdvisor` 等 RAG Advisor 能力,可以把检索增强直接挂到模型调用流程中。 + +但当前项目是 Agent 工程项目,知识检索不是普通聊天增强,而是 Agent 在诊断流程中显式调用的工具。系统还依赖 `tool_invocation` 记录检索事实,用于 evidence score 和诊断追踪。 + +--- + +## 问题 + +如果直接把 RAG 全部迁到 Advisor,可能会损失当前项目已有的显式工具链路: + +1. Agent 是否调用知识库不够透明。 +2. `tool_invocation` 记录可能变弱。 +3. AIOps 诊断步骤和知识证据之间的对应关系不清晰。 +4. 面试项目中“Agent 如何使用工具”的展示价值下降。 + +--- + +## 改造方向 + +不要把 `lookup_knowledge` 完全替换成隐式 Advisor,而是分层使用: + +```text +Agent Tool 层: + lookup_knowledge + sessionId + traceId + tool_invocation + evidence score + +Spring AI RAG 层: + query transformer + retriever + vector store + document post processor +``` + +也就是说,Advisor / Retriever 可以作为工具内部实现,而不是取代工具本身。 + +--- + +## 验收标准 + +- Agent 仍然通过显式 `lookup_knowledge` 使用知识库。 +- Spring AI RAG 能力被封装在工具内部或服务内部。 +- 每次检索仍能落 `tool_invocation`。 +- Chat / AIOps 两条链路都能追踪检索输入、输出和证据来源。 + +--- + +## 相关文件 + +- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java` +- `src/main/java/com/superbiz/agent/service/ChatService.java` +- `src/main/java/com/superbiz/agent/service/AiOpsService.java` +- `src/main/java/com/superbiz/agent/service/ToolInvocationRecorder.java` diff --git a/mvp/issues/rag-spring-ai-document-postprocessor.md b/mvp/issues/rag-spring-ai-document-postprocessor.md new file mode 100644 index 0000000..c635b21 --- /dev/null +++ b/mvp/issues/rag-spring-ai-document-postprocessor.md @@ -0,0 +1,60 @@ +# RAG 使用 DocumentPostProcessor 做后处理 + +**状态**:待规划 +**严重程度**:中 +**发现时间**:2026-07-05 +**范围**:检索后处理、去重、上下文打包、轻量 rerank + +--- + +## 背景 + +当前检索结果返回给 Agent 前,主要依赖 `LookupKnowledgeTool` 自己拼接内容。系统还缺少统一的后处理阶段。 + +Spring AI RAG 流程中可以使用 DocumentPostProcessor 类能力,在文档进入模型上下文前做过滤、去重、压缩或 rerank。 + +--- + +## 问题 + +当前检索后处理不足: + +1. L1 topK 候选没有被充分利用。 +2. 同文档或同章节结果可能重复。 +3. 命中 chunk 后没有统一处理前后文扩展。 +4. 证据块缺少统一格式,后续 verifier / evaluator 不容易复用。 + +--- + +## 改造方向 + +建立一个轻量后处理链: + +```text +retrieved documents + -> deduplicate + -> optional neighbor / section expansion + -> score / reason annotation + -> token budget packing + -> evidence blocks +``` + +优先做规则型后处理,不急于引入 cross-encoder 或 LLM rerank。 + +--- + +## 验收标准 + +- 同一个 docId/chunkIndex 不重复进入 Agent 上下文。 +- 最终返回内容包含 source、title、breadcrumb、score、hitReason。 +- 可以限制单次工具调用返回的最大 token 或最大字符数。 +- 后处理前后的候选数量、去重数量、最终 evidence 数量记录到 `tool_invocation`。 + +--- + +## 相关文件 + +- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.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/ToolInvocationRecorder.java` diff --git a/mvp/issues/rag-spring-ai-query-transformer.md b/mvp/issues/rag-spring-ai-query-transformer.md new file mode 100644 index 0000000..21a81b9 --- /dev/null +++ b/mvp/issues/rag-spring-ai-query-transformer.md @@ -0,0 +1,70 @@ +# RAG 接入 Spring AI Query Transformer + +**状态**:待规划 +**严重程度**:中 +**发现时间**:2026-07-05 +**范围**:查询改写、多查询扩展、AIOps 检索稳定性 + +--- + +## 背景 + +当前 `lookup_knowledge` 主要使用 Agent 传入的原始 query 进行 L0/L1 检索。query 的质量高度依赖 Agent 当次生成结果。 + +Spring AI 提供 Query Transformer / Query Expander 类能力,可以把用户问题或 Agent 子任务改写成更适合检索的查询。 + +--- + +## 问题 + +当前检索 query 存在几个风险: + +1. 用户问题口语化时,缺少领域关键词。 +2. AIOps payload 中的 alertName、service、metric 没有稳定拼入检索 query。 +3. 同义表达没有扩展,例如“连接耗尽”和“连接池打满”。 +4. 工具层无法复用框架提供的 rewrite / expansion 能力。 + +--- + +## 改造方向 + +在 `lookup_knowledge` 前增加查询改写层: + +```text +raw query / alert payload + -> query transformer + -> rewritten query / expanded queries + -> retriever +``` + +优先支持两类场景: + +1. **AIOps 模板化改写** + - alertName + - service + - metric + - symptom + - domain/category + +2. **Spring AI Query Transformer** + - rewrite 原始 query + - multi-query expansion + - 必要时做 query compression + +--- + +## 验收标准 + +- `tool_invocation` 中记录原始 query 和改写后的 query。 +- AIOps payload 存在时,检索 query 能稳定带上告警和服务上下文。 +- 对同一个测试问题,改写前后 topK 命中结果可对比。 +- 未配置 transformer 时,可以回退到原始 query。 + +--- + +## 相关文件 + +- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java` +- `src/main/java/com/superbiz/agent/service/AiOpsService.java` +- `src/main/java/com/superbiz/agent/service/VectorSearchService.java` +- `src/main/java/com/superbiz/agent/domain/entity/ToolInvocation.java` diff --git a/mvp/issues/rag-spring-ai-vectorstore-migration.md b/mvp/issues/rag-spring-ai-vectorstore-migration.md new file mode 100644 index 0000000..b7f38b5 --- /dev/null +++ b/mvp/issues/rag-spring-ai-vectorstore-migration.md @@ -0,0 +1,80 @@ +# RAG 迁移到 Spring AI VectorStore 检索抽象 + +**状态**:待规划 +**严重程度**:高 +**发现时间**:2026-07-05 +**范围**:向量检索、Milvus 接入、RAG 框架化改造 + +--- + +## 背景 + +当前系统的向量检索链路主要由项目手写实现: + +- `VectorIndexService` 负责向量化和写入 Milvus。 +- `VectorSearchService` 直接使用 Milvus SDK 查询。 +- `LookupKnowledgeTool` 自己组织 L0/L1 检索结果。 + +这能满足 MVP 打通链路,但继续扩展 RAG 能力时,容易把项目变成自研搜索框架。 + +项目当前已引入 Spring AI / Spring AI Alibaba 依赖,可以考虑迁移到 Spring AI 的 `VectorStore`、`VectorStoreDocumentRetriever` 等标准抽象。 + +--- + +## 问题 + +当前手写 Milvus 检索存在几个成本: + +1. topK、similarity threshold、metadata filter 等逻辑分散在业务代码中。 +2. 检索结果结构和 Spring AI RAG Advisor 生态不兼容。 +3. 后续接入 query transformer、post processor、advisor 时需要重复适配。 +4. Milvus SDK 直接调用让业务层承担了过多基础设施细节。 + +--- + +## 改造方向 + +优先引入 Spring AI 的 Milvus VectorStore 能力: + +```text +当前: +VectorSearchService -> Milvus SDK + +目标: +LookupKnowledgeTool / RAG Service + -> VectorStoreDocumentRetriever + -> Spring AI VectorStore + -> Milvus +``` + +业务层保留: + +- `lookup_knowledge` 工具入口 +- `tool_invocation` 记录 +- sessionId / category / domain 等业务上下文 + +底层检索交给框架: + +- topK +- similarity threshold +- metadata filter +- vector search options + +--- + +## 验收标准 + +- `VectorSearchService` 不再直接散落 Milvus 查询细节,至少封装到 Spring AI `VectorStore` 适配层。 +- 支持按 `category` 或其他 metadata filter 检索。 +- 检索结果仍能记录到 `tool_invocation`。 +- 现有 AIOps / Chat 检索链路行为保持兼容。 + +--- + +## 相关文件 + +- `pom.xml` +- `src/main/java/com/superbiz/agent/service/VectorSearchService.java` +- `src/main/java/com/superbiz/agent/service/VectorIndexService.java` +- `src/main/java/com/superbiz/agent/tool/LookupKnowledgeTool.java` +- `src/main/resources/application.yml` diff --git a/mvp/issues/rag-upload-chunk-parameter-drift.md b/mvp/issues/rag-upload-chunk-parameter-drift.md new file mode 100644 index 0000000..062c068 --- /dev/null +++ b/mvp/issues/rag-upload-chunk-parameter-drift.md @@ -0,0 +1,49 @@ +# RAG 上传切片参数未真正生效 + +**状态**:待规划 +**严重程度**:低 +**发现时间**:2026-07-04 +**范围**:文档上传接口、切片配置、API 行为一致性 + +--- + +## 现象 + +上传接口暴露了 `chunkSize` 和 `chunkOverlap` 参数,但实际切片主要使用全局 `DocumentChunkConfig`。这会造成 API 表面能力和真实行为不一致。 + +--- + +## 当前实现 + +- `DocumentController` 的上传接口接收 `chunkSize` 和 `chunkOverlap`。 +- 这些字段会进入 `DocumentUploadRequest`。 +- `DocumentChunkService` 的切片阈值主要来自 `DocumentChunkConfig`。 +- 单次上传请求中的参数没有真正覆盖切片配置。 + +--- + +## 影响 + +- 调用方以为可以控制切片大小,但实际无法影响结果。 +- 测试时容易误判“参数调优无效”的原因。 +- 面试中如果展示 API,会被追问参数是否真实生效。 + +--- + +## 建议修复 + +两个方向二选一: + +1. 如果 MVP 不需要请求级切片参数,就从接口中移除或标记为暂不支持。 +2. 如果需要支持,就让 `DocumentChunkService` 接收 per-request chunk options,并记录到文档 metadata 中。 + +建议面试项目中优先选择第二种,因为它更能体现工程闭环:API、配置、落库、追踪一致。 + +--- + +## 相关文件 + +- `src/main/java/com/superbiz/agent/controller/DocumentController.java` +- `src/main/java/com/superbiz/agent/service/DocumentManagementService.java` +- `src/main/java/com/superbiz/agent/service/DocumentChunkService.java` +- `src/main/java/com/superbiz/agent/config/DocumentChunkConfig.java`