# 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 常量