Commit 4f11d00cfd5d344c8b06c6f733a09b04c39b7016

Authored by YunaiV
1 parent 0139317a

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

yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/enums/AiPlatformEnum.java
... ... @@ -14,8 +14,8 @@ public enum AiPlatformEnum {
14 14  
15 15 // ========== 国内平台 ==========
16 16  
  17 + TONG_YI("TongYi", "通义千问"), // 阿里
17 18 YI_YAN("YiYan", "文心一言"), // 百度
18   - QIAN_WEN("QianWen", "千问"), // 阿里
19 19 DEEP_SEEK("DeepSeek", "DeepSeek"), // DeepSeek
20 20 XING_HUO("XingHuo", "星火"), // 讯飞
21 21  
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiModelFactoryImpl.java
... ... @@ -55,12 +55,12 @@ public class AiModelFactoryImpl implements AiModelFactory {
55 55 return Singleton.get(cacheKey, (Func0<ChatModel>) () -> {
56 56 //noinspection EnhancedSwitchMigration
57 57 switch (platform) {
  58 + case TONG_YI:
  59 + return buildTongYiChatModel(apiKey);
58 60 case YI_YAN:
59 61 return buildYiYanChatClient(apiKey);
60 62 case XING_HUO:
61 63 return buildXingHuoChatClient(apiKey);
62   - case QIAN_WEN:
63   - return buildQianWenChatClient(apiKey);
64 64 case DEEP_SEEK:
65 65 return buildDeepSeekChatClient(apiKey);
66 66 case OPENAI:
... ... @@ -77,16 +77,16 @@ public class AiModelFactoryImpl implements AiModelFactory {
77 77 public ChatModel getDefaultChatModel(AiPlatformEnum platform) {
78 78 //noinspection EnhancedSwitchMigration
79 79 switch (platform) {
80   - case OLLAMA:
81   - return SpringUtil.getBean(OllamaChatModel.class);
  80 + case TONG_YI:
  81 + return SpringUtil.getBean(TongYiChatModel.class);
82 82 case YI_YAN:
83 83 return SpringUtil.getBean(QianFanChatModel.class);
84 84 case XING_HUO:
85 85 return SpringUtil.getBean(XingHuoChatClient.class);
86   - case QIAN_WEN:
87   - return SpringUtil.getBean(TongYiChatModel.class);
88 86 case OPENAI:
89 87 return SpringUtil.getBean(OpenAiChatModel.class);
  88 + case OLLAMA:
  89 + return SpringUtil.getBean(OllamaChatModel.class);
90 90 default:
91 91 throw new IllegalArgumentException(StrUtil.format("未知平台({})", platform));
92 92 }
... ... @@ -143,6 +143,20 @@ public class AiModelFactoryImpl implements AiModelFactory {
143 143 // ========== 各种创建 spring-ai 客户端的方法 ==========
144 144  
145 145 /**
  146 + * 可参考 {@link TongYiAutoConfiguration#tongYiChatClient(Generation, TongYiChatProperties, TongYiConnectionProperties)}
  147 + */
  148 + private static TongYiChatModel buildTongYiChatModel(String key) {
  149 + com.alibaba.dashscope.aigc.generation.Generation generation = SpringUtil.getBean(Generation.class);
  150 + TongYiChatProperties chatOptions = SpringUtil.getBean(TongYiChatProperties.class);
  151 + // TODO @芋艿:貌似 apiKey 是全局唯一的???得测试下
  152 + // TODO @芋艿:貌似阿里云不是增量返回的
  153 + // 该 issue 进行跟进中 https://github.com/alibaba/spring-cloud-alibaba/issues/3790
  154 + TongYiConnectionProperties connectionProperties = new TongYiConnectionProperties();
  155 + connectionProperties.setApiKey(key);
  156 + return new TongYiAutoConfiguration().tongYiChatClient(generation, chatOptions, connectionProperties);
  157 + }
  158 +
  159 + /**
146 160 * 可参考 {@link OpenAiAutoConfiguration}
147 161 */
148 162 private static OpenAiChatModel buildOpenAiChatModel(String openAiToken, String url) {
... ... @@ -196,19 +210,6 @@ public class AiModelFactoryImpl implements AiModelFactory {
196 210 return new DeepSeekChatClient(apiKey);
197 211 }
198 212  
199   - /**
200   - * 可参考 {@link TongYiAutoConfiguration#tongYiChatClient(Generation, TongYiChatProperties, TongYiConnectionProperties)}
201   - */
202   - private static TongYiChatModel buildQianWenChatClient(String key) {
203   - com.alibaba.dashscope.aigc.generation.Generation generation = SpringUtil.getBean(Generation.class);
204   - TongYiChatProperties chatOptions = SpringUtil.getBean(TongYiChatProperties.class);
205   - // TODO @xin:貌似 apiKey 是全局唯一的???得测试下
206   - // TODO @xin:貌似阿里云不是增量返回的
207   - TongYiConnectionProperties connectionProperties = new TongYiConnectionProperties();
208   - connectionProperties.setApiKey(key);
209   - return new TongYiAutoConfiguration().tongYiChatClient(generation, chatOptions, connectionProperties);
210   - }
211   -
212 213 private StabilityAiImageModel buildStabilityAiImageClient(String apiKey, String url) {
213 214 url = StrUtil.blankToDefault(url, StabilityAiApi.DEFAULT_BASE_URL);
214 215 StabilityAiApi stabilityAiApi = new StabilityAiApi(apiKey, StabilityAiApi.DEFAULT_IMAGE_MODEL, url);
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/util/AiUtils.java
... ... @@ -32,7 +32,7 @@ public class AiUtils {
32 32 return QianFanChatOptions.builder().withTemperature(temperatureF).withMaxTokens(maxTokens).build();
33 33 case XING_HUO:
34 34 return XingHuoChatOptions.builder().model(model).temperature(temperatureF).maxTokens(maxTokens).build();
35   - case QIAN_WEN:
  35 + case TONG_YI:
36 36 return TongYiChatOptions.builder().withModel(model).withTemperature(temperature).withMaxTokens(maxTokens).build();
37 37 case DEEP_SEEK:
38 38 return DeepSeekChatOptions.builder().model(model).temperature(temperatureF).maxTokens(maxTokens).build();
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/QianWenChatClientTests.java deleted
1   -//package cn.iocoder.yudao.framework.ai.chat;
2   -//
3   -//import cn.iocoder.yudao.framework.ai.core.model.tongyi.QianWenChatClient;
4   -//import cn.iocoder.yudao.framework.ai.core.model.tongyi.QianWenChatModal;
5   -//import cn.iocoder.yudao.framework.ai.core.model.tongyi.QianWenOptions;
6   -//import cn.iocoder.yudao.framework.ai.core.model.tongyi.api.QianWenApi;
7   -//import com.alibaba.dashscope.aigc.generation.GenerationResult;
8   -//import com.alibaba.dashscope.aigc.generation.models.QwenParam;
9   -//import com.alibaba.dashscope.common.Message;
10   -//import com.alibaba.dashscope.common.MessageManager;
11   -//import com.alibaba.dashscope.common.Role;
12   -//import com.alibaba.dashscope.exception.InputRequiredException;
13   -//import com.alibaba.dashscope.exception.NoApiKeyException;
14   -//import org.junit.Before;
15   -//import org.junit.Test;
16   -//import org.springframework.ai.chat.messages.SystemMessage;
17   -//import org.springframework.ai.chat.messages.UserMessage;
18   -//import org.springframework.ai.chat.model.ChatResponse;
19   -//import org.springframework.ai.chat.prompt.Prompt;
20   -//import reactor.core.publisher.Flux;
21   -//
22   -//import java.util.ArrayList;
23   -//import java.util.List;
24   -//import java.util.Scanner;
25   -//import java.util.function.Consumer;
26   -//
27   -//// TODO 芋艿:整理单测
28   -///**
29   -// * author: fansili
30   -// * time: 2024/3/13 21:37
31   -// */
32   -//public class QianWenChatClientTests {
33   -//
34   -// private QianWenChatClient qianWenChatClient;
35   -//
36   -// @Before
37   -// public void setup() {
38   -// QianWenApi qianWenApi = new QianWenApi("sk-Zsd81gZYg7", QianWenChatModal.QWEN_72B_CHAT);
39   -// QianWenOptions qianWenOptions = new QianWenOptions();
40   -// qianWenOptions.setTopP(0.8F);
41   -//// qianWenOptions.setTopK(3); TODO 芋艿:临时处理
42   -//// qianWenOptions.setTemperature(0.6F); TODO 芋艿:临时处理
43   -// qianWenChatClient = new QianWenChatClient(
44   -// qianWenApi,
45   -// qianWenOptions
46   -// );
47   -// }
48   -//
49   -// @Test
50   -// public void callTest() {
51   -// List<org.springframework.ai.chat.messages.Message> messages = new ArrayList<>();
52   -// messages.add(new SystemMessage("你是一个优质的小红书文艺作者,抒写着各城市的美好文化和风景。"));
53   -// messages.add(new UserMessage("长沙怎么样?"));
54   -//
55   -// ChatResponse call = qianWenChatClient.call(new Prompt(messages));
56   -// System.err.println(call.getResult());
57   -// }
58   -//
59   -// @Test
60   -// public void streamTest() {
61   -// List<org.springframework.ai.chat.messages.Message> messages = new ArrayList<>();
62   -// messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
63   -// messages.add(new UserMessage("长沙怎么样?"));
64   -//
65   -// Flux<ChatResponse> flux = qianWenChatClient.stream(new Prompt(messages));
66   -// flux.subscribe(new Consumer<ChatResponse>() {
67   -// @Override
68   -// public void accept(ChatResponse chatResponse) {
69   -// System.err.print(chatResponse.getResult().getOutput().getContent());
70   -// }
71   -// });
72   -//
73   -// // 阻止退出
74   -// Scanner scanner = new Scanner(System.in);
75   -// scanner.nextLine();
76   -// }
77   -//
78   -// @Test
79   -// public void qianwenDemoTest() throws NoApiKeyException, InputRequiredException {
80   -// com.alibaba.dashscope.aigc.generation.Generation gen = new com.alibaba.dashscope.aigc.generation.Generation();
81   -// MessageManager msgManager = new MessageManager(10);
82   -// Message systemMsg =
83   -// Message.builder().role(Role.SYSTEM.getValue()).content("You are a helpful assistant.").build();
84   -// Message userMsg = Message.builder().role(Role.USER.getValue()).content("就当前的海洋污染的情况,写一份限塑的倡议书提纲,需要有理有据地号召大家克制地使用塑料制品").build();
85   -// msgManager.add(systemMsg);
86   -// msgManager.add(userMsg);
87   -// QwenParam param =
88   -// QwenParam.builder().model("qwen-72b-chat").messages(msgManager.get())
89   -// .resultFormat(QwenParam.ResultFormat.MESSAGE)
90   -// .topP(0.8)
91   -// /* set the random seed, optional, default to 1234 if not set */
92   -// .seed(100)
93   -// .apiKey("sk-Zsd81gZYg7")
94   -// .build();
95   -// GenerationResult result = gen.call(param);
96   -// System.out.println(result);
97   -// System.out.println("-----------------");
98   -// System.out.println("-----------------");
99   -// msgManager.add(result);
100   -// param.setPrompt("能否缩短一些,只讲三点");
101   -// param.setMessages(msgManager.get());
102   -// result = gen.call(param);
103   -// System.out.println(result);
104   -// }
105   -//}
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/TongYiChatModelTests.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.ai.chat;
  2 +
  3 +import cn.hutool.core.util.ReflectUtil;
  4 +import com.alibaba.cloud.ai.tongyi.chat.TongYiChatModel;
  5 +import com.alibaba.cloud.ai.tongyi.chat.TongYiChatOptions;
  6 +import com.alibaba.dashscope.aigc.generation.Generation;
  7 +import com.alibaba.dashscope.common.MessageManager;
  8 +import com.alibaba.dashscope.utils.Constants;
  9 +import org.junit.jupiter.api.BeforeEach;
  10 +import org.junit.jupiter.api.Disabled;
  11 +import org.junit.jupiter.api.Test;
  12 +import org.springframework.ai.chat.messages.Message;
  13 +import org.springframework.ai.chat.messages.SystemMessage;
  14 +import org.springframework.ai.chat.messages.UserMessage;
  15 +import org.springframework.ai.chat.model.ChatResponse;
  16 +import org.springframework.ai.chat.prompt.Prompt;
  17 +import reactor.core.publisher.Flux;
  18 +
  19 +import java.util.ArrayList;
  20 +import java.util.List;
  21 +
  22 +/**
  23 + * {@link TongYiChatModel} 集成测试类
  24 + *
  25 + * @author fansili
  26 + */
  27 +public class TongYiChatModelTests {
  28 +
  29 + private final Generation generation = new Generation();
  30 + private final TongYiChatModel chatModel = new TongYiChatModel(generation,
  31 + TongYiChatOptions.builder().withModel("qwen1.5-72b-chat").build());
  32 +
  33 + static {
  34 + Constants.apiKey = "sk-Zsd81gZYg7";
  35 + }
  36 +
  37 + @BeforeEach
  38 + public void before() {
  39 + // 防止 TongYiChatModel 调用空指针
  40 + ReflectUtil.setFieldValue(chatModel, "msgManager", new MessageManager());
  41 + }
  42 +
  43 + @Test
  44 + @Disabled
  45 + public void testCall() {
  46 + // 准备参数
  47 + List<Message> messages = new ArrayList<>();
  48 + messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
  49 + messages.add(new UserMessage("1 + 1 = ?"));
  50 +
  51 + // 调用
  52 + ChatResponse response = chatModel.call(new Prompt(messages));
  53 + // 打印结果
  54 + System.out.println(response);
  55 + System.out.println(response.getResult().getOutput());
  56 + }
  57 +
  58 + @Test
  59 + @Disabled
  60 + public void testStream() {
  61 + // 准备参数
  62 + List<Message> messages = new ArrayList<>();
  63 + messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。"));
  64 + messages.add(new UserMessage("1 + 1 = ?"));
  65 +
  66 + // 调用
  67 + Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages));
  68 + // 打印结果
  69 + flux.doOnNext(response -> {
  70 +// System.out.println(response);
  71 + System.out.println(response.getResult().getOutput());
  72 + }).then().block();
  73 + }
  74 +
  75 +}
... ...