commit
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# ChatModel + Embedding 解耦 Design
|
||||
|
||||
## 架构摘要
|
||||
|
||||
当前代码直接使用 DashScope 具体实现类 → 改为面向 Spring AI 抽象接口编程,通过 Spring Boot 自动注入切换实现。
|
||||
|
||||
## 关键决策
|
||||
|
||||
- ChatModel:Spring Boot Starter 自动注册 Bean,通过 `@Autowired ChatModel` 注入,不再手动工厂创建
|
||||
- EmbeddingModel:Spring Boot Starter 自动注册 Bean,通过 `@Autowired EmbeddingModel` 注入,替代 DashScope TextEmbedding SDK
|
||||
- RagService 流式对话:用 `ChatModel.stream(Prompt)` 返回 `Flux<ChatResponse>` 替代 DashScope Generation
|
||||
- VECTOR_DIM:从 `application.yml` 配置读取,替代 `MilvusConstants.VECTOR_DIM` 常量
|
||||
|
||||
## 模块地图
|
||||
|
||||
| 模块 | 职责 | 改动 |
|
||||
| --- | --- | --- |
|
||||
| ChatService | 封装 ChatModel + ReactAgent | 删除工厂方法,注入 ChatModel |
|
||||
| ChatController | HTTP API 入口 | 删除 DashScope import,使用注入 ChatModel |
|
||||
| AiOpsService | 多 Agent 协作 | DashScopeChatModel → ChatModel |
|
||||
| VectorEmbeddingService | 向量化 | DashScope SDK → EmbeddingModel 接口 |
|
||||
| RagService | RAG 流式对话 | DashScope Generation → ChatModel.stream() |
|
||||
| MilvusConstants | Milvus 常量 | VECTOR_DIM 改为配置化 |
|
||||
| MilvusProperties | Milvus 配置 | 新增 vectorDim 字段 |
|
||||
| ModelRoutingConfig | 模型路由 | 新增:yml 关键字驱动的 @Primary 路由(Bean 名 > 类名 > 回退) |
|
||||
| SiliconFlowEmbeddingConfig | Embedding | 新增:独立 OpenAiApi → SiliconFlow, BGE-M3 |
|
||||
| application.yml | 配置 | 新增 vector-dim 配置项 |
|
||||
|
||||
## 接口影响
|
||||
|
||||
- 级别:L2 内部接口(所有消费者在同一实现范围内)
|
||||
- 判级原因:方法签名从具体类改为接口,调用方需同步修改,但都在本项目内
|
||||
- 不改变外部 API(/api/chat, /api/chat_stream, /api/ai_ops 的 HTTP 响应不变)
|
||||
|
||||
## 架构风险
|
||||
|
||||
- RagService 流式适配最复杂:DashScope Generation 返回 Flowable<GenerationResult>,Spring AI ChatModel.stream() 返回 Flux<ChatResponse>,需适配 StreamCallback 接口
|
||||
- 缓解:Spring AI 的 Flux 与项目已有的 SSE 推送逻辑天然兼容
|
||||
- ChatModel Bean 冲突:多 starter 并存时需 @Primary 或条件注解区分默认实现
|
||||
- 缓解:通过 ModelRoutingConfig 集中管理,@Primary 声明默认 Bean;跨厂商时只改 `@Qualifier` 名
|
||||
- DashScopeConfig 通用性:`spring.ai.dashscope.chat.options.timeout` 是厂商绑定配置键
|
||||
- 缓解:本次保留该配置(只做解耦不换实现);换模型时改配置键
|
||||
@@ -0,0 +1,50 @@
|
||||
# ChatModel + Embedding 解耦 Proposal
|
||||
|
||||
## 问题
|
||||
|
||||
项目 5 个 Java 文件硬编码 DashScope 具体实现类,而非 Spring AI 抽象接口:
|
||||
|
||||
- ChatService/ChatController/AiOpsService:方法签名用 `DashScopeChatModel` 而非 `ChatModel`
|
||||
- VectorEmbeddingService:完全绕过 Spring AI,直接用 DashScope SDK 的 `TextEmbedding`
|
||||
- RagService:完全绕过 Spring AI,直接用 DashScope SDK 的 `Generation`(流式对话)
|
||||
|
||||
导致替换 LLM 或 Embedding 模型需要改代码而非改配置。
|
||||
|
||||
## 建议方案
|
||||
|
||||
**面向 Spring AI 报表接口编程**:
|
||||
- Chat 部分:`DashScopeChatModel` → `ChatModel` 接口,通过 Spring Boot 自动注入
|
||||
- Embedding 部分:DashScope SDK `TextEmbedding` → Spring AI `EmbeddingModel` 接口
|
||||
- RagService 流式对话:DashScope SDK `Generation` → Spring AI `ChatModel` 流式接口 (`stream()`)
|
||||
|
||||
通过 Spring Boot Starter + `application.yml` 配置切换模型实现,无需改代码。
|
||||
|
||||
## 范围
|
||||
|
||||
- 本次要做:
|
||||
- ChatService:删除 `createDashScopeApi()` / `createChatModel()` 工厂方法,改为注入 `ChatModel`
|
||||
- ChatController:删除 DashScope import 和手动构建,改为使用注入的 `ChatModel`
|
||||
- AiOpsService:方法签名 `DashScopeChatModel` → `ChatModel`
|
||||
- VectorEmbeddingService:DashScope SDK → Spring AI `EmbeddingModel`
|
||||
- RagService:DashScope SDK `Generation` → Spring AI `ChatModel` stream
|
||||
- DashScopeConfig:通用化配置(保留 DashScope starter 配置,但代码层不再硬编码 DashScope 类)
|
||||
- application.yml:保持现有 DashScope 配置,增加模型切换说明
|
||||
- ModelRoutingConfig:新增 `@Configuration` + `@Primary` 集中路由,支持 Chat/Embedding 跨厂商混合
|
||||
|
||||
- 本次不做:
|
||||
- 不替换 DashScope 为其他提供商(只做解耦,不换实现)
|
||||
- 不修改 Agent Framework 本身
|
||||
- 不改 Milvus 相关代码
|
||||
- 不改 MCP 客户端配置
|
||||
|
||||
## 关键约束
|
||||
|
||||
- ReactAgent.builder().model() 已接受 ChatModel 接口(已验证)
|
||||
- Spring AI 的 EmbeddingModel 接口可替代 DashScope TextEmbedding
|
||||
- Spring AI 的 ChatModel.stream() 可替代 DashScope Generation 流式接口
|
||||
- DashScope starter 仍需保留作为默认实现(通过 pom 依赖 + yml 配置)
|
||||
|
||||
## 风险
|
||||
|
||||
- RagService 流式对话的迁移可能最复杂:DashScope SDK 返回 RxJava Flowable,Spring AI ChatModel.stream() 返回 Flux,需要适配 SSE 推送逻辑
|
||||
- VectorEmbeddingService 维度可能变化:DashScope text-embedding-v4 输出 1024 维,替换模型后维度不同,需要同步修改 Milvus VECTOR_DIM 常量
|
||||
@@ -0,0 +1,30 @@
|
||||
# ChatModel + Embedding 解耦 Specs
|
||||
|
||||
## 可观察行为规格
|
||||
|
||||
### S1: Chat 接口不变
|
||||
- `/api/chat`, `/api/chat_stream`, `/api/ai_ops` 的 HTTP 入参/出参/响应结构完全不变
|
||||
- 功能行为不变:工具调用、Agent 协作、SSE 流式推送照旧工作
|
||||
|
||||
### S2: 模型切换只需改配置
|
||||
- 替换 DashScope starter 为 OpenAI starter + 改 yml 配置 → ChatModel 自动注入不同实现
|
||||
- 替换 embedding 模型只需改 yml 的 `dashscope.embedding.model` 和 `milvus.vector-dim`
|
||||
- 不需要改任何 Java 代码
|
||||
|
||||
### S3: VECTOR_DIM 从配置读取
|
||||
- `MilvusClientFactory.createBizCollection()` 使用 MilvusProperties.getVectorDim() 而非 MilvusConstants.VECTOR_DIM
|
||||
- 切换 embedding 模型后改 yml 的 `milvus.vector-dim` 即可适配新维度
|
||||
|
||||
### S4: VectorEmbeddingService 行为不变
|
||||
- generateEmbedding/generateEmbeddings/generateQueryVector 的签名和返回类型不变
|
||||
- 内部实现从 DashScope SDK 切换到 Spring AI EmbeddingModel
|
||||
|
||||
### S5: RagService 流式对话行为不变
|
||||
- queryStream 方法签名和 StreamCallback 接口不变
|
||||
- 内部实现从 DashScope Generation 切换到 Spring AI ChatModel.stream()
|
||||
|
||||
### S6: 混合厂商路由支持(yml 驱动)
|
||||
- `model-routing.chat` / `model-routing.embedding` 声明启用哪个模型
|
||||
- ModelRoutingConfig 按关键字匹配 Bean:Bean 名优先 → 类名兜底 → 回退第一个
|
||||
- 切换示例:`chat: deepseek` → `chat: openai`,只改 yml
|
||||
- Service 代码零改动
|
||||
@@ -0,0 +1,38 @@
|
||||
# ChatModel + Embedding 解耦 Tasks
|
||||
|
||||
## 需求追踪
|
||||
|
||||
| 需求 | 状态 | 备注 |
|
||||
| --- | --- | --- |
|
||||
| ChatService 解耦 DashScopeChatModel | ✅ 已完成 | 改为注入 ChatModel |
|
||||
| ChatController 解耦 DashScope | ✅ 已完成 | 删除手动构建逻辑 |
|
||||
| AiOpsService 解耦 DashScopeChatModel | ✅ 已完成 | 方法签名改为 ChatModel |
|
||||
| VectorEmbeddingService 解耦 DashScope SDK | ✅ 已完成 | 改为注入 EmbeddingModel |
|
||||
| RagService 解耦 DashScope Generation | ✅ 已完成 | 改为 ChatModel.stream() |
|
||||
| VECTOR_DIM 配置化 | ✅ 已完成 | 从 yml 读取 |
|
||||
| 混合厂商路由 | ✅ 已完成 | ModelRoutingConfig + @Primary |
|
||||
| SiliconFlow Embedding | ✅ 已完成 | SiliconFlowEmbeddingConfig + BGE-M3 |
|
||||
|
||||
## 实现任务
|
||||
|
||||
- [x] T1: MilvusProperties 新增 vectorDim 字段 + getter/setter,application.yml 新增 `milvus.vector-dim: 1024`
|
||||
- [x] T2: MilvusConstants.VECTOR_DIM 改为从 MilvusProperties 动态读取(MilvusClientFactory 传入)
|
||||
- [x] T3: ChatService — 删除 createDashScopeApi/createChatModel/createStandardChatModel,新增 @Autowired ChatModel;createReactAgent 参数改为 ChatModel
|
||||
- [x] T4: ChatController — 删除 DashScope import 和手动构建(行83-84, 171-172, 292-301),改为使用注入 ChatModel 或 ChatService 传入
|
||||
- [x] T5: AiOpsService — executeAiOpsAnalysis/buildPlannerAgent/buildExecutorAgent 参数类型 DashScopeChatModel → ChatModel
|
||||
- [x] T6: VectorEmbeddingService — 删除 DashScope SDK import + TextEmbedding 字段 + @PostConstruct init(),改为 @Autowired EmbeddingModel;generateEmbedding 改为调用 EmbeddingModel.embed()
|
||||
- [x] T7: RagService — 删除 DashScope SDK import + Generation 字段 + Constants.apiKey,改为 @Autowired ChatModel;generateAnswerStream 改为 ChatModel.stream(Prompt) + Flux 适配 StreamCallback
|
||||
- [x] T8: 新增 ModelRoutingConfig — @Configuration + @Primary ChatModel / EmbeddingModel Bean,集中管理模型路由(List<T> 自检 + 类名筛选)
|
||||
- [x] T9: 新增 SiliconFlowEmbeddingConfig — 独立 OpenAiApi → SiliconFlow,BGE-M3 1024 维
|
||||
|
||||
## 最终状态
|
||||
|
||||
| 模型 | 厂商 | Spring AI 实现 | Bean |
|
||||
|---|---|---|---|
|
||||
| Chat | DeepSeek V4 Flash | `DeepSeekChatModel` (原生) | `deepSeekChatModel` |
|
||||
| Embedding | BGE-M3 | `OpenAiEmbeddingModel` → SiliconFlow | `siliconFlowEmbeddingModel` |
|
||||
| 路由 | — | `ModelRoutingConfig` | `chatModel` + `embeddingModel` @Primary |
|
||||
|
||||
### 验证
|
||||
- `ChatAndEmbeddingSmokeTest`: 5/5 ✅
|
||||
- `FullPipelineSmokeTest`: 5/5 ✅ (Chat + Embedding + Milvus 全链路)
|
||||
Reference in New Issue
Block a user