Commit 4daff933136b3806dfee6facd5455d8037373852
1 parent
4f11d00c
【代码优化】AI:完善 YiYanChatTests 单测,方便大家快速体验
Showing
3 changed files
with
67 additions
and
83 deletions
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiModelFactoryImpl.java
| ... | ... | @@ -58,7 +58,7 @@ public class AiModelFactoryImpl implements AiModelFactory { |
| 58 | 58 | case TONG_YI: |
| 59 | 59 | return buildTongYiChatModel(apiKey); |
| 60 | 60 | case YI_YAN: |
| 61 | - return buildYiYanChatClient(apiKey); | |
| 61 | + return buildYiYanChatModel(apiKey); | |
| 62 | 62 | case XING_HUO: |
| 63 | 63 | return buildXingHuoChatClient(apiKey); |
| 64 | 64 | case DEEP_SEEK: |
| ... | ... | @@ -157,6 +157,18 @@ public class AiModelFactoryImpl implements AiModelFactory { |
| 157 | 157 | } |
| 158 | 158 | |
| 159 | 159 | /** |
| 160 | + * 可参考 {@link QianFanAutoConfiguration#qianFanChatModel(QianFanConnectionProperties, QianFanChatProperties, RestClient.Builder, RetryTemplate, ResponseErrorHandler)} | |
| 161 | + */ | |
| 162 | + private static QianFanChatModel buildYiYanChatModel(String key) { | |
| 163 | + List<String> keys = StrUtil.split(key, '|'); | |
| 164 | + Assert.equals(keys.size(), 2, "YiYanChatClient 的密钥需要 (appKey|secretKey) 格式"); | |
| 165 | + String appKey = keys.get(0); | |
| 166 | + String secretKey = keys.get(1); | |
| 167 | + QianFanApi qianFanApi = new QianFanApi(appKey, secretKey); | |
| 168 | + return new QianFanChatModel(qianFanApi); | |
| 169 | + } | |
| 170 | + | |
| 171 | + /** | |
| 160 | 172 | * 可参考 {@link OpenAiAutoConfiguration} |
| 161 | 173 | */ |
| 162 | 174 | private static OpenAiChatModel buildOpenAiChatModel(String openAiToken, String url) { |
| ... | ... | @@ -183,19 +195,6 @@ public class AiModelFactoryImpl implements AiModelFactory { |
| 183 | 195 | } |
| 184 | 196 | |
| 185 | 197 | /** |
| 186 | - * 可参考 {@link QianFanAutoConfiguration#qianFanChatModel(QianFanConnectionProperties, QianFanChatProperties, RestClient.Builder, RetryTemplate, ResponseErrorHandler)} | |
| 187 | - */ | |
| 188 | - private static QianFanChatModel buildYiYanChatClient(String key) { | |
| 189 | - // TODO @xin:貌似目前设置,request 势必会报错;看看能不能有办法,参考 buildQianWenChatClient,调用 QianFanAutoConfiguration#qianFanChatModel初始化,当然 key 要用自己的哈 | |
| 190 | - List<String> keys = StrUtil.split(key, '|'); | |
| 191 | - Assert.equals(keys.size(), 2, "YiYanChatClient 的密钥需要 (appKey|secretKey) 格式"); | |
| 192 | - String appKey = keys.get(0); | |
| 193 | - String secretKey = keys.get(1); | |
| 194 | - QianFanApi qianFanApi = new QianFanApi(appKey, secretKey); | |
| 195 | - return new QianFanChatModel(qianFanApi); | |
| 196 | - } | |
| 197 | - | |
| 198 | - /** | |
| 199 | 198 | * 可参考 {@link YudaoAiAutoConfiguration#xingHuoChatClient(YudaoAiProperties)} |
| 200 | 199 | */ |
| 201 | 200 | private static XingHuoChatClient buildXingHuoChatClient(String key) { | ... | ... |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/util/AiUtils.java
| ... | ... | @@ -27,9 +27,7 @@ public class AiUtils { |
| 27 | 27 | case OLLAMA: |
| 28 | 28 | return OllamaOptions.create().withModel(model).withTemperature(temperatureF).withNumPredict(maxTokens); |
| 29 | 29 | case YI_YAN: |
| 30 | - // TODO @xin:貌似 model 只要一设置,就报错;可以排查下 | |
| 31 | -// return QianFanChatOptions.builder().withModel(model).withTemperature(temperatureF).withMaxTokens(maxTokens).build(); | |
| 32 | - return QianFanChatOptions.builder().withTemperature(temperatureF).withMaxTokens(maxTokens).build(); | |
| 30 | + return QianFanChatOptions.builder().withModel(model).withTemperature(temperatureF).withMaxTokens(maxTokens).build(); | |
| 33 | 31 | case XING_HUO: |
| 34 | 32 | return XingHuoChatOptions.builder().model(model).temperature(temperatureF).maxTokens(maxTokens).build(); |
| 35 | 33 | case TONG_YI: | ... | ... |
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/YiYanChatTests.java
| 1 | 1 | package cn.iocoder.yudao.framework.ai.chat; |
| 2 | 2 | |
| 3 | -//import cn.iocoder.yudao.framework.ai.core.model.yiyan.YiYanChatClient; | |
| 4 | -//import cn.iocoder.yudao.framework.ai.core.model.yiyan.YiYanChatOptions; | |
| 5 | -//import cn.iocoder.yudao.framework.ai.core.model.yiyan.api.YiYanApi; | |
| 6 | -//import cn.iocoder.yudao.framework.ai.core.model.yiyan.api.YiYanChatModel; | |
| 7 | -//import org.junit.Before; | |
| 8 | -//import org.junit.Test; | |
| 9 | -//import org.springframework.ai.chat.messages.Message; | |
| 10 | -//import org.springframework.ai.chat.messages.SystemMessage; | |
| 11 | -//import org.springframework.ai.chat.messages.UserMessage; | |
| 12 | -//import org.springframework.ai.chat.model.ChatResponse; | |
| 13 | -//import org.springframework.ai.chat.prompt.Prompt; | |
| 14 | -//import reactor.core.publisher.Flux; | |
| 15 | -// | |
| 16 | -//import java.util.ArrayList; | |
| 17 | -//import java.util.List; | |
| 18 | -//import java.util.Scanner; | |
| 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.UserMessage; | |
| 7 | +import org.springframework.ai.chat.model.ChatResponse; | |
| 8 | +import org.springframework.ai.chat.prompt.Prompt; | |
| 9 | +import org.springframework.ai.qianfan.QianFanChatModel; | |
| 10 | +import org.springframework.ai.qianfan.QianFanChatOptions; | |
| 11 | +import org.springframework.ai.qianfan.api.QianFanApi; | |
| 12 | +import reactor.core.publisher.Flux; | |
| 13 | + | |
| 14 | +import java.util.ArrayList; | |
| 15 | +import java.util.List; | |
| 19 | 16 | |
| 20 | -// TODO 芋艿:整理单测 | |
| 21 | 17 | /** |
| 22 | - * chat 文心一言 | |
| 23 | - * <p> | |
| 24 | - * author: fansili | |
| 25 | - * time: 2024/3/12 20:59 | |
| 18 | + * {@link QianFanChatModel} 的集成测试 | |
| 19 | + * | |
| 20 | + * @author fansili | |
| 26 | 21 | */ |
| 27 | 22 | public class YiYanChatTests { |
| 28 | 23 | |
| 29 | -// private YiYanChatClient yiYanChatClient; | |
| 30 | -// | |
| 31 | -// @Before | |
| 32 | -// public void setup() { | |
| 33 | -// YiYanApi yiYanApi = new YiYanApi( | |
| 34 | -// "x0cuLZ7XsaTCU08vuJWO87Lg", | |
| 35 | -// "R9mYF9dl9KASgi5RUq0FQt3wRisSnOcK", | |
| 36 | -// YiYanChatModel.ERNIE4_3_5_8K, | |
| 37 | -// 86400 | |
| 38 | -// ); | |
| 39 | -// YiYanChatOptions yiYanOptions = new YiYanChatOptions(); | |
| 40 | -// yiYanOptions.setMaxOutputTokens(2048); | |
| 41 | -// yiYanOptions.setTopP(0.6f); | |
| 42 | -// yiYanOptions.setTemperature(0.85f); | |
| 43 | -// yiYanChatClient = new YiYanChatClient( | |
| 44 | -// yiYanApi, | |
| 45 | -// yiYanOptions | |
| 46 | -// ); | |
| 47 | -// } | |
| 48 | -// | |
| 49 | -// @Test | |
| 50 | -// public void callTest() { | |
| 51 | -// | |
| 52 | -// // tip: 百度的message 有特殊规则(最后一个message为当前请求的信息,前面的message为历史对话信息) | |
| 53 | -// // tip: 地址 https://cloud.baidu.com/doc/WENXINWORKSHOP/s/jlil56u11 | |
| 54 | -// List<Message> messages = new ArrayList<>(); | |
| 55 | -// messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景,所有问题都采用文言文回答。")); | |
| 56 | -// messages.add(new UserMessage("长沙怎么样?")); | |
| 57 | -// | |
| 58 | -// ChatResponse call = yiYanChatClient.call(new Prompt(messages)); | |
| 59 | -// System.err.println(call.getResult()); | |
| 60 | -// } | |
| 61 | -// | |
| 62 | -// @Test | |
| 63 | -// public void streamTest() { | |
| 64 | -// List<Message> messages = new ArrayList<>(); | |
| 65 | -// messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景,所有问题都采用文言文回答。")); | |
| 66 | -// messages.add(new UserMessage("长沙怎么样?")); | |
| 67 | -// | |
| 68 | -// Flux<ChatResponse> fluxResponse = yiYanChatClient.stream(new Prompt(messages)); | |
| 69 | -// fluxResponse.subscribe(chatResponse -> System.err.print(chatResponse.getResult().getOutput().getContent())); | |
| 70 | -// // 阻止退出 | |
| 71 | -// Scanner scanner = new Scanner(System.in); | |
| 72 | -// scanner.nextLine(); | |
| 73 | -// } | |
| 24 | + private final QianFanApi qianFanApi = new QianFanApi( | |
| 25 | + "qS8k8dYr2nXunagK4SSU8Xjj", | |
| 26 | + "pHGbx51ql2f0hOyabQvSZezahVC3hh3e"); | |
| 27 | + private final QianFanChatModel chatModel = new QianFanChatModel(qianFanApi, | |
| 28 | + QianFanChatOptions.builder().withModel(QianFanApi.ChatModel.ERNIE_Tiny_8K.getValue()).build() | |
| 29 | + ); | |
| 30 | + | |
| 31 | + @Test | |
| 32 | + @Disabled | |
| 33 | + public void testCall() { | |
| 34 | + // 准备参数 | |
| 35 | + List<Message> messages = new ArrayList<>(); | |
| 36 | + // TODO @芋艿:文心一言,只要带上 system message 就报错,已经各种测试,很莫名! | |
| 37 | +// messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。")); | |
| 38 | + messages.add(new UserMessage("1 + 1 = ?")); | |
| 39 | + | |
| 40 | + // 调用 | |
| 41 | + ChatResponse response = chatModel.call(new Prompt(messages)); | |
| 42 | + // 打印结果 | |
| 43 | + System.out.println(response); | |
| 44 | + } | |
| 45 | + | |
| 46 | + @Test | |
| 47 | + @Disabled | |
| 48 | + public void testStream() { | |
| 49 | + // 准备参数 | |
| 50 | + List<Message> messages = new ArrayList<>(); | |
| 51 | + // TODO @芋艿:文心一言,只要带上 system message 就报错,已经各种测试,很莫名! | |
| 52 | +// messages.add(new SystemMessage("你是一个优质的文言文作者,用文言文描述着各城市的人文风景。")); | |
| 53 | + messages.add(new UserMessage("1 + 1 = ?")); | |
| 54 | + | |
| 55 | + // 调用 | |
| 56 | + Flux<ChatResponse> flux = chatModel.stream(new Prompt(messages)); | |
| 57 | + // 打印结果 | |
| 58 | + flux.doOnNext(System.out::println).then().block(); | |
| 59 | + } | |
| 60 | + | |
| 74 | 61 | } | ... | ... |