4.9 KiB
RAG 重构故事
1. 起点
原始 RAG 实现已经能支撑 MVP:
- 文档可以上传、切片、向量化,并写入 Milvus/Zilliz。
- Agent 可以显式调用
lookup_knowledge。 - AIOps 诊断能在告警流程里检索排障知识。
- 工具调用会落到
tool_invocation,检索步骤可见。
但它有几个工程问题:
- 检索实现过于依赖 Milvus SDK,业务代码承担了太多底层搜索细节。
- L0 和 L1 职责不清,L0 关键词命中容易被当作最终召回决策。
- chunk 级检索容易丢失章节上下文。
breadcrumb存在 metadata 中,但没有充分参与 embedding、filter 和上下文重建。- 检索质量主要靠手工接口和日志判断,缺少可重复的 golden cases。
所以重构目标不是“全盘替换成框架”,而是:
通用 RAG 基础设施交给 Spring AI,
业务可观测链路保留在项目里。
2. 我如何拆解问题
我把迁移拆成几个阶段,因为 RAG 同时影响 Agent 工具层、AIOps、向量检索、证据打包和 Trace。
第一步是建立 baseline。eval/rag-retrieval/ 中的 golden cases 用来对比后续改动,而不是只靠直觉判断检索有没有变好。
第二步是明确职责:
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. 当前架构
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。
支持三种模式:
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 出错。
当前拆成:
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. 面试短版
这个 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。
这些不是当前迁移阻塞项,而是后续检索质量优化方向。