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();
    }
}
                


















