Commit dfc3c6227c6180206305996b12bd3e12d416f3ea

Authored by YunaiV
1 parent f8ca6341

fix:【ai 大模型】混元支持 thinking 返回

yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/config/AiAutoConfiguration.java
@@ -14,6 +14,9 @@ import cn.iocoder.yudao.module.ai.framework.ai.core.model.siliconflow.SiliconFlo @@ -14,6 +14,9 @@ import cn.iocoder.yudao.module.ai.framework.ai.core.model.siliconflow.SiliconFlo
14 import cn.iocoder.yudao.module.ai.framework.ai.core.model.suno.api.SunoApi; 14 import cn.iocoder.yudao.module.ai.framework.ai.core.model.suno.api.SunoApi;
15 import cn.iocoder.yudao.module.ai.framework.ai.core.model.xinghuo.XingHuoChatModel; 15 import cn.iocoder.yudao.module.ai.framework.ai.core.model.xinghuo.XingHuoChatModel;
16 import lombok.extern.slf4j.Slf4j; 16 import lombok.extern.slf4j.Slf4j;
  17 +import org.springframework.ai.deepseek.DeepSeekChatModel;
  18 +import org.springframework.ai.deepseek.DeepSeekChatOptions;
  19 +import org.springframework.ai.deepseek.api.DeepSeekApi;
