From 1a6e25758ebe756f9c80e3a381232da157e6003a Mon Sep 17 00:00:00 2001 From: Dallas98 <40557804+Dallas98@users.noreply.github.com> Date: Tue, 28 Oct 2025 16:06:53 +0800 Subject: [PATCH] feat: add model health check functionality and improve model configuration (#30) * refactor: rename artifactId and application name to 'datamate'; add model configuration and related services * refactor: simplify package scanning by using wildcard for mapper packages * feat: add model health check functionality and improve model configuration --- backend/pom.xml | 13 ++++++++ .../models/domain/entity/ModelConfig.java | 2 ++ .../infrastructure/client/ModelClient.java | 30 +++++++++++++++---- .../exception/ModelsErrorCode.java | 7 ++++- .../rest/ModelConfigController.java | 6 ++-- scripts/db/model-management-init.sql | 4 ++- 6 files changed, 52 insertions(+), 10 deletions(-) diff --git a/backend/pom.xml b/backend/pom.xml index 8a7a795..ef6da27 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -207,6 +207,19 @@ spring-boot-maven-plugin ${spring-boot.version} + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + ${maven.compiler.source} + ${maven.compiler.target} + true + + -parameters + + + diff --git a/backend/shared/domain-common/src/main/java/com/datamate/common/models/domain/entity/ModelConfig.java b/backend/shared/domain-common/src/main/java/com/datamate/common/models/domain/entity/ModelConfig.java index 1eecd8e..9cfbbff 100644 --- a/backend/shared/domain-common/src/main/java/com/datamate/common/models/domain/entity/ModelConfig.java +++ b/backend/shared/domain-common/src/main/java/com/datamate/common/models/domain/entity/ModelConfig.java @@ -5,6 +5,7 @@ import com.datamate.common.domain.model.base.BaseEntity; import lombok.Builder; import lombok.Getter; import lombok.Setter; +import lombok.ToString; /** * 模型配置实体类 @@ -16,6 +17,7 @@ import lombok.Setter; @Setter @TableName("t_model_config") @Builder +@ToString public class ModelConfig extends BaseEntity { /** * 模型名称(如 qwen2) diff --git a/backend/shared/domain-common/src/main/java/com/datamate/common/models/infrastructure/client/ModelClient.java b/backend/shared/domain-common/src/main/java/com/datamate/common/models/infrastructure/client/ModelClient.java index 5246c03..26ddf73 100644 --- a/backend/shared/domain-common/src/main/java/com/datamate/common/models/infrastructure/client/ModelClient.java +++ b/backend/shared/domain-common/src/main/java/com/datamate/common/models/infrastructure/client/ModelClient.java @@ -1,13 +1,13 @@ package com.datamate.common.models.infrastructure.client; +import com.datamate.common.infrastructure.exception.BusinessException; import com.datamate.common.models.domain.entity.ModelConfig; -import com.datamate.common.models.domain.entity.ModelType; +import com.datamate.common.models.infrastructure.exception.ModelsErrorCode; import dev.langchain4j.model.chat.ChatModel; import dev.langchain4j.model.embedding.EmbeddingModel; import dev.langchain4j.model.openai.OpenAiChatModel; import dev.langchain4j.model.openai.OpenAiEmbeddingModel; - -import java.util.function.Consumer; +import lombok.extern.slf4j.Slf4j; /** * 模型客户端接口 @@ -15,6 +15,7 @@ import java.util.function.Consumer; * @author dallas * @since 2025-10-27 */ +@Slf4j public class ModelClient { public static T invokeModel(ModelConfig modelConfig, Class modelInterface) { return switch (modelConfig.getType()) { @@ -23,7 +24,7 @@ public class ModelClient { }; } - private static EmbeddingModel invokeEmbeddingModel(ModelConfig modelConfig) { + public static EmbeddingModel invokeEmbeddingModel(ModelConfig modelConfig) { return OpenAiEmbeddingModel.builder() .baseUrl(modelConfig.getBaseUrl()) .apiKey(modelConfig.getApiKey()) @@ -31,7 +32,7 @@ public class ModelClient { .build(); } - private static ChatModel invokeChatModel(ModelConfig modelConfig) { + public static ChatModel invokeChatModel(ModelConfig modelConfig) { return OpenAiChatModel.builder() .baseUrl(modelConfig.getBaseUrl()) .apiKey(modelConfig.getApiKey()) @@ -40,5 +41,24 @@ public class ModelClient { } public static void checkHealth(ModelConfig modelConfig) { + try { + switch (modelConfig.getType()) { + case CHAT -> checkChatModelHealth(modelConfig); + case EMBEDDING -> checkEmbeddingModelHealth(modelConfig); + } + } catch (Exception e) { + log.error("Model health check failed for modelConfig: {}", modelConfig, e); + throw BusinessException.of(ModelsErrorCode.MODEL_HEALTH_CHECK_FAILED); + } + } + + private static void checkEmbeddingModelHealth(ModelConfig modelConfig) { + EmbeddingModel embeddingModel = invokeEmbeddingModel(modelConfig); + embeddingModel.embed("text"); + } + + private static void checkChatModelHealth(ModelConfig modelConfig) { + ChatModel chatModel = invokeChatModel(modelConfig); + chatModel.chat("hello"); } } diff --git a/backend/shared/domain-common/src/main/java/com/datamate/common/models/infrastructure/exception/ModelsErrorCode.java b/backend/shared/domain-common/src/main/java/com/datamate/common/models/infrastructure/exception/ModelsErrorCode.java index e083583..48501a1 100644 --- a/backend/shared/domain-common/src/main/java/com/datamate/common/models/infrastructure/exception/ModelsErrorCode.java +++ b/backend/shared/domain-common/src/main/java/com/datamate/common/models/infrastructure/exception/ModelsErrorCode.java @@ -20,7 +20,12 @@ public enum ModelsErrorCode implements ErrorCode { /** * 模型配置已存在 */ - MODEL_CONFIG_ALREADY_EXISTS("model.0002", "模型配置已存在"); + MODEL_CONFIG_ALREADY_EXISTS("model.0002", "模型配置已存在"), + + /** + * 模型健康检查失败 + */ + MODEL_HEALTH_CHECK_FAILED("model.0003", "模型健康检查失败"); private final String code; private final String message; diff --git a/backend/shared/domain-common/src/main/java/com/datamate/common/models/interfaces/rest/ModelConfigController.java b/backend/shared/domain-common/src/main/java/com/datamate/common/models/interfaces/rest/ModelConfigController.java index e05ddc5..20eacf8 100644 --- a/backend/shared/domain-common/src/main/java/com/datamate/common/models/interfaces/rest/ModelConfigController.java +++ b/backend/shared/domain-common/src/main/java/com/datamate/common/models/interfaces/rest/ModelConfigController.java @@ -19,7 +19,7 @@ import java.util.List; * @since 2025-10-27 */ @RestController -@RequestMapping("/api/models") +@RequestMapping("/models") @RequiredArgsConstructor public class ModelConfigController { private final ModelConfigApplicationService modelConfigApplicationService; @@ -40,7 +40,7 @@ public class ModelConfigController { * @return 模型列表 */ @GetMapping("/list") - public PagedResponse getModels(@RequestParam QueryModelRequest queryModelRequest) { + public PagedResponse getModels(QueryModelRequest queryModelRequest) { return modelConfigApplicationService.getModels(queryModelRequest); } @@ -51,7 +51,7 @@ public class ModelConfigController { * @return 模型详情 */ @GetMapping("/{modelId}") - public ModelConfig getModelDetail(@PathVariable String modelId) { + public ModelConfig getModelDetail(@PathVariable("modelId") String modelId) { return modelConfigApplicationService.getModelDetail(modelId); } diff --git a/scripts/db/model-management-init.sql b/scripts/db/model-management-init.sql index 993ba5a..0ad2548 100644 --- a/scripts/db/model-management-init.sql +++ b/scripts/db/model-management-init.sql @@ -1,6 +1,8 @@ +USE datamate; + CREATE TABLE t_model_config ( - id VARCHAR(36) AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID', + id VARCHAR(36) PRIMARY KEY COMMENT '主键ID', model_name VARCHAR(100) NOT NULL COMMENT '模型名称(如 qwen2)', provider VARCHAR(50) NOT NULL COMMENT '模型提供商(如 Ollama、OpenAI、DeepSeek)', base_url VARCHAR(255) NOT NULL COMMENT 'API 基础地址',