Commit 59c853b54d3f5ca4f32e0ca82114b777850b7ed1

Authored by YunaiV
1 parent 4daff933

【代码优化】AI:完善 DeepSeekChatTests、XingHuoChatModelTests 单测,方便大家快速体验

Showing 10 changed files with 70 additions and 63 deletions
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java
... ... @@ -2,11 +2,11 @@ package cn.iocoder.yudao.framework.ai.config;
2 2  
3 3 import cn.iocoder.yudao.framework.ai.core.factory.AiModelFactory;
4 4 import cn.iocoder.yudao.framework.ai.core.factory.AiModelFactoryImpl;
5   -import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatClient;
  5 +import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatModel;
6 6 import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatOptions;
7 7 import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi;
8 8 import cn.iocoder.yudao.framework.ai.core.model.suno.api.SunoApi;
9   -import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatClient;
  9 +import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatModel;
10 10 import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatOptions;
11 11 import com.alibaba.cloud.ai.tongyi.TongYiAutoConfiguration;
12 12 import lombok.extern.slf4j.Slf4j;
... ... @@ -35,29 +35,29 @@ public class YudaoAiAutoConfiguration {
35 35 // ========== 各种 AI Client 创建 ==========
36 36  
37 37 @Bean
38   - @ConditionalOnProperty(value = "yudao.ai.xinghuo.enable", havingValue = "true")
39   - public XingHuoChatClient xingHuoChatClient(YudaoAiProperties yudaoAiProperties) {
40   - YudaoAiProperties.XingHuoProperties properties = yudaoAiProperties.getXinghuo();
41   - XingHuoChatOptions options = XingHuoChatOptions.builder()
  38 + @ConditionalOnProperty(value = "yudao.ai.deepseek.enable", havingValue = "true")
  39 + public DeepSeekChatModel deepSeekChatModel(YudaoAiProperties yudaoAiProperties) {
  40 + YudaoAiProperties.DeepSeekProperties properties = yudaoAiProperties.getDeepSeek();
  41 + DeepSeekChatOptions options = DeepSeekChatOptions.builder()
42 42 .model(properties.getModel())
43 43 .temperature(properties.getTemperature())
44 44 .maxTokens(properties.getMaxTokens())
45   - .topK(properties.getTopK())
  45 + .topP(properties.getTopP())
46 46 .build();
47   - return new XingHuoChatClient(properties.getAppKey(), properties.getSecretKey(), options);
  47 + return new DeepSeekChatModel(properties.getApiKey(), options);
48 48 }
49 49  
50 50 @Bean
51   - @ConditionalOnProperty(value = "yudao.ai.deepseek.enable", havingValue = "true")
52   - public DeepSeekChatClient deepSeekChatClient(YudaoAiProperties yudaoAiProperties) {
53   - YudaoAiProperties.DeepSeekProperties properties = yudaoAiProperties.getDeepSeek();
54   - DeepSeekChatOptions options = DeepSeekChatOptions.builder()
  51 + @ConditionalOnProperty(value = "yudao.ai.xinghuo.enable", havingValue = "true")
  52 + public XingHuoChatModel xingHuoChatClient(YudaoAiProperties yudaoAiProperties) {
  53 + YudaoAiProperties.XingHuoProperties properties = yudaoAiProperties.getXinghuo();
  54 + XingHuoChatOptions options = XingHuoChatOptions.builder()
55 55 .model(properties.getModel())
56 56 .temperature(properties.getTemperature())
57 57 .maxTokens(properties.getMaxTokens())
58   - .topP(properties.getTopP())
  58 + .topK(properties.getTopK())
59 59 .build();
60   - return new DeepSeekChatClient(properties.getApiKey(), options);
  60 + return new XingHuoChatModel(properties.getAppKey(), properties.getSecretKey(), options);
61 61 }
62 62  
63 63 @Bean
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiProperties.java
... ... @@ -14,14 +14,14 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
14 14 public class YudaoAiProperties {
15 15  
16 16 /**
17   - * 讯飞星火
  17 + * DeepSeek
18 18 */
19   - private XingHuoProperties xinghuo;
  19 + private DeepSeekProperties deepSeek;
20 20  
21 21 /**
22   - * DeepSeek
  22 + * 讯飞星火
23 23 */
24   - private DeepSeekProperties deepSeek;
  24 + private XingHuoProperties xinghuo;
25 25  
26 26 /**
27 27 * Midjourney 绘图
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiModelFactoryImpl.java
... ... @@ -9,10 +9,10 @@ import cn.hutool.extra.spring.SpringUtil;
9 9 import cn.iocoder.yudao.framework.ai.config.YudaoAiAutoConfiguration;
10 10 import cn.iocoder.yudao.framework.ai.config.YudaoAiProperties;
11 11 import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum;
12   -import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatClient;
  12 +import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatModel;
13 13 import cn.iocoder.yudao.framework.ai.core.model.midjourney.api.MidjourneyApi;
14 14 import cn.iocoder.yudao.framework.ai.core.model.suno.api.SunoApi;
15   -import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatClient;
  15 +import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatModel;
16 16 import com.alibaba.cloud.ai.tongyi.TongYiAutoConfiguration;
17 17 import com.alibaba.cloud.ai.tongyi.TongYiConnectionProperties;
18 18 import com.alibaba.cloud.ai.tongyi.chat.TongYiChatModel;
... ... @@ -59,10 +59,10 @@ public class AiModelFactoryImpl implements AiModelFactory {
59 59 return buildTongYiChatModel(apiKey);
60 60 case YI_YAN:
61 61 return buildYiYanChatModel(apiKey);
62   - case XING_HUO:
63   - return buildXingHuoChatClient(apiKey);
64 62 case DEEP_SEEK:
65   - return buildDeepSeekChatClient(apiKey);
  63 + return buildDeepSeekChatModel(apiKey);
  64 + case XING_HUO:
  65 + return buildXingHuoChatModel(apiKey);
66 66 case OPENAI:
67 67 return buildOpenAiChatModel(apiKey, url);
68 68 case OLLAMA:
... ... @@ -82,7 +82,7 @@ public class AiModelFactoryImpl implements AiModelFactory {
82 82 case YI_YAN:
83 83 return SpringUtil.getBean(QianFanChatModel.class);
84 84 case XING_HUO:
85   - return SpringUtil.getBean(XingHuoChatClient.class);
  85 + return SpringUtil.getBean(XingHuoChatModel.class);
86 86 case OPENAI:
87 87 return SpringUtil.getBean(OpenAiChatModel.class);
88 88 case OLLAMA:
... ... @@ -112,7 +112,7 @@ public class AiModelFactoryImpl implements AiModelFactory {
112 112 case OPENAI:
113 113 return buildOpenAiImageModel(apiKey, url);
114 114 case STABLE_DIFFUSION:
115   - return buildStabilityAiImageClient(apiKey, url);
  115 + return buildStabilityAiImageModel(apiKey, url);
116 116 default:
117 117 throw new IllegalArgumentException(StrUtil.format("未知平台({})", platform));
118 118 }
... ... @@ -169,6 +169,24 @@ public class AiModelFactoryImpl implements AiModelFactory {
169 169 }
170 170  
171 171 /**
  172 + * 可参考 {@link YudaoAiAutoConfiguration#deepSeekChatModel(YudaoAiProperties)}
  173 + */
  174 + private static DeepSeekChatModel buildDeepSeekChatModel(String apiKey) {
  175 + return new DeepSeekChatModel(apiKey);
  176 + }
  177 +
  178 + /**
  179 + * 可参考 {@link YudaoAiAutoConfiguration#xingHuoChatClient(YudaoAiProperties)}
  180 + */
  181 + private static XingHuoChatModel buildXingHuoChatModel(String key) {
  182 + List<String> keys = StrUtil.split(key, '|');
  183 + Assert.equals(keys.size(), 3, "XingHuoChatClient 的密钥需要 (appid|appKey|secretKey) 格式");
  184 + String appKey = keys.get(1);
  185 + String secretKey = keys.get(2);
  186 + return new XingHuoChatModel(appKey, secretKey);
  187 + }
  188 +
  189 + /**
172 190 * 可参考 {@link OpenAiAutoConfiguration}
173 191 */
174 192 private static OpenAiChatModel buildOpenAiChatModel(String openAiToken, String url) {
... ... @@ -194,22 +212,7 @@ public class AiModelFactoryImpl implements AiModelFactory {
194 212 return new OllamaChatModel(ollamaApi);
195 213 }
196 214  
197   - /**
198   - * 可参考 {@link YudaoAiAutoConfiguration#xingHuoChatClient(YudaoAiProperties)}
199   - */
200   - private static XingHuoChatClient buildXingHuoChatClient(String key) {
201   - List<String> keys = StrUtil.split(key, '|');
202   - Assert.equals(keys.size(), 3, "XingHuoChatClient 的密钥需要 (appid|appKey|secretKey) 格式");
203   - String appKey = keys.get(1);
204   - String secretKey = keys.get(2);
205   - return new XingHuoChatClient(appKey, secretKey);
206   - }
207   -
208   - private static DeepSeekChatClient buildDeepSeekChatClient(String apiKey) {
209   - return new DeepSeekChatClient(apiKey);
210   - }
211   -
212   - private StabilityAiImageModel buildStabilityAiImageClient(String apiKey, String url) {
  215 + private StabilityAiImageModel buildStabilityAiImageModel(String apiKey, String url) {
213 216 url = StrUtil.blankToDefault(url, StabilityAiApi.DEFAULT_BASE_URL);
214 217 StabilityAiApi stabilityAiApi = new StabilityAiApi(apiKey, StabilityAiApi.DEFAULT_IMAGE_MODEL, url);
215 218 return new StabilityAiImageModel(stabilityAiApi);
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/deepseek/DeepSeekChatClient.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/deepseek/DeepSeekChatModel.java
... ... @@ -29,7 +29,7 @@ import static cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatOpti
29 29 * @author fansili
30 30 */
31 31 @Slf4j
32   -public class DeepSeekChatClient implements ChatModel {
  32 +public class DeepSeekChatModel implements ChatModel {
33 33  
34 34 private static final String BASE_URL = "https://api.deepseek.com";
35 35  
... ... @@ -43,15 +43,15 @@ public class DeepSeekChatClient implements ChatModel {
43 43 */
44 44 private final OpenAiApi openAiApi;
45 45  
46   - public DeepSeekChatClient(String apiKey) {
  46 + public DeepSeekChatModel(String apiKey) {
47 47 this(apiKey, DeepSeekChatOptions.builder().model(MODEL_DEFAULT).temperature(0.7F).build());
48 48 }
49 49  
50   - public DeepSeekChatClient(String apiKey, DeepSeekChatOptions options) {
  50 + public DeepSeekChatModel(String apiKey, DeepSeekChatOptions options) {
51 51 this(apiKey, options, RetryUtils.DEFAULT_RETRY_TEMPLATE);
52 52 }
53 53  
54   - public DeepSeekChatClient(String apiKey, DeepSeekChatOptions options, RetryTemplate retryTemplate) {
  54 + public DeepSeekChatModel(String apiKey, DeepSeekChatOptions options, RetryTemplate retryTemplate) {
55 55 Assert.notEmpty(apiKey, "apiKey 不能为空");
56 56 Assert.notNull(options, "options 不能为空");
57 57 Assert.notNull(retryTemplate, "retryTemplate 不能为空");
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/xinghuo/XingHuoChatClient.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/xinghuo/XingHuoChatModel.java
... ... @@ -29,7 +29,7 @@ import static cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatOption
29 29 * @author fansili
30 30 */
31 31 @Slf4j
32   -public class XingHuoChatClient implements ChatModel {
  32 +public class XingHuoChatModel implements ChatModel {
33 33  
34 34 private static final String BASE_URL = "https://spark-api-open.xf-yun.com";
35 35  
... ... @@ -43,16 +43,16 @@ public class XingHuoChatClient implements ChatModel {
43 43 */
44 44 private final OpenAiApi openAiApi;
45 45  
46   - public XingHuoChatClient(String apiKey, String secretKey) {
  46 + public XingHuoChatModel(String apiKey, String secretKey) {
47 47 this(apiKey, secretKey,
48 48 XingHuoChatOptions.builder().model(MODEL_DEFAULT).temperature(0.7F).build());
49 49 }
50 50  
51   - public XingHuoChatClient(String apiKey, String secretKey, XingHuoChatOptions options) {
  51 + public XingHuoChatModel(String apiKey, String secretKey, XingHuoChatOptions options) {
52 52 this(apiKey, secretKey, options, RetryUtils.DEFAULT_RETRY_TEMPLATE);
53 53 }
54 54  
55   - public XingHuoChatClient(String apiKey, String secretKey, XingHuoChatOptions options, RetryTemplate retryTemplate) {
  55 + public XingHuoChatModel(String apiKey, String secretKey, XingHuoChatOptions options, RetryTemplate retryTemplate) {
56 56 Assert.notEmpty(apiKey, "apiKey 不能为空");
57 57 Assert.notEmpty(secretKey, "secretKey 不能为空");
58 58 Assert.notNull(options, "options 不能为空");
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/DeepSeekChatTests.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/DeepSeekChatModelTests.java
1 1 package cn.iocoder.yudao.framework.ai.chat;
2 2  
3   -import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatClient;
  3 +import cn.iocoder.yudao.framework.ai.core.model.deepseek.DeepSeekChatModel;
4 4 import org.junit.jupiter.api.Test;
5 5 import org.springframework.ai.chat.messages.Message;
6 6 import org.springframework.ai.chat.messages.SystemMessage;
... ... @@ -13,13 +13,13 @@ import java.util.ArrayList;
13 13 import java.util.List;
14 14  
15 15 /**
16   - * {@link DeepSeekChatClient} 集成测试
  16 + * {@link DeepSeekChatModel} 集成测试
17 17 *
18 18 * @author 芋道源码
19 19 */
20   -public class DeepSeekChatTests {
  20 +public class DeepSeekChatModelTests {
21 21  
22   - private final DeepSeekChatClient chatModel = new DeepSeekChatClient("sk-e94db327cc7d457d99a8de8810fc6b12");
  22 + private final DeepSeekChatModel chatModel = new DeepSeekChatModel("sk-e94db327cc7d457d99a8de8810fc6b12");
23 23  
24 24 @Test
25 25 public void testCall() {
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/OpenAIChatModelTests.java
1 1 package cn.iocoder.yudao.framework.ai.chat;
2 2  
3   -import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatClient;
  3 +import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatModel;
4 4 import org.junit.jupiter.api.Disabled;
5 5 import org.junit.jupiter.api.Test;
6 6 import org.springframework.ai.chat.messages.Message;
... ... @@ -17,7 +17,7 @@ import java.util.ArrayList;
17 17 import java.util.List;
18 18  
19 19 /**
20   - * {@link XingHuoChatClient} 集成测试
  20 + * {@link XingHuoChatModel} 集成测试
21 21 *
22 22 * @author 芋道源码
23 23 */
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/XingHuoChatClientTests.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/XingHuoChatModelTests.java
1 1 package cn.iocoder.yudao.framework.ai.chat;
2 2  
3   -import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatClient;
  3 +import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatModel;
4 4 import org.junit.jupiter.api.Test;
5 5 import org.springframework.ai.chat.messages.Message;
6 6 import org.springframework.ai.chat.messages.SystemMessage;
... ... @@ -13,13 +13,13 @@ import java.util.ArrayList;
13 13 import java.util.List;
14 14  
15 15 /**
16   - * {@link XingHuoChatClient} 集成测试
  16 + * {@link XingHuoChatModel} 集成测试
17 17 *
18 18 * @author fansili
19 19 */
20   -public class XingHuoChatClientTests {
  20 +public class XingHuoChatModelTests {
21 21  
22   - private final XingHuoChatClient chatModel = new XingHuoChatClient(
  22 + private final XingHuoChatModel chatModel = new XingHuoChatModel(
23 23 "cb6415c19d6162cda07b47316fcb0416",
24 24 "Y2JiYTIxZjA3MDMxMjNjZjQzYzVmNzdh");
25 25  
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/YiYanChatTests.java renamed to yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/YiYanChatModelTests.java
... ... @@ -19,7 +19,7 @@ import java.util.List;
19 19 *
20 20 * @author fansili
21 21 */
22   -public class YiYanChatTests {
  22 +public class YiYanChatModelTests {
23 23  
24 24 private final QianFanApi qianFanApi = new QianFanApi(
25 25 "qS8k8dYr2nXunagK4SSU8Xjj",
... ...
yudao-server/src/main/resources/application.yaml
... ... @@ -153,6 +153,9 @@ spring:
153 153  
154 154 spring:
155 155 ai:
  156 + qianfan: # 文心一言
  157 + api-key: x0cuLZ7XsaTCU08vuJWO87Lg
  158 + secret-key: R9mYF9dl9KASgi5RUq0FQt3wRisSnOcK
156 159 ollama:
157 160 base-url: http://127.0.0.1:11434
158 161 chat:
... ... @@ -162,9 +165,6 @@ spring:
162 165 base-url: https://api.gptsapi.net
163 166 stabilityai:
164 167 api-key: sk-e53UqbboF8QJCscYvzJscJxJXoFcFg4iJjl1oqgE7baJETmx
165   - qianfan: # 文心一言
166   - api-key: x0cuLZ7XsaTCU08vuJWO87Lg
167   - secret-key: R9mYF9dl9KASgi5RUq0FQt3wRisSnOcK
168 168 cloud:
169 169 ai:
170 170 tongyi: # 通义千问
... ... @@ -173,6 +173,10 @@ spring:
173 173  
174 174 yudao:
175 175 ai:
  176 + deep-seek:
  177 + enable: true
  178 + api-key: sk-e94db327cc7d457d99a8de8810fc6b12
  179 + model: deepseek-chat
176 180 xinghuo:
177 181 enable: true
178 182 appId: 13c8cca6
... ...