Commit d865cc293b106501642985c193f81696a61f90cf
1 parent
db7315b8
【增加】chatglm 实现 spring ai 标准
Showing
5 changed files
with
261 additions
and
0 deletions
yudao-module-ai/yudao-spring-boot-starter-ai/pom.xml
| ... | ... | @@ -60,6 +60,13 @@ |
| 60 | 60 | <version>2.14.0</version> |
| 61 | 61 | </dependency> |
| 62 | 62 | |
| 63 | + <!-- bigmodel --> | |
| 64 | + <dependency> | |
| 65 | + <groupId>cn.bigmodel.openapi</groupId> | |
| 66 | + <artifactId>oapi-java-sdk</artifactId> | |
| 67 | + <version>release-V4-2.0.2</version> | |
| 68 | + </dependency> | |
| 69 | + | |
| 63 | 70 | <!-- Test 测试相关 --> |
| 64 | 71 | <dependency> |
| 65 | 72 | <groupId>org.springframework.boot</groupId> | ... | ... |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/chatglm/ChatGlmImageModel.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.ai.core.model.chatglm; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.ai.core.model.chatglm.api.ChatGlmResponseMetadata; | |
| 4 | +import com.zhipu.oapi.ClientV4; | |
| 5 | +import com.zhipu.oapi.service.v4.image.CreateImageRequest; | |
| 6 | +import com.zhipu.oapi.service.v4.image.ImageApiResponse; | |
| 7 | +import org.springframework.ai.image.*; | |
| 8 | + | |
| 9 | +import java.io.ByteArrayOutputStream; | |
| 10 | +import java.net.URL; | |
| 11 | +import java.util.Base64; | |
| 12 | +import java.util.stream.Collectors; | |
| 13 | + | |
| 14 | +public class ChatGlmImageModel implements ImageModel { | |
| 15 | + | |
| 16 | + private ClientV4 client; | |
| 17 | + | |
| 18 | + public ChatGlmImageModel(String apiSecretKey) { | |
| 19 | + client = new ClientV4.Builder(apiSecretKey).build(); | |
| 20 | + } | |
| 21 | + | |
| 22 | + @Override | |
| 23 | + public ImageResponse call(ImagePrompt request) { | |
| 24 | + CreateImageRequest imageRequest = CreateImageRequest.builder() | |
| 25 | + .model(request.getOptions().getModel()) | |
| 26 | + .prompt(request.getInstructions().get(0).getText()) | |
| 27 | + .build(); | |
| 28 | + return convert(client.createImage(imageRequest)); | |
| 29 | + } | |
| 30 | + | |
| 31 | + private ImageResponse convert(ImageApiResponse result) { | |
| 32 | + return new ImageResponse( | |
| 33 | + result.getData().getData().stream().map(item -> { | |
| 34 | + try { | |
| 35 | + String url = item.getUrl(); | |
| 36 | + String base64Image = convertImageToBase64(url); | |
| 37 | + Image image = new Image(url, base64Image); | |
| 38 | + return new ImageGeneration(image); | |
| 39 | + } catch (Exception e) { | |
| 40 | + throw new RuntimeException(e); | |
| 41 | + } | |
| 42 | + }).collect(Collectors.toList()), | |
| 43 | + new ChatGlmResponseMetadata(result) | |
| 44 | + ); | |
| 45 | + } | |
| 46 | + | |
| 47 | + | |
| 48 | + /** | |
| 49 | + * Convert image to base64. | |
| 50 | + * @param imageUrl the image url. | |
| 51 | + * @return the base64 image. | |
| 52 | + * @throws Exception the exception. | |
| 53 | + */ | |
| 54 | + public String convertImageToBase64(String imageUrl) throws Exception { | |
| 55 | + | |
| 56 | + var url = new URL(imageUrl); | |
| 57 | + var inputStream = url.openStream(); | |
| 58 | + var outputStream = new ByteArrayOutputStream(); | |
| 59 | + var buffer = new byte[4096]; | |
| 60 | + int bytesRead; | |
| 61 | + | |
| 62 | + while ((bytesRead = inputStream.read(buffer)) != -1) { | |
| 63 | + outputStream.write(buffer, 0, bytesRead); | |
| 64 | + } | |
| 65 | + | |
| 66 | + var imageBytes = outputStream.toByteArray(); | |
| 67 | + | |
| 68 | + String base64Image = Base64.getEncoder().encodeToString(imageBytes); | |
| 69 | + | |
| 70 | + inputStream.close(); | |
| 71 | + outputStream.close(); | |
| 72 | + | |
| 73 | + return base64Image; | |
| 74 | + } | |
| 75 | +} | ... | ... |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/chatglm/ChatGlmImageOptions.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.ai.core.model.chatglm; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.JsonProperty; | |
| 4 | +import lombok.Setter; | |
| 5 | +import org.springframework.ai.image.ImageOptions; | |
| 6 | + | |
| 7 | +/** | |
| 8 | + * chatglm | |
| 9 | + * api地址:https://open.bigmodel.cn/dev/api#cogview | |
| 10 | + */ | |
| 11 | +@Setter | |
| 12 | +public class ChatGlmImageOptions implements ImageOptions { | |
| 13 | + | |
| 14 | + @JsonProperty("n") | |
| 15 | + private Integer n; | |
| 16 | + | |
| 17 | + @JsonProperty("model") | |
| 18 | + private String model = "cogview-3"; | |
| 19 | + | |
| 20 | + @JsonProperty("size_width") | |
| 21 | + private Integer width; | |
| 22 | + | |
| 23 | + @JsonProperty("size_height") | |
| 24 | + private Integer height; | |
| 25 | + | |
| 26 | + @JsonProperty("size") | |
| 27 | + private String size; | |
| 28 | + | |
| 29 | + @JsonProperty("style") | |
| 30 | + private String style; | |
| 31 | + | |
| 32 | + @JsonProperty("user_id") | |
| 33 | + private String user; | |
| 34 | + | |
| 35 | + @JsonProperty("responseFormat") | |
| 36 | + private String responseFormat; | |
| 37 | + | |
| 38 | + // ==== build | |
| 39 | + | |
| 40 | + | |
| 41 | + public static ChatGlmImageOptions.Builder builder() { | |
| 42 | + return new ChatGlmImageOptions.Builder(); | |
| 43 | + } | |
| 44 | + | |
| 45 | + public static class Builder { | |
| 46 | + | |
| 47 | + private final ChatGlmImageOptions options; | |
| 48 | + | |
| 49 | + private Builder() { | |
| 50 | + this.options = new ChatGlmImageOptions(); | |
| 51 | + } | |
| 52 | + | |
| 53 | + public ChatGlmImageOptions.Builder withN(Integer n) { | |
| 54 | + options.setN(n); | |
| 55 | + return this; | |
| 56 | + } | |
| 57 | + | |
| 58 | + public ChatGlmImageOptions.Builder withModel(String model) { | |
| 59 | + options.setModel(model); | |
| 60 | + return this; | |
| 61 | + } | |
| 62 | + | |
| 63 | + public ChatGlmImageOptions.Builder withWidth(Integer width) { | |
| 64 | + options.setWidth(width); | |
| 65 | + return this; | |
| 66 | + } | |
| 67 | + | |
| 68 | + public ChatGlmImageOptions.Builder withHeight(Integer height) { | |
| 69 | + options.setHeight(height); | |
| 70 | + return this; | |
| 71 | + } | |
| 72 | + | |
| 73 | + public ChatGlmImageOptions.Builder withStyle(String style) { | |
| 74 | + options.setStyle(style); | |
| 75 | + return this; | |
| 76 | + } | |
| 77 | + | |
| 78 | + public ChatGlmImageOptions.Builder withUser(String user) { | |
| 79 | + options.setUser(user); | |
| 80 | + return this; | |
| 81 | + } | |
| 82 | + | |
| 83 | + public ChatGlmImageOptions build() { | |
| 84 | + return options; | |
| 85 | + } | |
| 86 | + | |
| 87 | + } | |
| 88 | + | |
| 89 | + // ==== get | |
| 90 | + | |
| 91 | + @Override | |
| 92 | + public Integer getN() { | |
| 93 | + return n; | |
| 94 | + } | |
| 95 | + | |
| 96 | + @Override | |
| 97 | + public String getModel() { | |
| 98 | + return model; | |
| 99 | + } | |
| 100 | + | |
| 101 | + @Override | |
| 102 | + public Integer getWidth() { | |
| 103 | + return width; | |
| 104 | + } | |
| 105 | + | |
| 106 | + @Override | |
| 107 | + public Integer getHeight() { | |
| 108 | + return height; | |
| 109 | + } | |
| 110 | + | |
| 111 | + @Override | |
| 112 | + public String getResponseFormat() { | |
| 113 | + return responseFormat; | |
| 114 | + } | |
| 115 | +} | ... | ... |
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/chatglm/api/ChatGlmResponseMetadata.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.ai.core.model.chatglm.api; | |
| 2 | + | |
| 3 | +import com.zhipu.oapi.service.v4.image.ImageApiResponse; | |
| 4 | +import org.springframework.ai.image.ImageResponseMetadata; | |
| 5 | + | |
| 6 | +import java.util.HashMap; | |
| 7 | + | |
| 8 | +public class ChatGlmResponseMetadata extends HashMap<String, Object> implements ImageResponseMetadata { | |
| 9 | + | |
| 10 | + private Long created; | |
| 11 | + | |
| 12 | + public ChatGlmResponseMetadata(ImageApiResponse result) { | |
| 13 | + created = result.getData().getCreated(); | |
| 14 | + } | |
| 15 | + | |
| 16 | + @Override | |
| 17 | + public Long getCreated() { | |
| 18 | + return created; | |
| 19 | + } | |
| 20 | + | |
| 21 | + public void setCreated(Long created) { | |
| 22 | + this.created = created; | |
| 23 | + } | |
| 24 | +} | ... | ... |
yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/image/ChatGlmImageModelTests.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.ai.image; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.ai.core.model.chatglm.ChatGlmImageModel; | |
| 4 | +import cn.iocoder.yudao.framework.ai.core.model.chatglm.ChatGlmImageOptions; | |
| 5 | +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | |
| 6 | +import com.alibaba.fastjson.JSON; | |
| 7 | +import com.zhipu.oapi.ClientV4; | |
| 8 | +import com.zhipu.oapi.core.httpclient.ApacheHttpClientTransport; | |
| 9 | +import com.zhipu.oapi.service.v4.image.CreateImageRequest; | |
| 10 | +import com.zhipu.oapi.service.v4.image.ImageApiResponse; | |
| 11 | +import org.junit.jupiter.api.Test; | |
| 12 | +import org.springframework.ai.image.ImageOptionsBuilder; | |
| 13 | +import org.springframework.ai.image.ImagePrompt; | |
| 14 | +import org.springframework.ai.image.ImageResponse; | |
| 15 | +import org.springframework.ai.qianfan.QianFanImageModel; | |
| 16 | +import org.springframework.ai.qianfan.QianFanImageOptions; | |
| 17 | +import org.springframework.ai.qianfan.api.QianFanImageApi; | |
| 18 | + | |
| 19 | +/** | |
| 20 | + * 百度千帆 image | |
| 21 | + */ | |
| 22 | +public class ChatGlmImageModelTests { | |
| 23 | + | |
| 24 | + @Test | |
| 25 | + public void callTest() { | |
| 26 | + ChatGlmImageModel model = new ChatGlmImageModel("78d3228c1d9e5e342a3e1ab349e2dd7b.VXLoq5vrwK2ofboy"); | |
| 27 | + ImageResponse call = model.call(new ImagePrompt("万里长城", ChatGlmImageOptions.builder().build())); | |
| 28 | + System.err.println(call.getResult().getOutput().getUrl()); | |
| 29 | + } | |
| 30 | + | |
| 31 | + @Test | |
| 32 | + public void createImageTest() { | |
| 33 | + ClientV4 client = new ClientV4.Builder("78d3228c1d9e5e342a3e1ab349e2dd7b.VXLoq5vrwK2ofboy").build(); | |
| 34 | + CreateImageRequest createImageRequest = new CreateImageRequest(); | |
| 35 | + createImageRequest.setModel("cogview-3"); | |
| 36 | + createImageRequest.setPrompt("长城!"); | |
| 37 | + ImageApiResponse image = client.createImage(createImageRequest); | |
| 38 | + System.err.println(JSON.toJSONString(image)); | |
| 39 | + } | |
| 40 | +} | ... | ... |