From 5267d29d970f8187d25078087bdf39f5ba2d7ec8 Mon Sep 17 00:00:00 2001 From: Ttt Date: Tue, 17 Mar 2026 22:49:00 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=99=BA=E8=83=BD=E4=BD=93=E5=88=9B?= =?UTF-8?q?=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-local.yml | 5 +++++ .../xservice/ai/agent/SimpleChatAgent.java | 2 +- .../ai/core/provider/BaseProvider.java | 10 ++++++++-- .../ai/core/provider/OllamaLlmProvider.java | 9 +++++++++ .../ai/core/provider/OpenAILlmProvider.java | 19 ++++++++++++++++--- .../xservice/ai/core/route/ModelRouter.java | 12 +++++++++--- .../xservice/ai/core/route/TaskRouter.java | 13 ++++++++++++- .../ai/core/strategy/ChatStrategy.java | 4 +--- 8 files changed, 61 insertions(+), 13 deletions(-) diff --git a/xservice-server/src/main/resources/application-local.yml b/xservice-server/src/main/resources/application-local.yml index bc138ef..c8e8e39 100644 --- a/xservice-server/src/main/resources/application-local.yml +++ b/xservice-server/src/main/resources/application-local.yml @@ -12,4 +12,9 @@ ai: apiKey: sk-70cb426d7d1e4b54b4ffe71022e7d815 modelName: qwen3.5-plus baseUrl: https://dashscope.aliyuncs.com/compatible-mode/v1 + ollama: + configs: + qwen3: + modelName: qwen3 + baseUrl: http://192.168.1.12:11434/api/chat diff --git a/xservice-service/src/main/java/com/xiang/xservice/ai/agent/SimpleChatAgent.java b/xservice-service/src/main/java/com/xiang/xservice/ai/agent/SimpleChatAgent.java index c4e2f5b..f4469c5 100644 --- a/xservice-service/src/main/java/com/xiang/xservice/ai/agent/SimpleChatAgent.java +++ b/xservice-service/src/main/java/com/xiang/xservice/ai/agent/SimpleChatAgent.java @@ -49,7 +49,7 @@ public class SimpleChatAgent implements BaseAgent { .modelName(openAIConfig.getModelName()) .temperature(openAIConfig.getTemperature()) .build(); - StreamingChatModel chat = router.route(ModelStrategyEnum.CHAT, modelType.getModelType(), modelConfig); + StreamingChatModel chat = router.routeStream(ModelStrategyEnum.CHAT, modelType.getModelType(), modelConfig); if (chat == null) { throw new RuntimeException("chat model route failed"); } diff --git a/xservice-service/src/main/java/com/xiang/xservice/ai/core/provider/BaseProvider.java b/xservice-service/src/main/java/com/xiang/xservice/ai/core/provider/BaseProvider.java index ef32ca1..aeed6e0 100644 --- a/xservice-service/src/main/java/com/xiang/xservice/ai/core/provider/BaseProvider.java +++ b/xservice-service/src/main/java/com/xiang/xservice/ai/core/provider/BaseProvider.java @@ -2,7 +2,6 @@ package com.xiang.xservice.ai.core.provider; import com.xiang.xservice.ai.core.entity.ModelConfig; import com.xiang.xservice.ai.core.enums.ModelStrategyEnum; -import com.xiang.xservice.ai.core.enums.ModelTypeEnum; import dev.langchain4j.model.chat.ChatModel; import dev.langchain4j.model.chat.StreamingChatModel; @@ -14,11 +13,18 @@ public interface BaseProvider { */ String providerName(); /** - * 创建model + * 创建流式model * @param config model配置文件 * @return ChatModel */ StreamingChatModel build(ModelConfig config); + + /** + * 同步聊天模型 + * @param config + * @return + */ + ChatModel buildChatModel(ModelConfig config); /** * 用于标记这个 Provider 是否适合某个 TaskType * @param taskType ModelStrategyEnum diff --git a/xservice-service/src/main/java/com/xiang/xservice/ai/core/provider/OllamaLlmProvider.java b/xservice-service/src/main/java/com/xiang/xservice/ai/core/provider/OllamaLlmProvider.java index 3032a24..16a35eb 100644 --- a/xservice-service/src/main/java/com/xiang/xservice/ai/core/provider/OllamaLlmProvider.java +++ b/xservice-service/src/main/java/com/xiang/xservice/ai/core/provider/OllamaLlmProvider.java @@ -26,6 +26,15 @@ public class OllamaLlmProvider implements BaseProvider{ .build(); } + @Override + public ChatModel buildChatModel(ModelConfig config) { + return OllamaChatModel.builder() + .baseUrl(config.getBaseUrl()) + .modelName(config.getModelName()) + .temperature(config.getTemperature()) + .build(); + } + @Override public boolean support(ModelStrategyEnum taskType) { return true; diff --git a/xservice-service/src/main/java/com/xiang/xservice/ai/core/provider/OpenAILlmProvider.java b/xservice-service/src/main/java/com/xiang/xservice/ai/core/provider/OpenAILlmProvider.java index ea52dce..fef3d20 100644 --- a/xservice-service/src/main/java/com/xiang/xservice/ai/core/provider/OpenAILlmProvider.java +++ b/xservice-service/src/main/java/com/xiang/xservice/ai/core/provider/OpenAILlmProvider.java @@ -3,13 +3,14 @@ package com.xiang.xservice.ai.core.provider; import com.xiang.xservice.ai.core.entity.ModelConfig; import com.xiang.xservice.ai.core.enums.ModelStrategyEnum; import com.xiang.xservice.ai.core.enums.ModelTypeEnum; -import com.xiang.xservice.ai.core.storage.MemoryPersistentStore; -import dev.langchain4j.memory.chat.ChatMemoryProvider; -import dev.langchain4j.memory.chat.MessageWindowChatMemory; +import dev.langchain4j.model.chat.ChatModel; import dev.langchain4j.model.chat.StreamingChatModel; +import dev.langchain4j.model.openai.OpenAiChatModel; import dev.langchain4j.model.openai.OpenAiStreamingChatModel; import org.springframework.stereotype.Component; +import java.time.Duration; + @Component public class OpenAILlmProvider implements BaseProvider { @@ -33,6 +34,18 @@ public class OpenAILlmProvider implements BaseProvider { .build(); } + @Override + public ChatModel buildChatModel(ModelConfig config) { + return OpenAiChatModel.builder() + .baseUrl(config.getBaseUrl()) + .apiKey(config.getApiKey()) + .modelName(config.getModelName()) + .temperature(config.getTemperature()) + .maxTokens(config.getMaxTokens()) + .timeout(Duration.ofSeconds(300)) + .build(); + } + @Override public boolean support(ModelStrategyEnum taskType) { return true; diff --git a/xservice-service/src/main/java/com/xiang/xservice/ai/core/route/ModelRouter.java b/xservice-service/src/main/java/com/xiang/xservice/ai/core/route/ModelRouter.java index 36683d6..339ca98 100644 --- a/xservice-service/src/main/java/com/xiang/xservice/ai/core/route/ModelRouter.java +++ b/xservice-service/src/main/java/com/xiang/xservice/ai/core/route/ModelRouter.java @@ -3,10 +3,8 @@ package com.xiang.xservice.ai.core.route; import com.xiang.xservice.ai.core.entity.ModelConfig; import com.xiang.xservice.ai.core.enums.ModelStrategyEnum; import com.xiang.xservice.ai.core.provider.BaseProvider; -import com.xiang.xservice.ai.core.strategy.BaseStrategy; import dev.langchain4j.model.chat.ChatModel; import dev.langchain4j.model.chat.StreamingChatModel; -import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import java.util.List; @@ -29,7 +27,7 @@ public class ModelRouter { /** * 根据 providerName 选择 Provider,并用 config 构建模型 */ - public StreamingChatModel route(String providerName, ModelConfig config) { + public StreamingChatModel routeStream(String providerName, ModelConfig config) { BaseProvider provider = providerMap.get(providerName); if (provider == null) { throw new RuntimeException("Provider " + providerName + " not found"); @@ -37,6 +35,14 @@ public class ModelRouter { return provider.build(config); } + public ChatModel route(String providerName, ModelConfig config) { + BaseProvider provider = providerMap.get(providerName); + if (provider == null) { + throw new RuntimeException("Provider " + providerName + " not found"); + } + return provider.buildChatModel(config); + } + /** * 获取某个 TaskType 支持的所有 Provider 名称 */ diff --git a/xservice-service/src/main/java/com/xiang/xservice/ai/core/route/TaskRouter.java b/xservice-service/src/main/java/com/xiang/xservice/ai/core/route/TaskRouter.java index a099dc9..ea9e2fc 100644 --- a/xservice-service/src/main/java/com/xiang/xservice/ai/core/route/TaskRouter.java +++ b/xservice-service/src/main/java/com/xiang/xservice/ai/core/route/TaskRouter.java @@ -3,6 +3,7 @@ package com.xiang.xservice.ai.core.route; import com.xiang.xservice.ai.core.entity.ModelConfig; import com.xiang.xservice.ai.core.enums.ModelStrategyEnum; import com.xiang.xservice.ai.core.provider.BaseProvider; +import dev.langchain4j.model.chat.ChatModel; import dev.langchain4j.model.chat.StreamingChatModel; import org.springframework.stereotype.Component; @@ -29,7 +30,17 @@ public class TaskRouter { /** * 第一层路由 + 第二层 ProviderRouter */ - public StreamingChatModel route(ModelStrategyEnum taskType, String providerName, ModelConfig config) { + public StreamingChatModel routeStream(ModelStrategyEnum taskType, String providerName, ModelConfig config) { + // 如果没有传 providerName,使用默认 Provider + if (providerName == null || providerName.isEmpty()) { + providerName = taskDefaultProviderMap.get(taskType).get(0); + } + + // 第二层路由 + return providerRouter.routeStream(providerName, config); + } + + public ChatModel route(ModelStrategyEnum taskType, String providerName, ModelConfig config) { // 如果没有传 providerName,使用默认 Provider if (providerName == null || providerName.isEmpty()) { providerName = taskDefaultProviderMap.get(taskType).get(0); diff --git a/xservice-service/src/main/java/com/xiang/xservice/ai/core/strategy/ChatStrategy.java b/xservice-service/src/main/java/com/xiang/xservice/ai/core/strategy/ChatStrategy.java index a9f774f..14e1887 100644 --- a/xservice-service/src/main/java/com/xiang/xservice/ai/core/strategy/ChatStrategy.java +++ b/xservice-service/src/main/java/com/xiang/xservice/ai/core/strategy/ChatStrategy.java @@ -2,9 +2,7 @@ package com.xiang.xservice.ai.core.strategy; import com.xiang.xservice.ai.core.entity.ModelConfig; import com.xiang.xservice.ai.core.enums.ModelStrategyEnum; -import com.xiang.xservice.ai.core.provider.BaseProvider; import com.xiang.xservice.ai.core.route.TaskRouter; -import dev.langchain4j.model.chat.ChatModel; import dev.langchain4j.model.chat.StreamingChatModel; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @@ -22,6 +20,6 @@ public class ChatStrategy implements BaseStrategy { @Override public StreamingChatModel createProvider(String provider, ModelConfig config) { - return taskRouter.route(ModelStrategyEnum.CHAT, provider, config); + return taskRouter.routeStream(ModelStrategyEnum.CHAT, provider, config); } }