Files
SuperBizAgent-java/handoff/handoff-chatmodel-abstraction.md
T
2026-05-31 21:45:14 +08:00

4.6 KiB
Raw Blame History

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 客户端重新启用 + 真实腾讯云日志查询验证