Commit 1feff2b12b4f3c7b5711ce980ae94492bbad44c2
1 parent
e0f08a0f
【代码优化】AI:完善 OpenAIChatModelTests、OpenAiImageModelTests 单测,方便大家快速体验
Showing
6 changed files
with
108 additions
and
73 deletions
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiApiKeyServiceImpl.java
| ... | ... | @@ -101,7 +101,7 @@ public class AiApiKeyServiceImpl implements AiApiKeyService { |
| 101 | 101 | public ChatModel getChatModel(Long id) { |
| 102 | 102 | AiApiKeyDO apiKey = validateApiKey(id); |
| 103 | 103 | AiPlatformEnum platform = AiPlatformEnum.validatePlatform(apiKey.getPlatform()); |
| 104 | - return modelFactory.getOrCreateChatClient(platform, apiKey.getApiKey(), apiKey.getUrl()); | |
| 104 | + return modelFactory.getOrCreateChatModel(platform, apiKey.getApiKey(), apiKey.getUrl()); | |
| 105 | 105 | } |
| 106 | 106 | |
| 107 | 107 | @Override | ... | ... |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiModelFactory.java
| ... | ... | @@ -23,7 +23,7 @@ public interface AiModelFactory { |
| 23 | 23 | * @param url API URL |
| 24 | 24 | * @return ChatModel 对象 |
| 25 | 25 | */ |
| 26 | - ChatModel getOrCreateChatClient(AiPlatformEnum platform, String apiKey, String url); | |
| 26 | + ChatModel getOrCreateChatModel(AiPlatformEnum platform, String apiKey, String url); | |
| 27 | 27 | |
| 28 | 28 | /** |
| 29 | 29 | * 基于默认配置,获得 ChatModel 对象 | ... | ... |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/factory/AiModelFactoryImpl.java
| ... | ... | @@ -50,7 +50,7 @@ import java.util.List; |
| 50 | 50 | public class AiModelFactoryImpl implements AiModelFactory { |
| 51 | 51 | |
| 52 | 52 | @Override |
| 53 | - public ChatModel getOrCreateChatClient(AiPlatformEnum platform, String apiKey, String url) { | |
| 53 | + public ChatModel getOrCreateChatModel(AiPlatformEnum platform, String apiKey, String url) { | |
| 54 | 54 | String cacheKey = buildClientCacheKey(ChatModel.class, platform, apiKey, url); |
| 55 | 55 | return Singleton.get(cacheKey, (Func0<ChatModel>) () -> { |
| 56 | 56 | //noinspection EnhancedSwitchMigration | ... | ... |
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/OpenAIChatModelTests.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.ai.chat; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.ai.core.model.xinghuo.XingHuoChatClient; | |
| 4 | +import org.junit.jupiter.api.Disabled; | |
| 5 | +import org.junit.jupiter.api.Test; | |
| 6 | +import org.springframework.ai.chat.messages.Message; | |
| 7 | +import org.springframework.ai.chat.messages.SystemMessage; | |
| 8 | +import org.springframework.ai.chat.messages.UserMessage; | |
| 9 | +import org.springframework.ai.chat.model.ChatResponse; | |
| 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; | |
| 14 | +import reactor.core.publisher.Flux; | |
| 15 | + | |
| 16 | +import java.util.ArrayList; | |
| 17 | +import java.util.List; | |
| 18 | + | |
| 19 | +/** | |
| 20 | + * {@link XingHuoChatClient} 集成测试 | |
| 21 | + * | |
| 22 | + * @author 芋道源码 | |
| 23 | + */ | |
| 24 | +public class OpenAIChatModelTests { | |
| 25 | + | |
| 26 | + private final OpenAiApi openAiApi = new OpenAiApi( | |
| 27 | + "https://api.holdai.top", | |
| 28 | + "sk-dZEPiVaNcT3FHhef51996bAa0bC74806BeAb620dA5Da10Bf"); | |
| 29 | + private final OpenAiChatModel chatModel = new OpenAiChatModel(openAiApi, | |
| 30 | + OpenAiChatOptions.builder().withModel(OpenAiApi.ChatModel.GPT_4_O).build()); | |
| 31 | + | |
| 32 | + @Test | |
| 33 | + @Disabled | |
| 34 | + public void testCall() { | |
| 35 | + // 准备参数 | |
| 36 | + List<Message> messages = new ArrayList<>(); | |
| 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 | + System.out.println(response.getResult().getOutput()); | |
| 45 | + } | |
| 46 | + | |
| 47 | + @Test | |
| 48 | + @Disabled | |
| 49 | + public void testStream() { | |
| 50 | + // 准备参数 | |
| 51 | + List<Message> messages = new ArrayList<>(); | |
| 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(response -> { | |
| 59 | +// System.out.println(response); | |
| 60 | + System.out.println(response.getResult().getOutput()); | |
| 61 | + }).then().block(); | |
| 62 | + } | |
| 63 | + | |
| 64 | +} | ... | ... |
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/image/OpenAiImageClientTests.java deleted
| 1 | -package cn.iocoder.yudao.framework.ai.image; | |
| 2 | - | |
| 3 | -import org.junit.jupiter.api.BeforeEach; | |
| 4 | -import org.junit.jupiter.api.Test; | |
| 5 | -import org.springframework.ai.image.ImagePrompt; | |
| 6 | -import org.springframework.ai.image.ImageResponse; | |
| 7 | -import org.springframework.ai.openai.OpenAiImageModel; | |
| 8 | -import org.springframework.ai.openai.api.OpenAiImageApi; | |
| 9 | - | |
| 10 | -import javax.imageio.ImageIO; | |
| 11 | -import javax.swing.*; | |
| 12 | -import java.awt.image.BufferedImage; | |
| 13 | -import java.io.ByteArrayInputStream; | |
| 14 | -import java.io.IOException; | |
| 15 | -import java.util.Base64; | |
| 16 | -import java.util.Scanner; | |
| 17 | - | |
| 18 | -// TODO 芋艿:整理单测 | |
| 19 | -/** | |
| 20 | - * author: fansili | |
| 21 | - * time: 2024/3/17 10:40 | |
| 22 | - */ | |
| 23 | -public class OpenAiImageClientTests { | |
| 24 | - | |
| 25 | - | |
| 26 | - private OpenAiImageModel openAiImageClient; | |
| 27 | - | |
| 28 | - @BeforeEach | |
| 29 | - public void setup() { | |
| 30 | - // 初始化 openAiImageClient | |
| 31 | - this.openAiImageClient = new OpenAiImageModel( | |
| 32 | - new OpenAiImageApi("") | |
| 33 | -// new OpenAiImageOptions().setResponseFormat(OpenAiImageOptions.ResponseFormatEnum.URL.getValue()) TODO 芋艿:临时处理 | |
| 34 | - ); | |
| 35 | - } | |
| 36 | - | |
| 37 | - @Test | |
| 38 | - public void callTest() { | |
| 39 | - ImageResponse call = openAiImageClient.call(new ImagePrompt("中国长城!")); | |
| 40 | - System.err.println("url: " + call.getResult().getOutput().getUrl()); | |
| 41 | - System.err.println("base64: " + call.getResult().getOutput().getB64Json()); | |
| 42 | - | |
| 43 | - String base64String = call.getResult().getOutput().getB64Json(); | |
| 44 | - ImageIcon imageIcon = new ImageIcon(decodeBase64ToImage(base64String)); | |
| 45 | - JLabel label = new JLabel(imageIcon); | |
| 46 | - | |
| 47 | - JFrame frame = new JFrame("Base64 Image Display"); | |
| 48 | - frame.getContentPane().add(label); | |
| 49 | - frame.pack(); | |
| 50 | - frame.setVisible(true); | |
| 51 | - | |
| 52 | - // 阻止退出 | |
| 53 | - Scanner scanner = new Scanner(System.in); | |
| 54 | - scanner.nextLine(); | |
| 55 | - } | |
| 56 | - | |
| 57 | - | |
| 58 | - // 将Base64解码为BufferedImage | |
| 59 | - private static BufferedImage decodeBase64ToImage(String base64String) { | |
| 60 | - try { | |
| 61 | - byte[] decodedBytes = Base64.getDecoder().decode(base64String); | |
| 62 | - ByteArrayInputStream bis = new ByteArrayInputStream(decodedBytes); | |
| 63 | - return ImageIO.read(bis); | |
| 64 | - } catch (IOException e) { | |
| 65 | - System.out.println("Error decoding the base64 image: " + e.getMessage()); | |
| 66 | - return null; | |
| 67 | - } | |
| 68 | - } | |
| 69 | - | |
| 70 | -} |
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/image/OpenAiImageModelTests.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.ai.image; | |
| 2 | + | |
| 3 | +import org.junit.jupiter.api.Disabled; | |
| 4 | +import org.junit.jupiter.api.Test; | |
| 5 | +import org.springframework.ai.image.ImageOptions; | |
| 6 | +import org.springframework.ai.image.ImagePrompt; | |
| 7 | +import org.springframework.ai.image.ImageResponse; | |
| 8 | +import org.springframework.ai.openai.OpenAiImageModel; | |
| 9 | +import org.springframework.ai.openai.OpenAiImageOptions; | |
| 10 | +import org.springframework.ai.openai.api.OpenAiImageApi; | |
| 11 | +import org.springframework.web.client.RestClient; | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * {@link OpenAiImageModel} 集成测试类 | |
| 15 | + * | |
| 16 | + * @author fansili | |
| 17 | + */ | |
| 18 | +public class OpenAiImageModelTests { | |
| 19 | + | |
| 20 | + private final OpenAiImageApi imageApi = new OpenAiImageApi( | |
| 21 | + "https://api.holdai.top", | |
| 22 | + "sk-dZEPiVaNcT3FHhef51996bAa0bC74806BeAb620dA5Da10Bf", | |
| 23 | + RestClient.builder()); | |
| 24 | + private final OpenAiImageModel imageClient = new OpenAiImageModel(imageApi); | |
| 25 | + | |
| 26 | + @Test | |
| 27 | + @Disabled | |
| 28 | + public void testCall() { | |
| 29 | + // 准备参数 | |
| 30 | + ImageOptions options = OpenAiImageOptions.builder() | |
| 31 | + .withModel(OpenAiImageApi.ImageModel.DALL_E_2.getValue()) // 这个模型比较便宜 | |
| 32 | + .withHeight(256).withWidth(256) | |
| 33 | + .build(); | |
| 34 | + ImagePrompt prompt = new ImagePrompt("中国长城!", options); | |
| 35 | + | |
| 36 | + // 方法调用 | |
| 37 | + ImageResponse response = imageClient.call(prompt); | |
| 38 | + System.out.println(response); | |
| 39 | + } | |
| 40 | + | |
| 41 | +} | ... | ... |