This commit is contained in:
aruo
2026-05-31 21:45:14 +08:00
parent d4b5015beb
commit ac08345369
67 changed files with 11120 additions and 387 deletions
+108
View File
@@ -0,0 +1,108 @@
# Handoff: ChatModel + Embedding 解耦 (chatmodel-abstraction)
**日期**: 2026-05-30
**分支**: `refactor/rag-chunking-strategy`
**状态**: ✅ 实现完成,测试通过,文档已回填
---
## 做了什么
将项目从 DashScope 硬编码解耦为 Spring AI 抽象接口,支持跨厂商模型切换。
### 代码改动 (9 tasks)
| Task | 文件 | 改动 |
|---|---|---|
| T1 | `MilvusProperties.java` + `application.yml` | `vectorDim` 字段 + `milvus.vector-dim` 配置 |
| T2 | `MilvusClientFactory.java` | `VECTOR_DIM` 常量 → `milvusProperties.getVectorDim()` |
| T3 | `ChatService.java` | 删除工厂方法,`@Autowired ChatModel` |
| T4 | `ChatController.java` | 删除 3 处 DashScope 手动构建 |
| T5 | `AiOpsService.java` | `DashScopeChatModel` → `ChatModel` |
| T6 | `VectorEmbeddingService.java` | DashScope SDK → `EmbeddingModel.embed()` |
| T7 | `RagService.java` | `Generation` + `Flowable` → `ChatModel.stream()` + `Flux` |
| T8 | `ModelRoutingConfig.java` (新增) | `@Primary` 集中路由,`List<T>` 自检 Bean |
| T9 | `SiliconFlowEmbeddingConfig.java` (新增) | `OpenAiApi` → SiliconFlow, BGE-M3 1024维 |
| — | `pom.xml` | `spring-ai-starter-model-deepseek` + `spring-ai-starter-model-openai`,移除 DashScope/Ollama |
| — | `application.yml` | DeepSeek 原生配置 + SiliconFlow embedding |
| — | `MilvusClientFactory.java` | 启动时 `loadCollection()` |
### 新增文件
- `src/main/java/org/example/config/ModelRoutingConfig.java`
- `src/main/java/org/example/config/SiliconFlowEmbeddingConfig.java`
- `src/test/java/org/example/service/ChatAndEmbeddingSmokeTest.java`
- `src/test/java/org/example/service/FullPipelineSmokeTest.java`
## 当前架构
| 层 | 厂商 | 实现 | Bean 名 |
|---|---|---|---|
| Chat | DeepSeek V4 Flash | `DeepSeekChatModel` (Spring AI 原生) | `deepSeekChatModel` |
| Embedding | SiliconFlow BGE-M3 | `OpenAiEmbeddingModel` (OpenAI 兼容) | `siliconFlowEmbeddingModel` |
| 向量存储 | Milvus (Zilliz Cloud) | `MilvusServiceClient` | — |
| 路由 | — | `ModelRoutingConfig` | `chatModel` + `embeddingModel` @Primary |
## 测试结果
```
ChatAndEmbeddingSmokeTest: 5/5 ✅
FullPipelineSmokeTest: 5/5 ✅ (Chat + Embedding + Milvus 全链路)
mvn spring-boot:run : ✅ 4.5s 启动, 端口 9900
```
### 启动条件
- DeepSeek / SiliconFlow API Key 已配在 yml
- Milvus Zilliz Cloud 已配置
- MCP 禁用、Prometheus+CLS Mock 模式
- `ToolCallbackProvider` 改为 `@Autowired(required = false)` + null 兜底
运行测试前需要:
- DeepSeek API Key 在 yml 中配置(`spring.ai.deepseek.api-key`)
- SiliconFlow API Key 在 yml 中配置(`siliconflow.api-key`)
- Milvus 连接已配置(Zilliz Cloud token 在 yml 中)
- MCP 客户端已禁用(`spring.ai.mcp.client.enabled: false`)
- 测试中 ToolCallbackProvider 由 mock 提供
## 关键经验教训
详见 `devflow/projects/2026-05-29-chatmodel-abstraction/decisions.md`:
1. **Spring AI version → 模型兼容性**: 1.1.0 的 OpenAI 兼容模式不兼容 DeepSeek V4(2026年4月发布),升级到 1.1.7 + 原生 DeepSeekChatModel 才解决
2. **`@Qualifier` Bean 名不要猜**: 用 `List<T>` 自检 + 类名筛选比硬编码更稳
3. **base-url 不要带 `/v1`**: Spring AI 自动追加版本路径,会导致双重
4. **多 starter 并存需要 `@Primary`**: ModelRoutingConfig 集中路由
5. **`EmbeddingModel.embed()` 返回 `float[]`**: 不是 `List<Double>`
## 问题备忘
| 问题 | 状态 |
|---|---|
| DashScope SDK 全部清除 | ✅ |
| DeepSeek V4 兼容性 | ✅ 用原生 starter 解决 |
| SiliconFlow 404 | ✅ base-url 修复 |
| Milvus collection not loaded | ✅ 加 loadCollection() |
| MCP ToolCallbackProvider 缺失 | ✅ 测试中 mock |
## 有效文档
- OpenSpec: `openspec/changes/chatmodel-abstraction/` (proposal/design/specs/tasks)
- devflow: `devflow/projects/2026-05-29-chatmodel-abstraction/decisions.md`
- 词汇表: `devflow/glossary/CONTEXT.md`
- 索引: `devflow/index.md`
- 项目 rules: `CLAUDE.md`, `AGENTS.md`
## Suggested Skills
下一个 agent 应加载:
- **sm-flow**: 如需继续推进(archive 归档、新需求变更)
- **openspec-apply-change**: 如需实现额外 task
- **openspec-archive-change**: 如需归档 OpenSpec change
- **gitnexus**: 如需分析影响范围、pre-commit 检查
## 可能的后续工作
1. 运行 `npx openspec` 归档当前 change(archive 阶段)
2. 真实 Milvus 数据灌入验证(当前 collection 为空)
3. RagService SSE 端到端测试(需要启动应用)
4. Ollama 本地 embedding 替代(如果 SiliconFlow 不可用)
5. MCP 客户端重新启用 + 真实腾讯云日志查询验证
+490
View File
@@ -0,0 +1,490 @@
# Handoff Document - SuperBizAgent-java 项目分析与学习
> **Session Date**: 2026-05-30
> **Project**: SuperBizAgent-java (智能 OnCall 助手)
> **Status**: 项目分析完成,学习路径已建立
> **Next Agent**: 继续深度学习或开始功能开发
---
## 📋 Session Summary
本次会话完成了 **SuperBizAgent-java 项目的全面分析**,并建立了完整的学习体系。用户从零开始了解项目,现在已经掌握了核心架构和关键设计模式。
---
## ✅ Completed Work
### 1. 项目功能分析(Playwright + 代码分析)
**成果**:
- 使用 Playwright MCP 工具分析了 `localhost:9900` 站点
- 识别出 2 大核心功能:
- **智能对话系统**:RAG 知识库检索、Prometheus 告警查询、腾讯云 CLS 日志查询
- **AI Ops 自动化分析**:3-Agent 协同的告警根因分析(⭐️ 核心特色)
**产物**:
- `docs/功能分析报告.md` - 完整的功能分析、技术栈、使用场景
**关键发现**:
- AI Ops 使用了 **3-Agent 协同模式**(Planner + Executor + Supervisor)
- 后端:Spring AI + DeepSeek V4 Flash + SiliconFlow BGE-M3 + Zilliz Cloud Milvus
- 前端:SSE 流式响应 + Markdown 渲染
---
### 2. 日志配置(解决 Claude 无法分析日志的问题)
**问题**:项目启动后日志只输出到控制台,Claude 无法读取分析
**解决方案**:
- 创建 `src/main/resources/logback-spring.xml`(完整配置)
- 修改 `src/main/resources/application.yml`(添加 logging 部分)
- 配置特性:
- 控制台 + 文件双输出
- 按模块分文件(`application.log`, `aiops.log`, `chat.log`, `application-error.log`)
- 异步写入(性能优化)
- 自动滚动(10MB/文件,保留 30 天)
**产物**:
- `docs/日志配置与分析指南.md` - 详细的配置说明、分析场景、故障排查
- `docs/日志配置完成总结.md` - 快速参考总结
- `scripts/verify-logging.sh` 和 `scripts/verify-logging.bat` - 验证脚本
**验证命令**:
```bash
bash scripts/verify-logging.sh
```
---
### 3. 项目学习路径设计
**成果**:
- 设计了 **5 阶段学习路径**(从核心执行流到配置基础设施)
- 每个阶段包含:执行流程图、具体学习步骤、阶段总结、检查点清单
- 提供了 3 种学习节奏:快速(1小时)、标准(2小时)、深度(3小时)
**产物**:
- `docs/项目学习路径.md` - 完整的分阶段学习计划
**学习阶段**:
1. **阶段 1**:核心执行流理解(AI Ops + Chat 对话流程)⭐️ 从这里开始
2. **阶段 2**:RAG 知识库链路(文档上传 → 向量化 → 检索)
3. **阶段 3**:模型抽象与路由(ChatModel/EmbeddingModel 解耦)
4. **阶段 4**:Tools 工具集(Prometheus、CLS、RAG、DateTime)
5. **阶段 5**:配置与基础设施(application.yml、Milvus)
---
### 4. AI Ops 核心设计深度分析(/essence 技能)
**分析目标**:`/api/ai_ops` 接口的 3-Agent 协同架构
**成果**:
- 识别出 **3-Agent Collaborative Analysis Pattern**(核心设计模式)
- 完整的端到端调用链追踪(HTTP → Controller → Service → 3 Agents → Tools → SSE)
- 与其他方案的对比分析(单 Agent、2-Agent、静态工作流、ReAct Loop)
- 可迁移的代码示例(≤20 行)
- 5 个关键陷阱及避免方法
**产物**:
- `docs/learning/01-AI-Ops-核心设计-Essence报告.md`
**核心洞察**:
- **Planner**:制定计划 & 重新规划(承担 Replanner 角色)
- **Executor**:执行工具调用(只执行第一步)
- **Supervisor**:循环调度(直到 decision=FINISH)
**关键机制**:
- `outputKey` - Agent 状态共享的桥梁
- Prompt 中的 `{}` 占位符自动替换为 `state.value(key)`
- 循环编排:Planner → Executor → Planner(重新规划)→ ... → FINISH
---
### 5. outputKey 机制深度解析
**背景**:用户询问 outputKey 的作用
**成果**:
- 详细解释了 outputKey 的共享内存模型
- 提供了 8 步完整时间线示例
- 回答了 3 个核心疑问:
1. Prompt 中的 `{}` 占位符如何替换?
2. 如果两个 Agent 用同一个 outputKey 会怎样?
3. 如何在 Prompt 中读取多个 key?
**产物**:
- `docs/learning/02-outputKey-深度解析.md`
- `docs/learning/03-核心疑问解答.md`
- `docs/learning/README.md` - 学习报告索引
**核心概念**:
```
OverAllState = Map<String, Object>
- Planner 写入: state["planner_plan"]
- Executor 写入: state["executor_feedback"]
- Planner 读取: {executor_feedback} → state.get("executor_feedback")
```
---
## 📁 Key Artifacts
### 已创建的文档
| 文档 | 路径 | 用途 |
|------|------|------|
| **功能分析报告** | `docs/功能分析报告.md` | 项目功能、技术栈、AI Ops 案例 |
| **日志配置指南** | `docs/日志配置与分析指南.md` | 日志配置、分析场景、故障排查 |
| **日志配置总结** | `docs/日志配置完成总结.md` | 快速参考、调试技巧 |
| **项目学习路径** | `docs/项目学习路径.md` | 5 阶段学习计划 |
| **Essence 报告** | `docs/learning/01-AI-Ops-核心设计-Essence报告.md` | 3-Agent 协同架构深度分析 |
| **outputKey 解析** | `docs/learning/02-outputKey-深度解析.md` | 状态共享机制详解 |
| **疑问解答** | `docs/learning/03-核心疑问解答.md` | 3 个核心疑问的深度回答 |
| **学习索引** | `docs/learning/README.md` | 学习路径索引、检查点清单 |
### 已修改的配置
| 文件 | 修改内容 |
|------|---------|
| `src/main/resources/logback-spring.xml` | 新增完整日志配置(分模块、异步、滚动) |
| `src/main/resources/application.yml` | 新增 logging 配置段 |
### 核心源码文件(分析重点)
| 文件 | 关键行 | 作用 |
|------|--------|------|
| `ChatController.java` | 280-314 | `/api/ai_ops` HTTP 入口 + SSE 流式返回 |
| `AiOpsService.java` | 51-70 | 3-Agent 构建与编排核心逻辑 |
| `AiOpsService.java` | 100-124 | Planner & Executor Agent 构建 |
| `AiOpsService.java` | 144-257 | Agent Prompts(Planner、Executor、Supervisor) |
| `AiOpsService.java` | 79-94 | 最终报告提取逻辑 |
---
## 🎯 Current State
### 用户理解程度
**已掌握**:
- ✅ 项目整体功能和技术架构
- ✅ AI Ops 3-Agent 协同模式的工作原理
- ✅ outputKey 状态共享机制
- ✅ 完整的调用链(HTTP → Agents → Tools → SSE)
- ✅ 日志配置和分析方法
**待深入**(基于学习路径):
- ⏳ 阶段 2:RAG 知识库链路(文档分块、向量化、检索)
- ⏳ 阶段 3:模型路由机制(ModelRoutingConfig、SiliconFlowEmbeddingConfig)
- ⏳ 阶段 4:Tools 工具集(QueryMetricsTools、QueryLogsTools 的实现细节)
- ⏳ 阶段 5:配置与基础设施(Milvus 连接、向量维度配置)
### 项目状态
- **GitNexus 索引**:已更新(1528 符号,2828 关系,87 执行流)
- **日志配置**:已完成,项目启动后会自动输出到 `logs/` 目录
- **学习体系**:已建立,文档齐全
---
## 🚀 Suggested Next Steps
### 选项 1:继续学习项目(推荐)
**按照学习路径继续**:
1. **阶段 2:RAG 知识库链路**(20 分钟)
```bash
# 第一个命令
Read src/main/java/org/example/service/RagService.java
```
- 理解文档分块策略(ChunkingStrategy)
- 掌握向量化流程(VectorEmbeddingService)
- 了解 Milvus 检索机制
2. **阶段 3:模型路由机制**(15 分钟)
```bash
Read src/main/java/org/example/config/ModelRoutingConfig.java
```
- 理解 yml 驱动的模型路由
- 掌握 ChatModel/EmbeddingModel 解耦设计
- 了解如何切换模型(只改配置不改代码)
3. **实践验证**:
- 启动项目:`mvn spring-boot:run`
- 查看日志:`tail -f logs/application.log`
- 访问 `http://localhost:9900`
- 点击 "AI Ops" 观察 3-Agent 协同过程
---
### 选项 2:功能开发(需求驱动)
如果用户有具体需求,可以开始功能开发:
**常见需求方向**:
- 新增工具(如 K8s 事件查询)
- 新增 Agent(如根因分析专家 Agent)
- 接入真实的 Prometheus/CLS(关闭 Mock 模式)
- 优化 RAG 检索(调整分块策略、Top-K)
- 性能优化(Milvus 索引升级 IVF_FLAT → HNSW)
**开发前必做**:
```bash
# 影响分析(MUST)
mcp__gitnexus__impact({
target: "要修改的类或方法",
direction: "upstream",
repo: "SuperBizAgent-java"
})
# 变更检测(MUST,修改后)
mcp__gitnexus__detect_changes({repo: "SuperBizAgent-java"})
```
---
### 选项 3:问题排查(如果遇到问题)
**常见问题**:
1. **项目启动失败**
- 检查日志:`tail -f logs/application-error.log`
- 查看配置:`Read src/main/resources/application.yml`
- 验证 API Key:`spring.ai.deepseek.api-key`、`siliconflow.api-key`
2. **AI Ops 分析失败**
- 查看 AI Ops 日志:`tail -f logs/aiops.log`
- 检查 Mock 配置:`prometheus.mock-enabled: true`
- 验证工具调用:查看是否有 `QueryMetricsTools` 的 DEBUG 日志
3. **RAG 检索无结果**
- 检查 Milvus 连接:`logs/application.log` 中搜索 "Milvus"
- 验证 Collection:是否创建了 `biz` collection
- 查看向量维度:`milvus.vector-dim: 1024`(必须与 BGE-M3 一致)
---
## 💡 Suggested Skills
### 继续学习项目
```bash
# 如果要探索 RAG 知识库
/explore src/main/java/org/example/service/RagService.java
# 如果要深入某个设计模式
/essence 分析模型路由配置的设计
# 如果要理解工具集
/explore src/main/java/org/example/agent/tool/
```
### 功能开发
```bash
# 进入计划模式(修改前必做)
/plan
# 诊断问题
/diagnose [问题描述]
# 代码审查
/code-review
```
### 测试验证
```bash
# 验证功能
/verify
# 运行项目
/run
```
---
## 🔑 Key Insights
### 1. 3-Agent 协同是核心竞争力
这不是简单的 Agent 框架应用,而是一个**生产级的 AIOps 解决方案**:
- Planner 承担 Replanner 角色(动态调整策略)
- Executor 只执行"第一步"(避免规划执行混杂)
- Supervisor 循环调度(保证输出稳定性)
**与竞品对比**:
- 单 Agent 系统:无法重新规划
- 静态工作流:无法适应告警场景的不确定性
- ReAct Loop:规划与执行混杂,输出格式不稳定
### 2. outputKey 是状态共享的关键
没有 outputKey,3 个 Agent 无法协同:
```
state["planner_plan"] → Executor 读取
state["executor_feedback"] → Planner 读取并重新规划
```
### 3. Mock 模式便于开发调试
当前配置:
- `prometheus.mock-enabled: true`
- `cls.mock-enabled: true`
切换到生产环境只需改配置,无需改代码。
### 4. 模型可切换(yml 驱动)
```yaml
model-routing:
chat: deepseek # 改为 ollama 即可切换到本地模型
embedding: siliconflow # 改为 openai 即可切换到 OpenAI
```
---
## 📊 Progress Tracking
### 学习进度
| 阶段 | 状态 | 完成度 |
|------|------|--------|
| **阶段 1:核心执行流** | ✅ 完成 | 100% |
| 阶段 2:RAG 知识库 | ⏳ 待学习 | 0% |
| 阶段 3:模型路由 | ⏳ 待学习 | 0% |
| 阶段 4:Tools 工具集 | ⏳ 待学习 | 0% |
| 阶段 5:配置基础设施 | ⏳ 待学习 | 0% |
### 学习检查点
**已能回答**:
- ✅ 为什么用 3 个 Agent 而不是 1 个?
- ✅ Planner 的 Replanner 角色是什么意思?
- ✅ Executor 为什么只执行"第一步"?
- ✅ Supervisor 如何知道该调用哪个 Agent?
- ✅ outputKey 的作用是什么?
- ✅ 如何从 state 中提取最终报告?
**待验证**(完成阶段 2 后):
- ⏳ 文档分块为什么要有 overlap?
- ⏳ 为什么用 BGE-M3 而不是其他 Embedding 模型?
- ⏳ Milvus 的 IVF_FLAT 索引适合什么场景?
---
## 🔒 Context Not to Lose
### 重要的设计决策(来自 devflow)
参考 `devflow/projects/2026-05-29-chatmodel-abstraction/decisions.md`:
1. **L1**:Spring AI 1.1.0 的 OpenAiChatModel 不兼容 DeepSeek V4
- 解决:升级到 1.1.7 + 使用原生 `spring-ai-starter-model-deepseek`
2. **L2**:`@Qualifier` Bean 名不要猜
- 解决:用 `List<T>` 自检 + 类名筛选
3. **L3**:base-url 末尾不要带 `/v1`
- 原因:Spring AI 自动追加 `/v1/embeddings`,会导致双重路径
4. **L4**:多 starter 并存需要 `@Primary` 路由
- 解决:集中路由(ModelRoutingConfig)
5. **L6**:yml 驱动路由优于硬编码 @Qualifier
- 目标:换模型只改 yml,不改 Java
### GitNexus 规范(CLAUDE.md)
**修改代码前 MUST**:
```bash
# 1. 影响分析
mcp__gitnexus__impact({target: "symbolName", direction: "upstream"})
# 2. 如果是 HIGH/CRITICAL 风险,警告用户
# 3. 修改代码...
# 4. 变更检测(提交前)
mcp__gitnexus__detect_changes()
```
### 关键配置项
| 配置项 | 当前值 | 修改影响 |
|--------|--------|---------|
| `milvus.vector-dim` | 1024 | 换 Embedding 模型时必须同步修改 |
| `model-routing.chat` | deepseek | 切换 Chat 模型 |
| `model-routing.embedding` | siliconflow | 切换 Embedding 模型 |
| `prometheus.mock-enabled` | true | 接入真实 Prometheus 时改为 false |
| `cls.mock-enabled` | true | 接入真实腾讯云 CLS 时改为 false |
---
## 📞 Handoff Notes
### For the Next Agent
1. **如果用户说"继续学习"**:
- 从 `docs/项目学习路径.md` 的阶段 2 开始
- 第一个命令:`Read src/main/java/org/example/service/RagService.java`
2. **如果用户说"启动项目试试"**:
- 先验证日志配置:`bash scripts/verify-logging.sh`
- 启动:`mvn spring-boot:run`
- 查看日志:`tail -f logs/application.log`
- 访问:`http://localhost:9900`
3. **如果用户提出新需求**:
- 先问清楚具体需求
- 进入计划模式:`/plan`
- 影响分析:`mcp__gitnexus__impact`
4. **如果用户遇到问题**:
- 先查看日志:`Read logs/application-error.log`
- 使用 `/diagnose` 技能
- 参考 `docs/日志配置与分析指南.md` 的故障排查部分
### 用户可能的下一步
基于对话趋势,用户最可能:
1. **继续学习**(60%)- 按照学习路径深入理解项目
2. **实践验证**(30%)- 启动项目,观察 AI Ops 运行
3. **提出新需求**(10%)- 基于理解后想扩展功能
---
## 🎓 Learning Resources Created
用户现在拥有完整的学习体系:
### 📖 入门文档
- `docs/功能分析报告.md` - 项目是什么、能做什么
### 🛠️ 实用指南
- `docs/日志配置与分析指南.md` - 如何调试
- `docs/项目学习路径.md` - 如何学习
### 🎯 深度分析
- `docs/learning/01-AI-Ops-核心设计-Essence报告.md` - 核心设计模式
- `docs/learning/02-outputKey-深度解析.md` - 关键机制详解
- `docs/learning/03-核心疑问解答.md` - 常见疑问
- `docs/learning/README.md` - 学习索引
### ✅ 学习检查点清单
每个阶段都有明确的检查点,用户可以自我验证理解程度。
---
**Session End Time**: 2026-05-30
**Handoff Status**: ✅ Ready for next session
**Estimated Next Session Duration**: 1-2 hours (depending on chosen path)
---
> 💡 **提示给下一个 Agent**:用户已经对项目有了深刻理解,可以直接进入实践或深度学习阶段。不需要从头解释项目,直接基于已有的文档和理解继续即可。