diff --git a/pom.xml b/pom.xml index c8dd86a586e4c2820814ed41798de2a006808e31..b3f9d62c1d0de9d0b60ee2376a8ab293343d5a57 100644 --- a/pom.xml +++ b/pom.xml @@ -237,7 +237,17 @@ com.github.ben-manes.caffeine caffeine - + + + org.asynchttpclient + async-http-client + 2.12.3 + jar + + + com.google.code.gson + gson + 2.10.1 diff --git a/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIChatRequest.java b/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIChatRequest.java new file mode 100644 index 0000000000000000000000000000000000000000..eb54f634ada55bec02f55dd08117b3ef362444ca --- /dev/null +++ b/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIChatRequest.java @@ -0,0 +1,24 @@ +package com.kwan.springbootkwan.entity.openai; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.util.List; + + +@Data +public class AzureAIChatRequest { + private List messages; + private Double temperature; + @SerializedName("n") + private Integer choices; + private boolean stream; + private String stop; + @SerializedName("max_tokens") + private Integer maxTokens; + @SerializedName("presence_penalty") + private Integer presencePenalty; + @SerializedName("frequency_penalty") + private Integer frequencyPenalty; + private String user; +} \ No newline at end of file diff --git a/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIChatResponse.java b/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIChatResponse.java new file mode 100644 index 0000000000000000000000000000000000000000..e45ccdcce5d04769058aeb0153f677364fa2b9bd --- /dev/null +++ b/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIChatResponse.java @@ -0,0 +1,16 @@ +package com.kwan.springbootkwan.entity.openai; + + +import lombok.Data; + +import java.util.List; + +@Data +public class AzureAIChatResponse { + private String id; + private String object; + private String created; + private String model; + private AzureAIUsage usage; + private List choices; +} \ No newline at end of file diff --git a/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIChoice.java b/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIChoice.java new file mode 100644 index 0000000000000000000000000000000000000000..fd67071d28dcd075443dbe24e3dc761afc339211 --- /dev/null +++ b/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIChoice.java @@ -0,0 +1,9 @@ +package com.kwan.springbootkwan.entity.openai; + + +import lombok.Data; + +@Data +public class AzureAIChoice { + private Object message; +} diff --git a/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIClient.java b/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIClient.java new file mode 100644 index 0000000000000000000000000000000000000000..5c4c70d0c906d721dabe305677b3b6146530581a --- /dev/null +++ b/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIClient.java @@ -0,0 +1,92 @@ +package com.kwan.springbootkwan.entity.openai; + +import cn.hutool.core.date.BetweenFormatter; +import cn.hutool.core.date.DateUnit; +import cn.hutool.core.date.DateUtil; +import cn.hutool.json.JSONUtil; +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; +import org.asynchttpclient.AsyncHttpClient; +import org.asynchttpclient.DefaultAsyncHttpClient; +import org.asynchttpclient.Request; +import org.asynchttpclient.RequestBuilder; +import org.asynchttpclient.Response; + +import java.io.Closeable; +import java.io.IOException; +import java.util.Date; +import java.util.concurrent.Future; + +@Slf4j +public class AzureAIClient implements Closeable { + private static final String JSON = "application/json; charset=UTF-8"; + private final boolean closeClient; + private final AsyncHttpClient client; + private final String deploymentName; + private final String url; + private final String token; + private final String apiVersion; + private boolean closed = false; + Gson gson = new Gson(); + + public AzureAIClient(String url, String apiKey, String deploymentName, String apiVersion) throws Exception { + this.client = new DefaultAsyncHttpClient(); + this.url = url + "/openai/deployments/" + deploymentName + "/"; + this.token = apiKey; + this.deploymentName = deploymentName; + this.apiVersion = apiVersion; + closeClient = true; + } + + public boolean isClosed() { + return closed || client.isClosed(); + } + + @Override + public void close() { + if (closeClient && !client.isClosed()) { + try { + client.close(); + } catch (IOException ex) { + } + } + closed = true; + } + + public AzureAIChatResponse sendChatRequest(AzureAIChatRequest chatRequest) throws Exception { + Date startDateOne = DateUtil.date(); + Future f = client.executeRequest(buildRequest("POST", "chat/completions?api-version=" + apiVersion, gson.toJson(chatRequest))); + Response r = f.get(); + Date endDateOne = DateUtil.date(); + // 获取开始时间和结束时间的时间差 + long betweenDateOne = DateUtil.between(startDateOne, endDateOne, DateUnit.MS); + // 格式化时间 + String formatBetweenOne = DateUtil.formatBetween(betweenDateOne, BetweenFormatter.Level.MILLISECOND); + log.info(String.format("请求数据耗时(毫秒):%s", formatBetweenOne)); + if (r.getStatusCode() != 200) { + log.info("Could not create chat request - server resposne was " + r.getStatusCode() + " to url: " + url + "chat/completions?api-version=2023-03-15-preview"); + return null; + } else { + Date startDate = DateUtil.date(); + AzureAIChatResponse azureAIChatResponse = JSONUtil.toBean(r.getResponseBody(), AzureAIChatResponse.class); + Date endDate = DateUtil.date(); + // 获取开始时间和结束时间的时间差 + long betweenDate = DateUtil.between(startDate, endDate, DateUnit.MS); + // 格式化时间 + String formatBetween = DateUtil.formatBetween(betweenDate, BetweenFormatter.Level.MILLISECOND); + log.info(String.format("格式化数据耗时(毫秒):%s", formatBetween)); + return azureAIChatResponse; + } + } + + private Request buildRequest(String type, String subUrl, String requestBody) { + RequestBuilder builder = new RequestBuilder(type); + Request request = builder.setUrl(this.url + subUrl) + .addHeader("Accept", JSON) + .addHeader("Content-Type", JSON) + .addHeader("api-key", this.token) + .setBody(requestBody) + .build(); + return request; + } +} \ No newline at end of file diff --git a/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIMessage.java b/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..7f1d530d4197dd66282fcc2c14ea2dc41d5d5686 --- /dev/null +++ b/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIMessage.java @@ -0,0 +1,9 @@ +package com.kwan.springbootkwan.entity.openai; + +import lombok.Data; + +@Data +public class AzureAIMessage { + private String role; + private String content; +} diff --git a/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIRole.java b/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIRole.java new file mode 100644 index 0000000000000000000000000000000000000000..e11ef620d13361116ba4a36832d1752519b46906 --- /dev/null +++ b/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIRole.java @@ -0,0 +1,24 @@ +package com.kwan.springbootkwan.entity.openai; + +import com.google.gson.annotations.SerializedName; + +public enum AzureAIRole { + + @SerializedName("assistant") + ASSISTANT("assistant"), + @SerializedName("system") + SYSTEM("system"), + @SerializedName("user") + USER("user"), + ; + private final String text; + + private AzureAIRole(final String text) { + this.text = text; + } + + @Override + public String toString() { + return text; + } +} \ No newline at end of file diff --git a/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIUsage.java b/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIUsage.java new file mode 100644 index 0000000000000000000000000000000000000000..44df7c4ba2f485b6d159c01db94c4b6709bb8b91 --- /dev/null +++ b/src/main/java/com/kwan/springbootkwan/entity/openai/AzureAIUsage.java @@ -0,0 +1,16 @@ +package com.kwan.springbootkwan.entity.openai; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +@Data +public class AzureAIUsage { + + @SerializedName("prompt_tokens") + private int promptTokens; + @SerializedName("completion_tokens") + private int completionTokens; + @SerializedName("total_tokens") + private int totalTokens; + +} diff --git a/src/main/java/com/kwan/springbootkwan/entity/openai/Main.java b/src/main/java/com/kwan/springbootkwan/entity/openai/Main.java new file mode 100644 index 0000000000000000000000000000000000000000..2a80d72da8cbf0d96abb28f762e763b0f086de13 --- /dev/null +++ b/src/main/java/com/kwan/springbootkwan/entity/openai/Main.java @@ -0,0 +1,53 @@ +package com.kwan.springbootkwan.entity.openai; + +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; + + +@Slf4j +public class Main { + + /** + * # 公司的key + * os.environ["OPENAI_API_KEY"] = '' + * os.environ["OPENAI_API_BASE"] = 'https://opencatgpt.openai.azure.com/' + * os.environ["OPENAI_API_TYPE"] = 'azure' + * os.environ["OPENAI_API_VERSION"] = '2023-05-15' + */ + public static void main(String[] args) throws Exception { + + // 装配请求集合 + List azureAiMessageList = new ArrayList<>(); + AzureAIChatRequest azureAiChatRequest = new AzureAIChatRequest(); + + AzureAIMessage azureAIMessage0 = new AzureAIMessage(); + azureAIMessage0.setRole(AzureAIRole.SYSTEM.toString()); + azureAIMessage0.setContent("你是一个AI机器人,请根据提问进行回答"); + + azureAiMessageList.add(azureAIMessage0); + execute(azureAiMessageList, azureAiChatRequest, "请解释一下java的多态"); + } + + private static void execute(List azureAiMessageList, AzureAIChatRequest azureAiChatRequest + , String question) throws Exception { + AzureAIMessage azureAIMessage1 = new AzureAIMessage(); + azureAIMessage1.setRole(AzureAIRole.USER.toString()); + azureAIMessage1.setContent(question); + azureAiMessageList.add(azureAIMessage1); + + azureAiChatRequest.setMessages(azureAiMessageList); + azureAiChatRequest.setMaxTokens(1024); + azureAiChatRequest.setTemperature(0.0); + // 是否进行留式返回 + azureAiChatRequest.setPresencePenalty(0); + azureAiChatRequest.setFrequencyPenalty(0); + azureAiChatRequest.setStop(null); + + AzureAIClient azureAIClient = new AzureAIClient("https://opencatgpt.openai.azure.com/", "", + "gpt-35-turbo", "2023-05-15"); + AzureAIChatResponse azureAIChatResponse = azureAIClient.sendChatRequest(azureAiChatRequest); + System.out.println(azureAIChatResponse.getChoices().get(0).getMessage()); + } +}