Commit 07fe6167e09d5b4e4d5707a4d313b5b27f4cc3f2

Authored by YunaiV
1 parent 99d5e7c5

【功能新增】AI:接入 minimax 和 moonshot 月之暗灭(kimi)

yudao-module-ai/yudao-spring-boot-starter-ai/pom.xml
@@ -14,7 +14,6 @@ @@ -14,7 +14,6 @@
14 <name>${project.artifactId}</name> 14 <name>${project.artifactId}</name>
15 <description>AI 大模型拓展,接入国内外大模型</description> 15 <description>AI 大模型拓展,接入国内外大模型</description>
16 <properties> 16 <properties>
17 - <spring-ai.groupId>org.springframework.ai</spring-ai.groupId>  
18 <spring-ai.version>1.0.0-M6</spring-ai.version> 17 <spring-ai.version>1.0.0-M6</spring-ai.version>
19 </properties> 18 </properties>
20 19
@@ -26,22 +25,22 @@ @@ -26,22 +25,22 @@
26 25
27 <!-- Spring AI Model 模型接入 --> 26 <!-- Spring AI Model 模型接入 -->
28 <dependency> 27 <dependency>
29 - <groupId>${spring-ai.groupId}</groupId> 28 + <groupId>org.springframework.ai</groupId>
30 <artifactId>spring-ai-openai-spring-boot-starter</artifactId> 29 <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
31 <version>${spring-ai.version}</version> 30 <version>${spring-ai.version}</version>
32 </dependency> 31 </dependency>
33 <dependency> 32 <dependency>
34 - <groupId>${spring-ai.groupId}</groupId> 33 + <groupId>org.springframework.ai</groupId>
35 <artifactId>spring-ai-azure-openai-spring-boot-starter</artifactId> 34 <artifactId>spring-ai-azure-openai-spring-boot-starter</artifactId>
36 <version>${spring-ai.version}</version> 35 <version>${spring-ai.version}</version>
37 </dependency> 36 </dependency>
38 <dependency> 37 <dependency>
39 - <groupId>${spring-ai.groupId}</groupId> 38 + <groupId>org.springframework.ai</groupId>
40 <artifactId>spring-ai-ollama-spring-boot-starter</artifactId> 39 <artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
41 <version>${spring-ai.version}</version> 40 <version>${spring-ai.version}</version>
42 </dependency> 41 </dependency>
43 <dependency> 42 <dependency>
44 - <groupId>${spring-ai.groupId}</groupId> 43 + <groupId>org.springframework.ai</groupId>
45 <artifactId>spring-ai-stability-ai-spring-boot-starter</artifactId> 44 <artifactId>spring-ai-stability-ai-spring-boot-starter</artifactId>
46 <version>${spring-ai.version}</version> 45 <version>${spring-ai.version}</version>
47 </dependency> 46 </dependency>
@@ -53,28 +52,38 @@ @@ -53,28 +52,38 @@
53 </dependency> 52 </dependency>
54 <dependency> 53 <dependency>
55 <!-- 文心一言 --> 54 <!-- 文心一言 -->
56 - <groupId>${spring-ai.groupId}</groupId> 55 + <groupId>org.springframework.ai</groupId>
57 <artifactId>spring-ai-qianfan-spring-boot-starter</artifactId> 56 <artifactId>spring-ai-qianfan-spring-boot-starter</artifactId>
58 <version>${spring-ai.version}</version> 57 <version>${spring-ai.version}</version>
59 </dependency> 58 </dependency>
60 <dependency> 59 <dependency>
61 <!-- 智谱 GLM --> 60 <!-- 智谱 GLM -->
62 - <groupId>${spring-ai.groupId}</groupId> 61 + <groupId>org.springframework.ai</groupId>
63 <artifactId>spring-ai-zhipuai-spring-boot-starter</artifactId> 62 <artifactId>spring-ai-zhipuai-spring-boot-starter</artifactId>
64 <version>${spring-ai.version}</version> 63 <version>${spring-ai.version}</version>
65 </dependency> 64 </dependency>
  65 + <dependency>
  66 + <groupId>org.springframework.ai</groupId>
  67 + <artifactId>spring-ai-minimax-spring-boot-starter</artifactId>
  68 + <version>${spring-ai.version}</version>
  69 + </dependency>
  70 + <dependency>
  71 + <groupId>org.springframework.ai</groupId>
  72 + <artifactId>spring-ai-moonshot-spring-boot-starter</artifactId>
  73 + <version>${spring-ai.version}</version>
  74 + </dependency>
