最近為公司做了一個ChatGPT工具,這里展示一下OpenAI接口的調用
前提條件
訪問OpenAI官網(國內需要翻墻)的賬號,需要sk
地址:https://platform.openai.com
依賴
使用開源工具調用OpenAI接口,依賴如下:
<dependency><groupId>com.unfbx</groupId><artifactId>chatgpt-java</artifactId><version>1.1.2-beta0</version></dependency>
代碼示例
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;import com.unfbx.chatgpt.OpenAiClient;
import com.unfbx.chatgpt.entity.chat.ChatChoice;
import com.unfbx.chatgpt.entity.chat.ChatCompletion;
import com.unfbx.chatgpt.entity.chat.ChatCompletionResponse;
import com.unfbx.chatgpt.entity.chat.Message;
import com.unfbx.chatgpt.function.KeyRandomStrategy;
import com.unfbx.chatgpt.interceptor.OpenAILogger;
import com.unfbx.chatgpt.interceptor.OpenAiResponseInterceptor;
import com.unfbx.chatgpt.utils.TikTokensUtil;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okhttp3.logging.HttpLoggingInterceptor;import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;/*** 請求OpenAI接口示例*/
@Slf4j
public class OpenAIDemo {public static void main(String[] args) {getOpenAiResult("你好");}private static OpenAiResult getOpenAiResult(String questionContent) {OpenAiClient openAiClient = builderOpenAiClient();//聊天模型:gpt-3.5Message message = Message.builder().role(Message.Role.USER).content(questionContent).build();ChatCompletion chatCompletion = ChatCompletion.builder().messages(Collections.singletonList(message)).model(ChatCompletion.Model.GPT_3_5_TURBO_0613.getName()) //指定模型.build();ChatCompletionResponse chatCompletionResponse = openAiClient.chatCompletion(chatCompletion);List<ChatChoice> choices = chatCompletionResponse.getChoices();//獲取請求的tokens數量long tokens = chatCompletion.tokens();//這種方式也可以
// long tokens = TikTokensUtil.tokens(chatCompletion.getModel(),messages);log.info("Message集合文本:【{}】", questionContent);log.info("本地計算的請求的tokens數{}", tokens);log.info("本地計算的返回的tokens數{}", TikTokensUtil.tokens(chatCompletion.getModel(), chatCompletionResponse.getChoices().get(0).getMessage().getContent()));log.info("Open AI 官方計算的總的tokens數{}", chatCompletionResponse.getUsage().getTotalTokens());log.info("Open AI 官方計算的請求的tokens數{}", chatCompletionResponse.getUsage().getPromptTokens());log.info("Open AI 官方計算的返回的tokens數{}", chatCompletionResponse.getUsage().getCompletionTokens());OpenAiResult result = new OpenAiResult();result.setChatCompletion(chatCompletion).setChatCompletionResponse(chatCompletionResponse).setLocalToken(tokens).setCompletionTokens(chatCompletionResponse.getUsage().getCompletionTokens()).setTotalTokens(chatCompletionResponse.getUsage().getTotalTokens()).setPromptTokens(chatCompletionResponse.getUsage().getPromptTokens());if (CollUtil.isNotEmpty(choices)) {result.setContent(choices.get(0).getMessage().getContent());log.info("Open AI 官方計算的返回的結果{}", result.getContent());}return result;}private static OpenAiClient builderOpenAiClient() {Map<String, String> proxyUser = setProxyUser();//可以為nullProxy proxy = new Proxy(Proxy.Type.HTTP,new InetSocketAddress(proxyUser.get("PROXY_HOST"), Integer.valueOf(proxyUser.get("PROXY_PORT"))));//設置socks代理服務器ip端口Authenticator proxyAuthenticator = new Authenticator() {@Overridepublic Request authenticate(Route route, Response response) throws IOException {String credential = Credentials.basic(proxyUser.get("PROXY_USERNAME"), proxyUser.get("PROXY_PASSWORD"));return response.request().newBuilder().header("Proxy-Authorization", credential).build();}};HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new OpenAILogger());//!!!!千萬別再生產或者測試環境打開BODY級別日志!!!!//!!!生產或者測試環境建議設置為這三種級別:NONE,BASIC,HEADERS,!!!httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);OkHttpClient okHttpClient = new OkHttpClient.Builder().proxy(proxy).proxyAuthenticator(proxyAuthenticator).addInterceptor(httpLoggingInterceptor).addInterceptor(new OpenAiResponseInterceptor()).connectTimeout(60, TimeUnit.SECONDS).writeTimeout(60, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).build();OpenAiClient openAiClient = OpenAiClient.builder()//支持多key傳入,請求時候隨機選擇 openAiSk.apiKey(Arrays.asList("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"))
// .apiKey(Arrays.asList("sk-########"))//自定義key的獲取策略:默認KeyRandomStrategy.keyStrategy(new KeyRandomStrategy()).okHttpClient(okHttpClient)//自己做了代理就傳代理地址
// .apiHost("https://自己代理的服務器地址/").build();return openAiClient;}/**
*因為國內不能直接訪問OpenAI接口,必須通過翻墻工具訪問
*/private static Map<String, String> setProxyUser() {Map<String, String> proxyUser = MapUtil.newHashMap();proxyUser.put("PROXY_USERNAME", "****");proxyUser.put("PROXY_PASSWORD", "****");proxyUser.put("PROXY_HOST", "****");proxyUser.put("PROXY_PORT", "****");return proxyUser;}
}
import com.unfbx.chatgpt.entity.chat.ChatCompletion;
import com.unfbx.chatgpt.entity.chat.ChatCompletionResponse;
import lombok.Data;
import lombok.experimental.Accessors;@Data
@Accessors(chain = true)
public class OpenAiResult {/*** 本地接口請求信息*/private ChatCompletion chatCompletion;/*** OpenAI接口返回信息對象*/private ChatCompletionResponse chatCompletionResponse;/*** 本地請求計算的token*/private long localToken;/*** OpenAI接口返回信息*/private String content;/*** 官方計算的請求的tokens數*/private long promptTokens;/*** 官方計算的返回的tokens數{*/private long completionTokens;/*** 官方計算的總的tokens數*/private long totalTokens;
}