一篇文章教会你使用Java来完成一个属于自己的AI对话助手

 前言

随着ChatGPT的热度日渐增长,我也开始玩起了AI对话,但是为了不想每次使用chatgpt都需要科学上网等一系列麻烦的操作,所以我打算自己写一个Java对接chatgpt的微服务项目,接入的是chatgpt的3.5模型,但是由于chatgpt国内的限制,又为了防止自己科学上网的不稳定,所以选择对接的是一个别人创建的一个OpenAI的代理服务地址 api.openai-proxy.com

文章参考了保姆级JAVA对接ChatGPT教程,实现自己的AI对话助手 - 掘金 (juejin.cn)

代理地址的详细信息可以访问OpenAI API 代理 (openai-proxy.com)

一、前置工作

虽然可以通过代理地址访问chatgpt,但是我们还是需要一个ApiKey,那么怎么获得ApiKey呢

可以查看这两篇文章

ChatGPT保姆级注册教学 - 掘金 (juejin.cn)

如何获取chatGPT的Api-Key - 掘金 (juejin.cn)

记得需要先科学上网,或者可以购买一个香港服务器进行代理。

二、代码实现

配置文件和依赖

配置文件

open:
  ai:
    url: https://api.openai-proxy.com/
    ## API-Key
    token: xxx
session:
  time: 4
token:
  num: 1000

部分依赖

<!-- hutool  -->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.20</version>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.56</version>
</dependency>

2.1、工具包(常量类和gpt工具类)

常量

public class Constant {
    public static String CREATE_CHAT_COMPLETION = "v1/chat/completions";
    public static String API_KEY_PREFIX = "Bearer ";
}

chatgpt工具类

@Slf4j
@Component
public class OpenAiApi {

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

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

    @Value("${token.num}")
    private int tokenNum;

    /**
     * gpt请求参数实体封装
     *
     * @param list   列表
     * @param userId 用户id
     * @return {@link String}
     */
    public String ChatCompletionRequestBuilder(List<ChatMessage> list, String userId){
        //封装gpt请求参数实体类
        ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
                .model("gpt-3.5-turbo")
                .messages(list)
                .user(userId)
                .max_tokens(tokenNum)
                .temperature(1.0)
                .build();
        return JSONObject.toJSONString(chatCompletionRequest);
    }
 }

2.2、实体类(chatgpt的实体类和用户上下文以及对话的实体类)

实体类可以从保姆级JAVA对接ChatGPT教程,实现自己的AI对话助手 - 掘金 (juejin.cn)这篇文章查看,根据自己需要的实体类获取。

2.3、service层的实现

关于mapper等mp的基础操作在这里就不做过多展示,我是把数据存放在数据库中,可以根据自己的需求改造。

@Override
public ChatMessage postChatCompletion(String content, String userId) {
    //封装发送的消息存到list中
    final List<ChatMessage> list = userContextMapper.selectMessageForUser(userId);
    ChatMessage systemMessage = new ChatMessage(ChatMessageRole.USER.value(), content);
    //消息添加至上下文
    list.add(systemMessage);
    //获取gpt返回的内容
    String json = openAiApi.post(Constant.CREATE_CHAT_COMPLETION, list, userId);
    JSONObject jsonObject = JSONObject.parseObject(json);
    List<ChatCompletionChoice> choices = jsonObject.getJSONArray("choices").toJavaList(ChatCompletionChoice.class);
    //把内容封装到ChatMessage对象中
    ChatMessage context = new ChatMessage(choices.get(0).getMessage().getRole(), choices.get(0).getMessage().getContent());
    list.add(context);
    return context;
}

2.4、hutool工具库调用(向gpt的api发送请求)

/**
 * gpt请求发送
 *
 * @param path   路径
 * @param list   列表
 * @param userId 用户id
 * @return {@link String}
 */
public String post(String path, List<ChatMessage> list, String userId) {
    try {
        String body = HttpRequest.post(url + path)
                .header("Authorization", API_KEY_PREFIX+token)
                .header("Content-Type", "application/json")
                .timeout(10000)
                .setReadTimeout(10000) 
                .body(ChatCompletionRequestBuilder(list, userId))
                .execute()
                .body();
        if(!StringUtils.isNotBlank(body)){
            throw new ChatException("返回异常");
        }
        log.info(body);
        return body;
    }catch (HttpException | ConversionException httpException){
        log.info(httpException.getMessage());
    }
    return null;
}

总结

这篇文章是我chat服务的一个初始版,没有完成新会话和会话持久化等功能,完整代码在GitHub。

项目具体使用了SpringCloud、springsecurity、redis、minio等框架,完成了chatgpt对话上下文,使用hutool工具库进行请求,可以创建新对话或长时间后延续上次对话。

如果对我这个项目感兴趣或者想参与贡献的欢迎大家,觉得有用的记得给我的GitHub项目点个star

GitHub项目地址fsj0591/ChatBucket (github.com)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值