1. 前言
必须要有chatGTP 账号,如果需要测试账号可以关注公众号 疯狂的野猿
如果有chatGTP 账号就直接往下看。还需要一台外网服务器使用 nginx 代理来访问chatGTP 如果都没有,可以关注公众号联系作者。 还有笔者已经对接完成了,需要源码的关注公众号获取
2. 申请 API-Key的获取
2.1 获取Api-key
点击此链接获取 API-KEYS https://platform.openai.com/account/api-keys
1.点击图中 view API key
2. 点击 Create new secret key 创建新的key 将key 一定要复制出来,后期代码中需要。
2.创建一个 springboot 项目
2.1 导入chatGPT 依赖
国外友人已经对chatGPT 已经封装好,所以直接拿过来改造使用。
<dependency>
<groupId>com.theokanning.openai-gpt3-java</groupId>
<artifactId>api</artifactId>
<version>0.12.0</version>
</dependency>
<dependency>
<groupId>com.theokanning.openai-gpt3-java</groupId>
<artifactId>client</artifactId>
<version>0.12.0</version>
</dependency>
<dependency>
<groupId>com.theokanning.openai-gpt3-java</groupId>
<artifactId>service</artifactId>
<version>0.12.0</version>
</dependency>
2.2 导入成功之后修改 openai-gpt3-java 让接口可以访问chatGPT
2.2.1 重写 OpenAiService
因为OpenAiService 中 BASE_URL 是写死的,咋们需要代理,所有重写他。重写完成之后就可以正常调用了。
package com.github.binarywang.demo.wx.mp.service;
import com.theokanning.openai.OpenAiApi;
import com.theokanning.openai.service.AuthenticationInterceptor;
import com.theokanning.openai.service.OpenAiService;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.HttpException;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.jackson.JacksonConverterFactory;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
/**
* @ClassName MyOpenAiService
* @Description TODO
* @Author
* @Date 2023/3/25 15:25
* @Version 1.0
*/
public class MyOpenAiService extends OpenAiService {
private static String BASE_URL = "请求openAI的地址,nginx代理的地址";
private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(1000L);
private final OpenAiApi api;
public MyOpenAiService(String token,String baseUrl) {
this(token, DEFAULT_TIMEOUT,baseUrl);
}
public MyOpenAiService(String token, Duration timeout, String baseUrl) {
this(buildApi(token, timeout,baseUrl));
}
public MyOpenAiService(OpenAiApi api) {
super(api);
this.api = api;
}
public static OpenAiApi buildApi(String token, Duration timeout, String baseUrl) {
BASE_URL = baseUrl;
ObjectMapper mapper = defaultObjectMapper();
OkHttpClient client = defaultClient(token, timeout);
Retrofit retrofit = defaultRetrofit(client, mapper);
return (OpenAiApi)retrofit.create(OpenAiApi.class);
}
public static OkHttpClient defaultClient(String token, Duration timeout) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(new MyAuthenticationInterceptor(token))
.connectionPool(new ConnectionPool(5, 1L, TimeUnit.SECONDS))
.readTimeout(timeout.toMillis(), TimeUnit.MILLISECONDS);
// builder.addInterceptor(new HttpLogInterceptor());
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
});
OkHttpClient build = builder.build();
return build;
}
public static Retrofit defaultRetrofit(OkHttpClient client, ObjectMapper mapper) {
return (new retrofit2.Retrofit.Builder()).baseUrl(BASE_URL)
.client(client).addConverterFactory(JacksonConverterFactory.create(mapper))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build();
}
}
2.2.2 调用 MyOpenAiService
因为作者是和微信公众号打通所以 传了appid 如果正常使用无需传值。
package com.github.binarywang.demo.wx.mp.service.impl;
import com.github.binarywang.demo.wx.mp.service.MyOpenAiService;
import com.github.binarywang.demo.wx.mp.service.OpenAiServiceInterface;
import com.theokanning.openai.completion.CompletionRequest;
import com.theokanning.openai.completion.CompletionResult;
import com.theokanning.openai.completion.chat.*;
import com.theokanning.openai.edit.EditChoice;
import com.theokanning.openai.edit.EditRequest;
import com.theokanning.openai.edit.EditResult;
import com.theokanning.openai.model.Model;
import com.theokanning.openai.service.OpenAiService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
/**
* @ClassName OpenAiService
* @Description TODO
* @Author
* @Date 2023/3/22 21:46
* @Version 1.0
*/
@Service
public class OpenAiServiceImpl implements OpenAiServiceInterface {
private OpenAiService openAiService = null;
@Value("${openAi.OPENAI_TOKEN}")
private String OPENAI_TOKEN = "申请的openAI 的key ";
@Value("${openAi.BASE_URL}")
private String BASE_URL = "请求openAI的地址,nginx代理的地址";
List<ChatMessage> messages = new ArrayList<>();
@Override
public String buildChat(String appid,String content) throws NoSuchFieldException, IllegalAccessException {
if(Objects.isNull(openAiService)) {
openAiService = new MyOpenAiService(OPENAI_TOKEN,BASE_URL);
}
ChatMessage chatMessage = new ChatMessage(ChatMessageRole.USER.value(), content);
messages.add(chatMessage);
ChatCompletionRequest completionRequest = ChatCompletionRequest.builder()
.model("gpt-3.5-turbo")
.messages(messages)
.user(ChatMessageRole.USER.value())
.n(3)
.build();
ChatCompletionResult chatCompletion = openAiService.createChatCompletion(completionRequest);
List<ChatCompletionChoice> choiceList = chatCompletion.getChoices();
if(CollectionUtils.isEmpty(choiceList)) {
return null;
}
return choiceList.iterator().next().getMessage().getContent();
}
}