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 基础地址',