From 0e0caf3637207a8bf9a31ac11f379ade6806c795 Mon Sep 17 00:00:00 2001 From: unFbx <453701735@qq.com> Date: Mon, 25 Dec 2023 13:08:26 +0800 Subject: [PATCH] =?UTF-8?q?feature=201.1.6=20ChatCompletion=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E6=94=AF=E6=8C=81logprobs=E5=8F=82=E6=95=B0=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + README_EN.md | 1 + pom.xml | 2 +- .../entity/chat/BaseChatCompletion.java | 9 ++ .../unfbx/chatgpt/entity/chat/ChatChoice.java | 2 + .../unfbx/chatgpt/entity/chat/Logprob.java | 28 ++++ .../chatgpt/entity/chat/LogprobContent.java | 20 +++ .../chatgpt/v1_1_6/OpenAiClientTest.java | 141 ++++++++++++++++++ 8 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/unfbx/chatgpt/entity/chat/Logprob.java create mode 100644 src/main/java/com/unfbx/chatgpt/entity/chat/LogprobContent.java create mode 100644 src/test/java/com/unfbx/chatgpt/v1_1_6/OpenAiClientTest.java diff --git a/README.md b/README.md index 6c8ae3f..3c770c6 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ WebSocket参考:[OpenAIWebSocketEventSourceListener](https://github.com/Grt122 - 支持全部OpenAI的Api # 📑 更新日志 +- [x] 1.1.6 ChatCompletion接口支持logprobs参数设置 - [x] 1.1.5 Bug Fix - [x] 1.1.3 支持Assistant、Run、Thread、Message Api。测试案例[OpenAiClientTest](https://github.com/Grt1228/chatgpt-java/blob/develop/src/test/java/com/unfbx/chatgpt/v1_1_3/OpenAiClientTest.java) - [x] 1.1.2-beta0 支持附加图片的ChatCompletion、指定返回数据格式、Tool Call、Dall-e-3生成图片、FineTuneJob、文本转语音TTS。官方文档示例:[chatgpt-java.unfbx.com](https://chatgpt-java.unfbx.com/docs/category/-%E6%A0%B8%E5%BF%83%E5%8A%9F%E8%83%BD) 。测试案例[OpenAiClientTest](https://github.com/Grt1228/chatgpt-java/blob/develop/src/test/java/com/unfbx/chatgpt/v1_1_2/OpenAiClientTest.java) diff --git a/README_EN.md b/README_EN.md index 2ad842f..365d1fc 100644 --- a/README_EN.md +++ b/README_EN.md @@ -65,6 +65,7 @@ WebSocket Reference:[OpenAIWebSocketEventSourceListener](https://github.com/Gr - Supports all OpenAI APIs. # 📑 Update Log +- [x] 1.1.6 ChatCompletion api support logprobs param. - [x] 1.1.5 Bug Fix - [x] 1.1.3 Upgrade to support Assistant、Run、Thread、Message Api. eg: [OpenAiClientTest](https://github.com/Grt1228/chatgpt-java/blob/develop/src/test/java/com/unfbx/chatgpt/v1_1_3/OpenAiClientTest.java) - [x] 1.1.2-beta0 Upgrade to support chat completion with picture GPT-4V、return JSON model、Tool Call、Dall-e-3、Fine Tune Job、TTS. diff --git a/pom.xml b/pom.xml index b8aa41e..ae6f307 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.unfbx chatgpt-java - 1.1.5 + 1.1.6 chatgpt-java OpenAI Java SDK, OpenAI Api for Java. ChatGPT Java SDK . https://chatgpt-java.unfbx.com diff --git a/src/main/java/com/unfbx/chatgpt/entity/chat/BaseChatCompletion.java b/src/main/java/com/unfbx/chatgpt/entity/chat/BaseChatCompletion.java index 9e10138..071c168 100644 --- a/src/main/java/com/unfbx/chatgpt/entity/chat/BaseChatCompletion.java +++ b/src/main/java/com/unfbx/chatgpt/entity/chat/BaseChatCompletion.java @@ -145,6 +145,15 @@ public class BaseChatCompletion implements Serializable { * @since 1.1.2 */ private Integer seed; + /** + * @since 1.1.6 + */ + private Boolean logprobs; + /** + * @since 1.1.6 + */ + @JsonProperty("top_logprobs") + private Integer topLogprobs; /** diff --git a/src/main/java/com/unfbx/chatgpt/entity/chat/ChatChoice.java b/src/main/java/com/unfbx/chatgpt/entity/chat/ChatChoice.java index 6b1fb1e..649dd51 100644 --- a/src/main/java/com/unfbx/chatgpt/entity/chat/ChatChoice.java +++ b/src/main/java/com/unfbx/chatgpt/entity/chat/ChatChoice.java @@ -29,4 +29,6 @@ public class ChatChoice implements Serializable { private Message message; @JsonProperty("finish_reason") private String finishReason; + + private LogprobContent logprobs; } diff --git a/src/main/java/com/unfbx/chatgpt/entity/chat/Logprob.java b/src/main/java/com/unfbx/chatgpt/entity/chat/Logprob.java new file mode 100644 index 0000000..79b16aa --- /dev/null +++ b/src/main/java/com/unfbx/chatgpt/entity/chat/Logprob.java @@ -0,0 +1,28 @@ +package com.unfbx.chatgpt.entity.chat; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.List; + +/** + * 描述: + * + * @author https:www.unfbx.com + * @since 2023-12-25 + */ +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class Logprob implements Serializable { + private String token; + + private BigDecimal logprob; + + private List bytes; + + @JsonProperty("top_logprobs") + private List topLogprobs; +} diff --git a/src/main/java/com/unfbx/chatgpt/entity/chat/LogprobContent.java b/src/main/java/com/unfbx/chatgpt/entity/chat/LogprobContent.java new file mode 100644 index 0000000..3f852ea --- /dev/null +++ b/src/main/java/com/unfbx/chatgpt/entity/chat/LogprobContent.java @@ -0,0 +1,20 @@ +package com.unfbx.chatgpt.entity.chat; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 描述: + * + * @author https:www.unfbx.com + * @since 2023-12-25 + */ +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class LogprobContent implements Serializable { + + private List content; +} diff --git a/src/test/java/com/unfbx/chatgpt/v1_1_6/OpenAiClientTest.java b/src/test/java/com/unfbx/chatgpt/v1_1_6/OpenAiClientTest.java new file mode 100644 index 0000000..b1a70df --- /dev/null +++ b/src/test/java/com/unfbx/chatgpt/v1_1_6/OpenAiClientTest.java @@ -0,0 +1,141 @@ +package com.unfbx.chatgpt.v1_1_6; + + +import com.unfbx.chatgpt.FirstKeyStrategy; +import com.unfbx.chatgpt.OpenAiClient; +import com.unfbx.chatgpt.OpenAiStreamClient; +import com.unfbx.chatgpt.entity.chat.*; +import com.unfbx.chatgpt.function.KeyRandomStrategy; +import com.unfbx.chatgpt.interceptor.DynamicKeyOpenAiAuthInterceptor; +import com.unfbx.chatgpt.interceptor.OpenAILogger; +import com.unfbx.chatgpt.interceptor.OpenAiResponseInterceptor; +import com.unfbx.chatgpt.sse.ConsoleEventSourceListener; +import lombok.extern.slf4j.Slf4j; +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/** + * 描述: 测试类 + * + * @author https:www.unfbx.com + * 2023-12-25 + */ +@Slf4j +public class OpenAiClientTest { + + private OpenAiClient client; + private OpenAiStreamClient streamClient; + + + @Before + public void before() { + //可以为null +// Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890)); + HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new OpenAILogger()); + //!!!!千万别再生产或者测试环境打开BODY级别日志!!!! + //!!!生产或者测试环境建议设置为这三种级别:NONE,BASIC,HEADERS,!!! + httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS); + OkHttpClient okHttpClient = new OkHttpClient + .Builder() +// .proxy(proxy) + .addInterceptor(httpLoggingInterceptor) + .addInterceptor(new OpenAiResponseInterceptor()) + .connectTimeout(10, TimeUnit.SECONDS) + .writeTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .build(); + client = OpenAiClient.builder() + //支持多key传入,请求时候随机选择 + .apiKey(Arrays.asList("sk-*************************************")) + //自定义key的获取策略:默认KeyRandomStrategy + //.keyStrategy(new KeyRandomStrategy()) + .keyStrategy(new FirstKeyStrategy()) + .okHttpClient(okHttpClient) + //自己做了代理就传代理地址,没有可不不传,(关注公众号回复:openai ,获取免费的测试代理地址) + .apiHost("https://*************/") + .build(); + + streamClient = OpenAiStreamClient.builder() + //支持多key传入,请求时候随机选择 + .apiKey(Arrays.asList("sk-*************************************")) + //自定义key的获取策略:默认KeyRandomStrategy + .keyStrategy(new KeyRandomStrategy()) + .authInterceptor(new DynamicKeyOpenAiAuthInterceptor()) + .okHttpClient(okHttpClient) + //自己做了代理就传代理地址,没有可不不传,(关注公众号回复:openai ,获取免费的测试代理地址) + .apiHost("https://*********/") + .build(); + } + + /** + * 聊天模型支持图片流式示例 + */ + @Test + public void pictureChat() { + Content textContent = Content.builder().text("What’s in this image?").type(Content.Type.TEXT.getName()).build(); + ImageUrl imageUrl = ImageUrl.builder().url("https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg").build(); + Content imageContent = Content.builder().imageUrl(imageUrl).type(Content.Type.IMAGE_URL.getName()).build(); + List contentList = new ArrayList<>(); + contentList.add(textContent); + contentList.add(imageContent); + MessagePicture message = MessagePicture.builder().role(Message.Role.USER).content(contentList).build(); + ChatCompletionWithPicture chatCompletion = ChatCompletionWithPicture + .builder() + .messages(Collections.singletonList(message)) + .model(ChatCompletion.Model.GPT_4_VISION_PREVIEW.getName()) + .build(); + ChatCompletionResponse chatCompletionResponse = client.chatCompletion(chatCompletion); + chatCompletionResponse.getChoices().forEach(e -> System.out.println(e.getMessage())); + } + + + @Test + public void chat() { + //聊天模型:gpt-3.5 + Message message = Message.builder().role(Message.Role.USER).content("你好啊我的伙伴!").build(); + ChatCompletion chatCompletion = ChatCompletion + .builder() + .messages(Collections.singletonList(message)) + .model(ChatCompletion.Model.GPT_3_5_TURBO.getName()) + .logprobs(true) + .topLogprobs(2) + .build(); + ChatCompletionResponse chatCompletionResponse = client.chatCompletion(chatCompletion); + chatCompletionResponse.getChoices().forEach(e -> { + System.out.println(e.getMessage()); + }); + } + + + @Test + public void chatCompletions() { + ConsoleEventSourceListener eventSourceListener = new ConsoleEventSourceListener(); + Message message = Message.builder().role(Message.Role.USER).content("random one word!").build(); + ChatCompletion chatCompletion = ChatCompletion + .builder() + .model(ChatCompletion.Model.GPT_4_1106_PREVIEW.getName()) + .temperature(0.2) + .maxTokens(2048) + .messages(Collections.singletonList(message)) + .stream(true) + .logprobs(true) + .topLogprobs(2) + .build(); + streamClient.streamChatCompletion(chatCompletion, eventSourceListener); + CountDownLatch countDownLatch = new CountDownLatch(1); + try { + countDownLatch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +}