Java 调用OpenAI完成聊天

这段时间比较火的chatGPT,准确来说应该只是openAI的一个小部分,这里对openAI的功能接口进行一个java实现,以文本补全、聊天(也就是chatGPT)和图像生成作为演示,体会一下AI的强大力量。

一、openAI账号创建以及测试

1.账号

访问openai.com注册,按照提示输入注册就行,这里注意的就是需要外国手机号,还浪费了我几十块钱,可恶。。

2.创建API KEY

在个人中心里面创建一下api密钥,这里要注意key只有创建时可以看到,创建完之后就不可见了,因此在创建时要注意复制保存,当然如果实在忘了,删除重新创建一个就行
Java 调用OpenAI完成聊天_第1张图片

二、配置Maven

  <dependency>
            <groupId>com.netflix.feigngroupId>
            <artifactId>feign-coreartifactId>
            <version>8.18.0version>
        dependency>
        <dependency>
            <groupId>com.netflix.feigngroupId>
            <artifactId>feign-jacksonartifactId>
            <version>8.18.0version>
        dependency>

        <dependency>
            <groupId>com.netflix.feigngroupId>
            <artifactId>feign-okhttpartifactId>
            <version>8.18.0version>
        dependency>

三、配置yml文件

key就是OpenAI官网申请的API KEY

open-ai:
   url: https://api.openai.com/
   key: xxxxxxxxx

三、Controller(以流的方式返回)

@Api(tags = "客户端-客户管理")
@RestController
@RequestMapping("/client/chatUser")
public class ChatUserClientController {

    @Resource
    private ChatUserService chatUserService;

    /**
     * 返回数据流 优化用户体验
     * @return
     */

    @ApiOperation(value = "发送聊天",produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    @PostMapping("/sendMessage")
    public ResponseBodyEmitter sendMessageByStream(@RequestBody OpenAIChatSendMessage openAIChatSendMessage) {
        return chatUserService.sendMessage(openAIChatSendMessage);
    }

}

四、接口层

public interface ChatUserService extends IService<ChatUser>{
    ResponseBodyEmitter sendMessage(OpenAIChatSendMessage openAIChatSendMessage);
}

五、实现层

可以根据自己的需求在此处添加判断逻辑

  
@Service
public class ChatUserServiceImpl extends ServiceImpl<ChatUserMapper, ChatUser> implements ChatUserService {

    @Resource
    private OpenAIApiDao openAIApiDao;

    @Override
    public ResponseBodyEmitter sendMessage(OpenAIChatSendMessage openAIChatSendMessage) {
        List<OpenAIChatMessage> messages = openAIChatSendMessage.getMessages();
        if (CollectionUtils.isEmpty(messages) || messages.size() == 1) {
            throw new NingException(ServiceCode.FAILED);
        }
		// 可在次数加判断逻辑

        ResponseBodyEmitter emitter = new ResponseBodyEmitter();

        CompletableFuture.runAsync(() -> {
            	 // 调用 OpenAI 返回
                openAIChatSendMessage.setStream(true);

                Response response = openAIApiDao.sendChatByOpenAI(openAIChatSendMessage);

                try {
                    try (InputStream inputStream = response.body().asInputStream()) {
                        byte[] buffer = new byte[1024];
                        int bytesRead = -1;
                        while ((bytesRead = inputStream.read(buffer)) != -1) {
                            emitter.send(Arrays.copyOf(buffer, bytesRead));
                        }
                    } finally {
                        emitter.complete();
                        response.close();
                    }
                } catch (IOException e) {
                    emitter.completeWithError(e);
                }
        });


        return emitter;
    }
 }

六、OpenAIApiDao

public interface OpenAIApiDao {

    Response sendChatByOpenAI(OpenAIChatSendMessage openAIChatSendMessage);

}

七、feign初始化、调用

包含跳过https校验

@Slf4j
@Service
public class OpenAIApiDaoImpl implements OpenAIApiDao {

    private static OpenAIChatApi OPEN_AI_CHAT_API;

    @Value("${open-ai.url}")
    protected String url;

    @Value("${open-ai.key}")
    private String key;


    private static SSLSocketFactory createTrustAllSslSocketFactory(TrustManager[] trustManagers) throws NoSuchAlgorithmException, KeyManagementException {
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustManagers, new SecureRandom());
        return sslContext.getSocketFactory();
    }


    @PostConstruct
    @SneakyThrows
    protected void init() {

		// 跳过https校验

        // 1. 创建一个不进行任何证书校验的 TrustManager
        TrustManager[] trustAllCerts = new TrustManager[] {
                new X509TrustManager() {
                    public void checkClientTrusted(X509Certificate[] chain, String authType) {}
                    public void checkServerTrusted(X509Certificate[] chain, String authType) {}
                    public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
                }
        };

        // 2. 创建一个 OkHttpClient.Builder 对象,并将上面创建的 TrustManager 设置到 OkHttpClient.Builder 中
        OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .hostnameVerifier((hostname, session) -> true)
                .sslSocketFactory(createTrustAllSslSocketFactory(trustAllCerts), new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[0];
                    }
                });

        OPEN_AI_CHAT_API = Feign.builder()
                .client(new feign.okhttp.OkHttpClient(builder.build()))
                .decoder(new Decoder.Default())
                .encoder(new JacksonEncoder())
                .errorDecoder(new ErrorDecoder.Default())
                .target(OpenAIChatApi.class, url);

    }

    @Override
    public Response sendChatByOpenAI(OpenAIChatSendMessage openAIChatSendMessage) {

        return OPEN_AI_CHAT_API.sendChatMessage(key, openAIChatSendMessage);
    }
}

八、调用层

public interface OpenAIChatApi {

    /**
     * 聊天消息发送
     */

    @RequestLine("POST v1/chat/completions")
    @Headers({"Content-Type: application/json","Authorization: {key}","Accept: application/octet-stream"})
    Response sendChatMessage(@Param("key") String key, OpenAIChatSendMessage messages);

}

九、VO类

1.OpenAIChatMessage

@Data
public class OpenAIChatMessage {

    private String role;

    private String content;
}

2.OpenAIChatSendMessage

@Data
public class OpenAIChatSendMessage {

    @ApiModelProperty("消息记录")
    private List<OpenAIChatMessage> messages;


    @ApiModelProperty("是否使用流式传输")
    private Boolean stream;


    @ApiModelProperty("温度(准确率,温度越高消费时间约长)")
    private BigDecimal temperature;

    @ApiModelProperty("指定生成文本的概率阈值。这个参数可以控制生成文本的多样性,以避免生成过于相似的文本。")
    private BigDecimal top_p;
}

ok,齐活~

你可能感兴趣的:(ChatGPT,Java,java,chatgpt)