Files
SuperBizAgent-java/interview/archive/2026-07-24-legacy/rag-refactor-story.md
T
zhuyongxin de5a5b09d9 docs(interview): refresh materials for single-agent harness narrative
Archive pre-refactor interview notes and add current deep-dives on
architecture evolution, issue-derived stories, and evidence gates.
2026-07-24 18:14:49 +08:00

128 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# RAG 重构故事
## 1. 起点
原始 RAG 实现已经能支撑 MVP:
- 文档可以上传、切片、向量化,并写入 Milvus/Zilliz。
- Agent 可以显式调用 `lookup_knowledge`。
- AIOps 诊断能在告警流程里检索排障知识。
- 工具调用会落到 `tool_invocation`,检索步骤可见。
但它有几个工程问题:
- 检索实现过于依赖 Milvus SDK,业务代码承担了太多底层搜索细节。
- L0 和 L1 职责不清,L0 关键词命中容易被当作最终召回决策。
- chunk 级检索容易丢失章节上下文。
- `breadcrumb` 存在 metadata 中,但没有充分参与 embedding、filter 和上下文重建。
- 检索质量主要靠手工接口和日志判断,缺少可重复的 golden cases。
所以重构目标不是“全盘替换成框架”,而是:
```text
通用 RAG 基础设施交给 Spring AI,
业务可观测链路保留在项目里。
```
## 2. 我如何拆解问题
我把迁移拆成几个阶段,因为 RAG 同时影响 Agent 工具层、AIOps、向量检索、证据打包和 Trace。
第一步是建立 baseline。`eval/rag-retrieval/` 中的 golden cases 用来对比后续改动,而不是只靠直觉判断检索有没有变好。
第二步是明确职责:
```text
L0 = domain/entity hint
L1 = semantic retrieval
postprocess = evidence shaping + trace-friendly output
```
L0 仍然有价值,但不再默认绕过语义检索。它更适合提取服务名、告警名、错误码、领域和 metadata filter。
第三步是增强 evidence 输出。Agent 不应该只拿到 raw chunk,而应该拿到带 source、title、breadcrumb、score、hit reason 的证据块。
最后,我把 Spring AI `VectorStore` 接入为读取主路径,同时保留原 Milvus SDK 作为 fallback。
## 3. 当前架构
```text
Agent / API
-> lookup_knowledge or /api/search/similar
-> L0 domain/entity hint
-> VectorSearchService
-> Spring AI VectorStore
-> Milvus SDK fallback
-> relevance normalization
-> tool_invocation trace
```
`VectorSearchService` 仍然是公共检索门面。Agent 工具层不需要知道底层是 SDK 还是 Spring AI。
支持三种模式:
```text
auto -> 优先 Spring AI VectorStore,失败后 fallback 到 SDK
spring-ai -> 强制 Spring AI VectorStore
sdk -> 强制 Milvus SDK
```
## 4. 关键取舍
### 保留显式工具
我没有把检索藏进 Spring AI Advisor。原因是这个项目强调 Agent 执行可见性:`lookup_knowledge` 的 query、命中文档、相关性和证据预览都要进入 Trace。
### 保留 SDK fallback
SDK fallback 不是废代码,而是迁移安全网。实际验证时,第一次 VectorStore 指向了错误 collection,`auto` 模式 fallback 到 SDK 后仍能返回结果。修正 collection 后,Spring AI 路径成为主路径。
### L0 降权
生产事故中经常有精确标识:错误码、告警名、服务名、指标名。L0 适合做 hint,但不应该做最终裁判。
### 分数语义拆开
SDK 使用 L2 distance,Spring AI 暴露 similarity。混在一个字段里会让 relevance normalization 出错。
当前拆成:
```text
score -> 兼容旧逻辑的距离型分数
rawScore -> 底层原始分数
scoreLabel -> rawScore 的语义
```
### 暂不迁移写入
写入和索引仍走 SDK。这是有意分阶段:先验证读路径,再评估 `VectorStore.add(...)` 是否适合现有 metadata 和 chunk 模型。
## 5. 验证方式
我用了三层验证:
- 单元测试:SDK mode、Spring AI mode、auto fallback、category filter、distance metadata mapping。
- Live API:`GET /api/search/similar?query=ERR_TIMEOUT&topK=3`。
- 代表性 query 对比:错误码、支付超时、MySQL 连接池、AIOps 告警式 query、抽象 RAG 设计问题。
核心排障和 AIOps query 在 SDK 与 VectorStore 下 top3 一致。差异主要集中在抽象设计类问题和 metadata taxonomy,这些被记录为后续质量工作。
## 6. 面试短版
```text
这个 RAG 系统最初是基于 Milvus SDK 的自研 MVP。它能跑,但底层检索细节过多地散落在业务代码里,L0/L1 职责也不够清晰。
我按阶段重构:先加 retrieval baseline,再把 L0 降级为 domain/entity hint,再增强 evidence postprocess,最后把读取主路径切到 Spring AI VectorStore,并保留 SDK fallback。
我没有把 lookup_knowledge 替换成隐式 Advisor,因为这个项目的核心是可追踪 Agent:面试官可以看到什么时候检索、检索了什么、证据如何支撑诊断。
```
## 7. 可主动承认的不足
- metadata taxonomy 还需要清理,例如 `database` 与 `infrastructure`。
- 抽象设计问题可能需要 query rewrite 或更好的文档索引。
- 邻居 chunk / 同章节上下文扩展还不完整。
- rerank、RRF、BM25、hybrid retrieval 还没有接入。
- 写入路径仍使用 SDK。
这些不是当前迁移阻塞项,而是后续检索质量优化方向。