17 import org.springframework.ai.embedding.BatchingStrategy; 20 import org.springframework.ai.embedding.BatchingStrategy;
18 import org.springframework.ai.embedding.TokenCountBatchingStrategy; 21 import org.springframework.ai.embedding.TokenCountBatchingStrategy;
19 import org.springframework.ai.model.tool.ToolCallingManager; 22 import org.springframework.ai.model.tool.ToolCallingManager;
@@ -152,13 +155,14 @@ public class AiAutoConfiguration { @@ -152,13 +155,14 @@ public class AiAutoConfiguration {
152 StrUtil.startWithIgnoreCase(properties.getModel(), "deepseek") ? HunYuanChatModel.DEEP_SEEK_BASE_URL 155 StrUtil.startWithIgnoreCase(properties.getModel(), "deepseek") ? HunYuanChatModel.DEEP_SEEK_BASE_URL
153 : HunYuanChatModel.BASE_URL); 156 : HunYuanChatModel.BASE_URL);
154 } 157 }
155 - // 创建 OpenAiChatModel、HunYuanChatModel 对象  
156 - OpenAiChatModel openAiChatModel = OpenAiChatModel.builder()  
157 - .openAiApi(OpenAiApi.builder() 158 + // 创建 DeepSeekChatModel、HunYuanChatModel 对象
  159 + DeepSeekChatModel openAiChatModel = DeepSeekChatModel.builder()
  160 + .deepSeekApi(DeepSeekApi.builder()
158 .baseUrl(properties.getBaseUrl()) 161 .baseUrl(properties.getBaseUrl())
  162 + .completionsPath(HunYuanChatModel.COMPLETE_PATH)
159 .apiKey(properties.getApiKey()) 163 .apiKey(properties.getApiKey())
160 .build()) 164 .build())
161 - .defaultOptions(OpenAiChatOptions.builder() 165 + .defaultOptions(DeepSeekChatOptions.builder()
162 .model(properties.getModel()) 166 .model(properties.getModel())
163 .temperature(properties.getTemperature()) 167 .temperature(properties.getTemperature())
164 .maxTokens(properties.getMaxTokens()) 168 .maxTokens(properties.getMaxTokens())
yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/hunyuan/HunYuanChatModel.java
@@ -6,7 +6,6 @@ import org.springframework.ai.chat.model.ChatModel; @@ -6,7 +6,6 @@ import org.springframework.ai.chat.model.ChatModel;
6 import org.springframework.ai.chat.model.ChatResponse; 6 import org.springframework.ai.chat.model.ChatResponse;
7 import org.springframework.ai.chat.prompt.ChatOptions; 7 import org.springframework.ai.chat.prompt.ChatOptions;
8 import org.springframework.ai.chat.prompt.Prompt; 8 import org.springframework.ai.chat.prompt.Prompt;
9 -import org.springframework.ai.openai.OpenAiChatModel;  
10 import reactor.core.publisher.Flux; 9 import reactor.core.publisher.Flux;
11 10
12 /** 11 /**
@@ -22,6 +21,7 @@ import reactor.core.publisher.Flux; @@ -22,6 +21,7 @@ import reactor.core.publisher.Flux;
22 public class HunYuanChatModel implements ChatModel { 21 public class HunYuanChatModel implements ChatModel {
23 22
24 public static final String BASE_URL = "https://api.hunyuan.cloud.tencent.com"; 23 public static final String BASE_URL = "https://api.hunyuan.cloud.tencent.com";
  24 + public static final String COMPLETE_PATH = "/v1/chat/completions";
25 25
26 public static final String MODEL_DEFAULT = "hunyuan-turbo"; 26 public static final String MODEL_DEFAULT = "hunyuan-turbo";
27 27
@@ -32,7 +32,7 @@ public class HunYuanChatModel implements ChatModel { @@ -32,7 +32,7 @@ public class HunYuanChatModel implements ChatModel {
32 /** 32 /**
33 * 兼容 OpenAI 接口,进行复用 33 * 兼容 OpenAI 接口,进行复用
34 */ 34 */
35 - private final OpenAiChatModel openAiChatModel; 35 + private final ChatModel openAiChatModel;
36 36
37 @Override 37 @Override
38 public ChatResponse call(Prompt prompt) { 38 public ChatResponse call(Prompt prompt) {
yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java
@@ -52,6 +52,7 @@ public class AiUtils { @@ -52,6 +52,7 @@ public class AiUtils {
52 case DOU_BAO: // 复用 DeepSeek 客户端 52 case DOU_BAO: // 复用 DeepSeek 客户端
53 return DeepSeekChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens) 53 return DeepSeekChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
54 .toolNames(toolNames).toolContext(toolContext).build(); 54 .toolNames(toolNames).toolContext(toolContext).build();
  55 + case HUN_YUAN: // 复用 DeepSeek 客户端
55 case ZHI_PU: 56 case ZHI_PU:
56 return ZhiPuAiChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens) 57 return ZhiPuAiChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
57 .toolNames(toolNames).toolContext(toolContext).build(); 58 .toolNames(toolNames).toolContext(toolContext).build();
@@ -63,7 +64,6 @@ public class AiUtils { @@ -63,7 +64,6 @@ public class AiUtils {
63 .toolNames(toolNames).toolContext(toolContext).build(); 64 .toolNames(toolNames).toolContext(toolContext).build();
64 case OPENAI: 65 case OPENAI:
65 case GEMINI: // 复用 OpenAI 客户端 66 case GEMINI: // 复用 OpenAI 客户端
66 - case HUN_YUAN: // 复用 OpenAI 客户端  
67 case XING_HUO: // 复用 OpenAI 客户端 67 case XING_HUO: // 复用 OpenAI 客户端
68 case SILICON_FLOW: // 复用 OpenAI 客户端 68 case SILICON_FLOW: // 复用 OpenAI 客户端
69 case BAI_CHUAN: // 复用 OpenAI 客户端 69 case BAI_CHUAN: // 复用 OpenAI 客户端
yudao-module-ai/src/test/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/chat/HunYuanChatModelTests.java
@@ -8,9 +8,9 @@ import org.springframework.ai.chat.messages.SystemMessage; @@ -8,9 +8,9 @@ import org.springframework.ai.chat.messages.SystemMessage;
8 import org.springframework.ai.chat.messages.UserMessage; 8 import org.springframework.ai.chat.messages.UserMessage;
9 import org.springframework.ai.chat.model.ChatResponse; 9 import org.springframework.ai.chat.model.ChatResponse;
10 import org.springframework.ai.chat.prompt.Prompt; 10 import org.springframework.ai.chat.prompt.Prompt;
11 -import org.springframework.ai.openai.OpenAiChatModel;  
12 -import org.springframework.ai.openai.OpenAiChatOptions;  
13 -import org.springframework.ai.openai.api.OpenAiApi; 11 +import org.springframework.ai.deepseek.DeepSeekChatModel;
  12 +import org.springframework.ai.deepseek.DeepSeekChatOptions;
  13 +import org.springframework.ai.deepseek.api.DeepSeekApi;
14 import reactor.core.publisher.Flux; 14 import reactor.core.publisher.Flux;
15 15
16 import java.util.ArrayList; 16 import java.util.ArrayList;
@@ -23,12 +23,13 @@ import java.util.List; @@ -23,12 +23,13 @@ import java.util.List;
23 */ 23 */
24 public class HunYuanChatModelTests { 24 public class HunYuanChatModelTests {
25 25
26 - private final OpenAiChatModel openAiChatModel = OpenAiChatModel.builder()  
27 - .openAiApi(OpenAiApi.builder() 26 + private final DeepSeekChatModel openAiChatModel = DeepSeekChatModel.builder()
  27 + .deepSeekApi(DeepSeekApi.builder()
28 .baseUrl(HunYuanChatModel.BASE_URL) 28 .baseUrl(HunYuanChatModel.BASE_URL)
29 - .apiKey("sk-bcd") // apiKey 29 + .completionsPath(HunYuanChatModel.COMPLETE_PATH)
  30 + .apiKey("sk-abc") // apiKey
30 .build()) 31 .build())
31 - .defaultOptions(OpenAiChatOptions.builder() 32 + .defaultOptions(DeepSeekChatOptions.builder()
32 .model(HunYuanChatModel.MODEL_DEFAULT) // 模型 33 .model(HunYuanChatModel.MODEL_DEFAULT) // 模型
33 .temperature(0.7) 34 .temperature(0.7)
34 .build()) 35 .build())
@@ -64,12 +65,33 @@ public class HunYuanChatModelTests { @@ -64,12 +65,33 @@ public class HunYuanChatModelTests {
64 flux.doOnNext(System.out::println).then().block(); 65 flux.doOnNext(System.out::println).then().block();
65 } 66 }
66 67
67 - private final OpenAiChatModel deepSeekOpenAiChatModel = OpenAiChatModel.builder()  
68 - .openAiApi(OpenAiApi.builder() 68 + @Test
  69 + @Disabled
  70 + public void testStream_thinking() {
  71 + // 准备参数
  72 + List<Message> messages = new ArrayList<>();
  73 + messages.add(new UserMessage("详细分析下,如何设计一个电商系统?"));
  74 + DeepSeekChatOptions options = DeepSeekChatOptions.builder()
  75 + .model("hunyuan-a13b")
  76 +// .model("hunyuan-turbos-latest")
  77 + .build();
  78 +
  79 + // 调用
  80 + Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages, options));
  81 + // 打印结果
  82 + flux.doOnNext(response -> {
  83 +// System.out.println(response);
  84 + System.out.println(response.getResult().getOutput());
  85 + }).then().block();
  86 + }
  87 +
  88 + private final DeepSeekChatModel deepSeekOpenAiChatModel = DeepSeekChatModel.builder()
  89 + .deepSeekApi(DeepSeekApi.builder()
69 .baseUrl(HunYuanChatModel.DEEP_SEEK_BASE_URL) 90 .baseUrl(HunYuanChatModel.DEEP_SEEK_BASE_URL)
  91 + .completionsPath(HunYuanChatModel.COMPLETE_PATH)
70 .apiKey("sk-abc") // apiKey 92 .apiKey("sk-abc") // apiKey
71 .build()) 93 .build())
72 - .defaultOptions(OpenAiChatOptions.builder() 94 + .defaultOptions(DeepSeekChatOptions.builder()
73 // .model(HunYuanChatModel.DEEP_SEEK_MODEL_DEFAULT) // 模型("deepseek-v3") 95 // .model(HunYuanChatModel.DEEP_SEEK_MODEL_DEFAULT) // 模型("deepseek-v3")
74 .model("deepseek-r1") // 模型("deepseek-r1") 96 .model("deepseek-r1") // 模型("deepseek-r1")
75 .temperature(0.7) 97 .temperature(0.7)
@@ -94,7 +116,7 @@ public class HunYuanChatModelTests { @@ -94,7 +116,7 @@ public class HunYuanChatModelTests {
94 116
95 @Test 117 @Test
96 @Disabled 118 @Disabled
97 - public void testStream_deekseek() { 119 + public void testStream_deepseek() {
98 // 准备参数 120 // 准备参数
99 List<Message> messages = new ArrayList<>(); 121 List<Message> messages = new ArrayList<>();
100 messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。")); 122 messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
@@ -106,5 +128,23 @@ public class HunYuanChatModelTests { @@ -106,5 +128,23 @@ public class HunYuanChatModelTests {
106 flux.doOnNext(System.out::println).then().block(); 128 flux.doOnNext(System.out::println).then().block();
107 } 129 }
108 130
  131 + @Test
  132 + @Disabled
  133 + public void testStream_deepseek_thinking() {
  134 + // 准备参数
  135 + List<Message> messages = new ArrayList<>();
  136 + messages.add(new UserMessage("详细分析下,如何设计一个电商系统?"));
  137 + DeepSeekChatOptions options = DeepSeekChatOptions.builder()
  138 + .model("deepseek-r1")
  139 + .build();
  140 +
  141 + // 调用
  142 + Flux<ChatResponse> flux = deepSeekChatModel.stream(new Prompt(messages, options));
  143 + // 打印结果
  144 + flux.doOnNext(response -> {
  145 +// System.out.println(response);
  146 + System.out.println(response.getResult().getOutput());
  147 + }).then().block();
  148 + }
109 149
110 } 150 }