Java 调用OpenAI完成聊天

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

一、openAI账号创建以及测试

1.账号

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

2.创建API KEY

在个人中心里面创建一下api密钥,这里要注意key只有创建时可以看到,创建完之后就不可见了,因此在创建时要注意复制保存,当然如果实在忘了,删除重新创建一个就行
在这里插入图片描述

二、配置Maven

  <dependency>
            <groupId>com.netflix.feign</groupId>
            <artifactId>feign-core</artifactId>
            <version>8.18.0</version>
        </dependency>
        <dependency>
            <groupId>com.netflix.feign</groupId>
            <artifactId>feign-jackson</artifactId>
            <version>8.18.0</version>
        </dependency>

        <dependency>
            <groupId>com.netflix.feign</groupId>
            <artifactId>feign-okhttp</artifactId>
            <version>8.18.0</version>
        </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,齐活~

### 配置和获取OpenAI API Key 在Spring项目中配置和获取OpenAI API Key涉及两个主要部分:一是正确设置`application.yml`文件中的属性;二是通过Java代码读取这些属性。 #### 1. 在 `application.yml` 文件中配置API密钥 为了使应用程序能够访问OpenAI服务,需将API密钥和其他必要参数添加至项目的`application.yml`文件内: ```yaml spring: application: name: spring-ai ai: openai: api-key: sk-proj-myfw5vSul******3YZlgehiw5A9 # 这里的值应替换为实际的Secret Key[^1] base-url: https://api.openai.com/v1 # OpenAI API的基础URL地址 ``` 此段落定义了一个名为`ai.openai.api-key`的属性用于存储API密钥,并指定了调用OpenAI接口所需的基本路径。 #### 2. 创建配置类来加载并提供API密钥 为了让其他组件可以轻松获得这个API密钥,在Spring应用中通常会创建一个专门负责管理外部资源连接信息的配置类。下面是一个简单的例子展示如何实现这一点: ```java package com.example.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; @Configuration public class AiConfig { @Value("${ai.openai.api-key}") private String apiKey; public String getApiKey() { return this.apiKey; } } ``` 上述代码片段展示了如何利用`@Configuration`注解声明一个新的Bean实例以及怎样借助于`@Value`注入来自YAML配置文件的具体值[^2]。 当需要使用该API密钥时,只需简单地将此类作为依赖项引入即可自动完成初始化过程。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿小张丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值