refactor(harness): remove legacy agent architecture

This commit is contained in:
zhuyongxin
2026-07-22 18:02:01 +08:00
parent bc36248cd8
commit 8ee7cc0b70
148 changed files with 3091 additions and 13889 deletions
@@ -0,0 +1,415 @@
# RAG 新架构
**更新日期**:2026-07-06
**状态**:当前主架构 + 后续演进边界
**关联计划**:[`mvp/issues/active/rag-refactor-plan.md`](../issues/active/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` |