4.6 KiB
4.6 KiB
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.javasrc/main/java/org/example/config/SiliconFlowEmbeddingConfig.javasrc/test/java/org/example/service/ChatAndEmbeddingSmokeTest.javasrc/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:
- Spring AI version → 模型兼容性: 1.1.0 的 OpenAI 兼容模式不兼容 DeepSeek V4(2026年4月发布),升级到 1.1.7 + 原生 DeepSeekChatModel 才解决
@QualifierBean 名不要猜: 用List<T>自检 + 类名筛选比硬编码更稳- base-url 不要带
/v1: Spring AI 自动追加版本路径,会导致双重 - 多 starter 并存需要
@Primary: ModelRoutingConfig 集中路由 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 检查
可能的后续工作
- 运行
npx openspec归档当前 change(archive 阶段) - 真实 Milvus 数据灌入验证(当前 collection 为空)
- RagService SSE 端到端测试(需要启动应用)
- Ollama 本地 embedding 替代(如果 SiliconFlow 不可用)
- MCP 客户端重新启用 + 真实腾讯云日志查询验证