66 75
67 <!-- 向量存储:https://db-engines.com/en/ranking/vector+dbms --> 76 <!-- 向量存储:https://db-engines.com/en/ranking/vector+dbms -->
68 <dependency> 77 <dependency>
69 <!-- Qdrant:https://qdrant.tech/ --> 78 <!-- Qdrant:https://qdrant.tech/ -->
70 - <groupId>${spring-ai.groupId}</groupId> 79 + <groupId>org.springframework.ai</groupId>
71 <artifactId>spring-ai-qdrant-store</artifactId> 80 <artifactId>spring-ai-qdrant-store</artifactId>
72 <version>${spring-ai.version}</version> 81 <version>${spring-ai.version}</version>
73 </dependency> 82 </dependency>
74 83
75 <dependency> 84 <dependency>
76 <!-- Redis:https://redis.io/docs/latest/develop/get-started/vector-database/ --> 85 <!-- Redis:https://redis.io/docs/latest/develop/get-started/vector-database/ -->
77 - <groupId>${spring-ai.groupId}</groupId> 86 + <groupId>org.springframework.ai</groupId>
78 <artifactId>spring-ai-redis-store</artifactId> 87 <artifactId>spring-ai-redis-store</artifactId>
79 <version>${spring-ai.version}</version> 88 <version>${spring-ai.version}</version>
80 </dependency> 89 </dependency>
@@ -92,7 +101,7 @@ @@ -92,7 +101,7 @@
92 101
93 <dependency> 102 <dependency>
94 <!-- Tika:负责内容的解析 --> 103 <!-- Tika:负责内容的解析 -->
95 - <groupId>${spring-ai.groupId}</groupId> 104 + <groupId>org.springframework.ai</groupId>
96 <artifactId>spring-ai-tika-document-reader</artifactId> 105 <artifactId>spring-ai-tika-document-reader</artifactId>
97 <version>${spring-ai.version}</version> 106 <version>${spring-ai.version}</version>
98 <!-- TODO 芋艿:boot 项目里,不引入 cloud 依赖!!!另外,这样也是为了解决启动报错的问题! --> 107 <!-- TODO 芋艿:boot 项目里,不引入 cloud 依赖!!!另外,这样也是为了解决启动报错的问题! -->
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/enums/AiPlatformEnum.java
@@ -25,6 +25,8 @@ public enum AiPlatformEnum implements ArrayValuable&lt;String&gt; { @@ -25,6 +25,8 @@ public enum AiPlatformEnum implements ArrayValuable&lt;String&gt; {
25 DOU_BAO("DouBao", "豆包"), // 字节 25 DOU_BAO("DouBao", "豆包"), // 字节
26 HUN_YUAN("HunYuan", "混元"), // 腾讯 26 HUN_YUAN("HunYuan", "混元"), // 腾讯
27 SILICON_FLOW("SiliconFlow", "硅基流动"), // 硅基流动 27 SILICON_FLOW("SiliconFlow", "硅基流动"), // 硅基流动
  28 + MINI_MAX("MiniMax", "MiniMax"), // 稀宇科技
  29 + MOONSHOT("Moonshot", "月之暗灭"), // KIMI
28 30
29 // ========== 国外平台 ========== 31 // ========== 国外平台 ==========
30 32
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiModelFactoryImpl.java
@@ -36,6 +36,8 @@ import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiAutoConfigur @@ -36,6 +36,8 @@ import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiAutoConfigur
36 import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiChatProperties; 36 import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiChatProperties;
37 import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiConnectionProperties; 37 import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiConnectionProperties;
38 import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiEmbeddingProperties; 38 import org.springframework.ai.autoconfigure.azure.openai.AzureOpenAiEmbeddingProperties;
  39 +import org.springframework.ai.autoconfigure.minimax.MiniMaxAutoConfiguration;
  40 +import org.springframework.ai.autoconfigure.moonshot.MoonshotAutoConfiguration;
39 import org.springframework.ai.autoconfigure.ollama.OllamaAutoConfiguration; 41 import org.springframework.ai.autoconfigure.ollama.OllamaAutoConfiguration;
40 import org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration; 42 import org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration;
41 import org.springframework.ai.autoconfigure.qianfan.QianFanAutoConfiguration; 43 import org.springframework.ai.autoconfigure.qianfan.QianFanAutoConfiguration;
@@ -48,7 +50,6 @@ import org.springframework.ai.autoconfigure.vectorstore.qdrant.QdrantVectorStore @@ -48,7 +50,6 @@ import org.springframework.ai.autoconfigure.vectorstore.qdrant.QdrantVectorStore
48 import org.springframework.ai.autoconfigure.vectorstore.redis.RedisVectorStoreAutoConfiguration; 50 import org.springframework.ai.autoconfigure.vectorstore.redis.RedisVectorStoreAutoConfiguration;
49 import org.springframework.ai.autoconfigure.vectorstore.redis.RedisVectorStoreProperties; 51 import org.springframework.ai.autoconfigure.vectorstore.redis.RedisVectorStoreProperties;
50 import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiAutoConfiguration; 52 import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiAutoConfiguration;
51 -import org.springframework.ai.autoconfigure.zhipuai.ZhiPuAiConnectionProperties;  
52 import org.springframework.ai.azure.openai.AzureOpenAiChatModel; 53 import org.springframework.ai.azure.openai.AzureOpenAiChatModel;
53 import org.springframework.ai.azure.openai.AzureOpenAiEmbeddingModel; 54 import org.springframework.ai.azure.openai.AzureOpenAiEmbeddingModel;
54 import org.springframework.ai.chat.model.ChatModel; 55 import org.springframework.ai.chat.model.ChatModel;
@@ -56,6 +57,12 @@ import org.springframework.ai.document.MetadataMode; @@ -56,6 +57,12 @@ import org.springframework.ai.document.MetadataMode;
56 import org.springframework.ai.embedding.BatchingStrategy; 57 import org.springframework.ai.embedding.BatchingStrategy;
57 import org.springframework.ai.embedding.EmbeddingModel; 58 import org.springframework.ai.embedding.EmbeddingModel;
58 import org.springframework.ai.image.ImageModel; 59 import org.springframework.ai.image.ImageModel;
  60 +import org.springframework.ai.minimax.MiniMaxChatModel;
  61 +import org.springframework.ai.minimax.MiniMaxEmbeddingModel;
  62 +import org.springframework.ai.minimax.MiniMaxEmbeddingOptions;
  63 +import org.springframework.ai.minimax.api.MiniMaxApi;
  64 +import org.springframework.ai.moonshot.MoonshotChatModel;
  65 +import org.springframework.ai.moonshot.api.MoonshotApi;
59 import org.springframework.ai.ollama.OllamaChatModel; 66 import org.springframework.ai.ollama.OllamaChatModel;
60 import org.springframework.ai.ollama.OllamaEmbeddingModel; 67 import org.springframework.ai.ollama.OllamaEmbeddingModel;
61 import org.springframework.ai.ollama.api.OllamaApi; 68 import org.springframework.ai.ollama.api.OllamaApi;
@@ -130,6 +137,10 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -130,6 +137,10 @@ public class AiModelFactoryImpl implements AiModelFactory {
130 return buildSiliconFlowChatModel(apiKey); 137 return buildSiliconFlowChatModel(apiKey);
131 case ZHI_PU: 138 case ZHI_PU:
132 return buildZhiPuChatModel(apiKey, url); 139 return buildZhiPuChatModel(apiKey, url);
  140 + case MINI_MAX:
  141 + return buildMiniMaxChatModel(apiKey, url);
  142 + case MOONSHOT:
  143 + return buildMoonshotChatModel(apiKey, url);
133 case XING_HUO: 144 case XING_HUO:
134 return buildXingHuoChatModel(apiKey); 145 return buildXingHuoChatModel(apiKey);
135 case OPENAI: 146 case OPENAI:
@@ -162,6 +173,10 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -162,6 +173,10 @@ public class AiModelFactoryImpl implements AiModelFactory {
162 return SpringUtil.getBean(SiliconFlowChatModel.class); 173 return SpringUtil.getBean(SiliconFlowChatModel.class);
163 case ZHI_PU: 174 case ZHI_PU:
164 return SpringUtil.getBean(ZhiPuAiChatModel.class); 175 return SpringUtil.getBean(ZhiPuAiChatModel.class);
  176 + case MINI_MAX:
  177 + return SpringUtil.getBean(MiniMaxChatModel.class);
  178 + case MOONSHOT:
  179 + return SpringUtil.getBean(MoonshotChatModel.class);
165 case XING_HUO: 180 case XING_HUO:
166 return SpringUtil.getBean(XingHuoChatModel.class); 181 return SpringUtil.getBean(XingHuoChatModel.class);
167 case OPENAI: 182 case OPENAI:
@@ -242,6 +257,8 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -242,6 +257,8 @@ public class AiModelFactoryImpl implements AiModelFactory {
242 return buildYiYanEmbeddingModel(apiKey, model); 257 return buildYiYanEmbeddingModel(apiKey, model);
243 case ZHI_PU: 258 case ZHI_PU:
244 return buildZhiPuEmbeddingModel(apiKey, url, model); 259 return buildZhiPuEmbeddingModel(apiKey, url, model);
  260 + case MINI_MAX:
  261 + return buildMiniMaxEmbeddingModel(apiKey, url, model);
245 case OPENAI: 262 case OPENAI:
246 return buildOpenAiEmbeddingModel(apiKey, url, model); 263 return buildOpenAiEmbeddingModel(apiKey, url, model);
247 case AZURE_OPENAI: 264 case AZURE_OPENAI:
@@ -365,8 +382,8 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -365,8 +382,8 @@ public class AiModelFactoryImpl implements AiModelFactory {
365 * 可参考 {@link ZhiPuAiAutoConfiguration} 的 zhiPuAiChatModel 方法 382 * 可参考 {@link ZhiPuAiAutoConfiguration} 的 zhiPuAiChatModel 方法
366 */ 383 */
367 private ZhiPuAiChatModel buildZhiPuChatModel(String apiKey, String url) { 384 private ZhiPuAiChatModel buildZhiPuChatModel(String apiKey, String url) {
368 - url = StrUtil.blankToDefault(url, ZhiPuAiConnectionProperties.DEFAULT_BASE_URL);  
369 - ZhiPuAiApi zhiPuAiApi = new ZhiPuAiApi(url, apiKey); 385 + ZhiPuAiApi zhiPuAiApi = StrUtil.isEmpty(url) ? new ZhiPuAiApi(apiKey)
  386 + : new ZhiPuAiApi(url, apiKey);
370 return new ZhiPuAiChatModel(zhiPuAiApi); 387 return new ZhiPuAiChatModel(zhiPuAiApi);
371 } 388 }
372 389
@@ -374,12 +391,30 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -374,12 +391,30 @@ public class AiModelFactoryImpl implements AiModelFactory {
374 * 可参考 {@link ZhiPuAiAutoConfiguration} 的 zhiPuAiImageModel 方法 391 * 可参考 {@link ZhiPuAiAutoConfiguration} 的 zhiPuAiImageModel 方法
375 */ 392 */
376 private ZhiPuAiImageModel buildZhiPuAiImageModel(String apiKey, String url) { 393 private ZhiPuAiImageModel buildZhiPuAiImageModel(String apiKey, String url) {
377 - url = StrUtil.blankToDefault(url, ZhiPuAiConnectionProperties.DEFAULT_BASE_URL);  
378 - ZhiPuAiImageApi zhiPuAiApi = new ZhiPuAiImageApi(url, apiKey, RestClient.builder()); 394 + ZhiPuAiImageApi zhiPuAiApi = StrUtil.isEmpty(url) ? new ZhiPuAiImageApi(apiKey)
  395 + : new ZhiPuAiImageApi(url, apiKey, RestClient.builder());
379 return new ZhiPuAiImageModel(zhiPuAiApi); 396 return new ZhiPuAiImageModel(zhiPuAiApi);
380 } 397 }
381 398
382 /** 399 /**
  400 + * 可参考 {@link MiniMaxAutoConfiguration} 的 miniMaxChatModel 方法
  401 + */
  402 + private MiniMaxChatModel buildMiniMaxChatModel(String apiKey, String url) {
  403 + MiniMaxApi miniMaxApi = StrUtil.isEmpty(url) ? new MiniMaxApi(apiKey)
  404 + : new MiniMaxApi(url, apiKey);
  405 + return new MiniMaxChatModel(miniMaxApi);
  406 + }
  407 +
  408 + /**
  409 + * 可参考 {@link MoonshotAutoConfiguration} 的 moonshotChatModel 方法
  410 + */
  411 + private MoonshotChatModel buildMoonshotChatModel(String apiKey, String url) {
  412 + MoonshotApi moonshotApi = StrUtil.isEmpty(url)? new MoonshotApi(apiKey)
  413 + : new MoonshotApi(url, apiKey);
  414 + return new MoonshotChatModel(moonshotApi);
  415 + }
  416 +
  417 + /**
383 * 可参考 {@link YudaoAiAutoConfiguration#xingHuoChatClient(YudaoAiProperties)} 418 * 可参考 {@link YudaoAiAutoConfiguration#xingHuoChatClient(YudaoAiProperties)}
384 */ 419 */
385 private static XingHuoChatModel buildXingHuoChatModel(String key) { 420 private static XingHuoChatModel buildXingHuoChatModel(String key) {
@@ -454,13 +489,23 @@ public class AiModelFactoryImpl implements AiModelFactory { @@ -454,13 +489,23 @@ public class AiModelFactoryImpl implements AiModelFactory {
454 * 可参考 {@link ZhiPuAiAutoConfiguration} 的 zhiPuAiEmbeddingModel 方法 489 * 可参考 {@link ZhiPuAiAutoConfiguration} 的 zhiPuAiEmbeddingModel 方法
455 */ 490 */
456 private ZhiPuAiEmbeddingModel buildZhiPuEmbeddingModel(String apiKey, String url, String model) { 491 private ZhiPuAiEmbeddingModel buildZhiPuEmbeddingModel(String apiKey, String url, String model) {
457 - url = StrUtil.blankToDefault(url, ZhiPuAiConnectionProperties.DEFAULT_BASE_URL);  
458 - ZhiPuAiApi zhiPuAiApi = new ZhiPuAiApi(url, apiKey); 492 + ZhiPuAiApi zhiPuAiApi = StrUtil.isEmpty(url) ? new ZhiPuAiApi(apiKey)
  493 + : new ZhiPuAiApi(url, apiKey);
459 ZhiPuAiEmbeddingOptions zhiPuAiEmbeddingOptions = ZhiPuAiEmbeddingOptions.builder().model(model).build(); 494 ZhiPuAiEmbeddingOptions zhiPuAiEmbeddingOptions = ZhiPuAiEmbeddingOptions.builder().model(model).build();
460 return new ZhiPuAiEmbeddingModel(zhiPuAiApi, MetadataMode.EMBED, zhiPuAiEmbeddingOptions); 495 return new ZhiPuAiEmbeddingModel(zhiPuAiApi, MetadataMode.EMBED, zhiPuAiEmbeddingOptions);
461 } 496 }
462 497
463 /** 498 /**
  499 + * 可参考 {@link MiniMaxAutoConfiguration} 的 miniMaxEmbeddingModel 方法
  500 + */
  501 + private EmbeddingModel buildMiniMaxEmbeddingModel(String apiKey, String url, String model) {
  502 + MiniMaxApi miniMaxApi = StrUtil.isEmpty(url)? new MiniMaxApi(apiKey)
  503 + : new MiniMaxApi(url, apiKey);
  504 + MiniMaxEmbeddingOptions miniMaxEmbeddingOptions = MiniMaxEmbeddingOptions.builder().model(model).build();
  505 + return new MiniMaxEmbeddingModel(miniMaxApi, MetadataMode.EMBED, miniMaxEmbeddingOptions);
  506 + }
  507 +
  508 + /**
464 * 可参考 {@link QianFanAutoConfiguration} 的 qianFanEmbeddingModel 方法 509 * 可参考 {@link QianFanAutoConfiguration} 的 qianFanEmbeddingModel 方法
465 */ 510 */
466 private QianFanEmbeddingModel buildYiYanEmbeddingModel(String key, String model) { 511 private QianFanEmbeddingModel buildYiYanEmbeddingModel(String key, String model) {
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/util/AiUtils.java
@@ -6,6 +6,8 @@ import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions; @@ -6,6 +6,8 @@ import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
6 import org.springframework.ai.azure.openai.AzureOpenAiChatOptions; 6 import org.springframework.ai.azure.openai.AzureOpenAiChatOptions;
7 import org.springframework.ai.chat.messages.*; 7 import org.springframework.ai.chat.messages.*;
8 import org.springframework.ai.chat.prompt.ChatOptions; 8 import org.springframework.ai.chat.prompt.ChatOptions;
  9 +import org.springframework.ai.minimax.MiniMaxChatOptions;
  10 +import org.springframework.ai.moonshot.MoonshotChatOptions;
9 import org.springframework.ai.ollama.api.OllamaOptions; 11 import org.springframework.ai.ollama.api.OllamaOptions;
10 import org.springframework.ai.openai.OpenAiChatOptions; 12 import org.springframework.ai.openai.OpenAiChatOptions;
11 import org.springframework.ai.qianfan.QianFanChatOptions; 13 import org.springframework.ai.qianfan.QianFanChatOptions;
@@ -27,6 +29,10 @@ public class AiUtils { @@ -27,6 +29,10 @@ public class AiUtils {
27 return QianFanChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens).build(); 29 return QianFanChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens).build();
28 case ZHI_PU: 30 case ZHI_PU:
29 return ZhiPuAiChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens).build(); 31 return ZhiPuAiChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens).build();
  32 + case MINI_MAX:
  33 + return MiniMaxChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens).build();
  34 + case MOONSHOT:
  35 + return MoonshotChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens).build();
30 case OPENAI: 36 case OPENAI:
31 case DEEP_SEEK: // 复用 OpenAI 客户端 37 case DEEP_SEEK: // 复用 OpenAI 客户端
32 case DOU_BAO: // 复用 OpenAI 客户端 38 case DOU_BAO: // 复用 OpenAI 客户端
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/MiniMaxChatModelTests.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.ai.chat;
  2 +
  3 +import org.junit.jupiter.api.Disabled;
  4 +import org.junit.jupiter.api.Test;
  5 +import org.springframework.ai.chat.messages.Message;
  6 +import org.springframework.ai.chat.messages.SystemMessage;
  7 +import org.springframework.ai.chat.messages.UserMessage;
  8 +import org.springframework.ai.chat.model.ChatResponse;
  9 +import org.springframework.ai.chat.prompt.Prompt;
  10 +import org.springframework.ai.minimax.MiniMaxChatModel;
  11 +import org.springframework.ai.minimax.MiniMaxChatOptions;
  12 +import org.springframework.ai.minimax.api.MiniMaxApi;
  13 +import reactor.core.publisher.Flux;
  14 +
  15 +import java.util.ArrayList;
  16 +import java.util.List;
  17 +
  18 +/**
  19 + * {@link MiniMaxChatModel} 的集成测试
  20 + *
  21 + * @author 芋道源码
  22 + */
  23 +public class MiniMaxChatModelTests {
  24 +
  25 + private final MiniMaxChatModel chatModel = new MiniMaxChatModel(
  26 + new MiniMaxApi("eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJHcm91cE5hbWUiOiLnjovmlofmlowiLCJVc2VyTmFtZSI6IueOi-aWh-aWjCIsIkFjY291bnQiOiIiLCJTdWJqZWN0SUQiOiIxODk3Mjg3MjQ5NDU2ODA4MzQ2IiwiUGhvbmUiOiIxNTYwMTY5MTM5OSIsIkdyb3VwSUQiOiIxODk3Mjg3MjQ5NDQ4NDE5NzM4IiwiUGFnZU5hbWUiOiIiLCJNYWlsIjoiIiwiQ3JlYXRlVGltZSI6IjIwMjUtMDMtMTEgMTI6NTI6MDIiLCJUb2tlblR5cGUiOjEsImlzcyI6Im1pbmltYXgifQ.aAuB7gWW_oA4IYhh-CF7c9MfWWxKN49B_HK-DYjXaDwwffhiG-H1571z1WQhp9QytWG-DqgLejneeSxkiq1wQIe3FsEP2wz4BmGBct31LehbJu8ehLxg_vg75Uod1nFAHbm5mZz6JSVLNIlSo87Xr3UtSzJhAXlapEkcqlA4YOzOpKrZ8l5_OJPTORTCmHWZYgJcRS-faNiH62ZnUEHUozesTFhubJHo5GfJCw_edlnmfSUocERV1BjWvenhZ9My-aYXNktcW9WaSj9l6gayV7A0Ium_PL55T9ln1PcI8gayiVUKJGJDoqNyF1AF9_aF9NOKtTnQzwNqnZdlTYH6hw"), // 密钥
  27 + MiniMaxChatOptions.builder()
  28 + .model(MiniMaxApi.ChatModel.ABAB_6_5_G_Chat.getValue()) // 模型
  29 + .build());
  30 + @Test
  31 + @Disabled
  32 + public void testCall() {
  33 + // 准备参数
  34 + List<Message> messages = new ArrayList<>();
  35 + messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
  36 + messages.add(new UserMessage("1 + 1 = ?"));
  37 +
  38 + // 调用
  39 + ChatResponse response = chatModel.call(new Prompt(messages));
  40 + // 打印结果
  41 + System.out.println(response);
  42 + System.out.println(response.getResult().getOutput());
  43 + }
  44 +
  45 + @Test
  46 + @Disabled
  47 + public void testStream() {
  48 + // 准备参数
  49 + List<Message> messages = new ArrayList<>();
  50 + messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
  51 + messages.add(new UserMessage("1 + 1 = ?"));
  52 +
  53 + // 调用
  54 + Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages));
  55 + // 打印结果
  56 + flux.doOnNext(response -> {
  57 +// System.out.println(response);
  58 + System.out.println(response.getResult().getOutput());
  59 + }).then().block();
  60 + }
  61 +
  62 +}
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/MoonshotChatModelTests.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.ai.chat;
  2 +
  3 +import org.junit.jupiter.api.Disabled;
  4 +import org.junit.jupiter.api.Test;
  5 +import org.springframework.ai.chat.messages.Message;
  6 +import org.springframework.ai.chat.messages.SystemMessage;
  7 +import org.springframework.ai.chat.messages.UserMessage;
  8 +import org.springframework.ai.chat.model.ChatResponse;
  9 +import org.springframework.ai.chat.prompt.Prompt;
  10 +import org.springframework.ai.moonshot.MoonshotChatModel;
  11 +import org.springframework.ai.moonshot.MoonshotChatOptions;
  12 +import org.springframework.ai.moonshot.api.MoonshotApi;
  13 +import reactor.core.publisher.Flux;
  14 +
  15 +import java.util.ArrayList;
  16 +import java.util.List;
  17 +
  18 +/**
  19 + * {@link org.springframework.ai.moonshot.MoonshotChatModel} 的集成测试
  20 + *
  21 + * @author 芋道源码
  22 + */
  23 +public class MoonshotChatModelTests {
  24 +
  25 + private final MoonshotChatModel chatModel = new MoonshotChatModel(
  26 + new MoonshotApi("sk-aHYYV1SARscItye5QQRRNbXij4fy65Ee7pNZlC9gsSQnUKXA"), // 密钥
  27 + MoonshotChatOptions.builder()
  28 + .model("moonshot-v1-8k") // 模型
  29 + .build());
  30 + @Test
  31 + @Disabled
  32 + public void testCall() {
  33 + // 准备参数
  34 + List<Message> messages = new ArrayList<>();
  35 + messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
  36 + messages.add(new UserMessage("1 + 1 = ?"));
  37 +
  38 + // 调用
  39 + ChatResponse response = chatModel.call(new Prompt(messages));
  40 + // 打印结果
  41 + System.out.println(response);
  42 + System.out.println(response.getResult().getOutput());
  43 + }
  44 +
  45 + @Test
  46 + @Disabled
  47 + public void testStream() {
  48 + // 准备参数
  49 + List<Message> messages = new ArrayList<>();
  50 + messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
  51 + messages.add(new UserMessage("1 + 1 = ?"));
  52 +
  53 + // 调用
  54 + Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages));
  55 + // 打印结果
  56 + flux.doOnNext(response -> {
  57 +// System.out.println(response);
  58 + System.out.println(response.getResult().getOutput());
  59 + }).then().block();
  60 + }
  61 +
  62 +}
yudao-server/src/main/resources/application.yaml
@@ -184,6 +184,10 @@ spring: @@ -184,6 +184,10 @@ spring:
184 api-key: sk-e53UqbboF8QJCscYvzJscJxJXoFcFg4iJjl1oqgE7baJETmx 184 api-key: sk-e53UqbboF8QJCscYvzJscJxJXoFcFg4iJjl1oqgE7baJETmx
185 dashscope: # 通义千问 185 dashscope: # 通义千问
186 api-key: sk-71800982914041848008480000000000 186 api-key: sk-71800982914041848008480000000000
  187 + minimax: # Minimax:https://www.minimaxi.com/
  188 + api-key: xxxx
  189 + moonshot: # 月之暗灭(KIMI)
  190 + api-key: sk-abc
187 191
188 yudao: 192 yudao:
189 ai: 193 ai: