chatGPT(openAI) Java版功能接口实现

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

一、openAI账号创建以及测试

1.账号

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


2.创建token

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

image


3.简单测试demo

官方文档

按照教程,下载zip,创建env文件并填写上面复制的API Key,然后,就可以使用指令运行了,这里我用的webstorm,在终端运行指令即可,得到地址在浏览器访问就可以看到一个简单的宠物起名字小网站啦

image

image

image



二、Java接口

1.官方推荐的各种社区开发语言接口

image


2.选择java客户端后导入依赖

可以看到版本为v0.11.0,在下面有maven的导入格式

image

<dependency>
            <groupId>com.theokanning.openai-gpt3-java</groupId>
            <artifactId>api</artifactId>
            <version>0.11.0</version>
        </dependency>
        <dependency>
            <groupId>com.theokanning.openai-gpt3-java</groupId>
            <artifactId>client</artifactId>
            <version>0.11.0</version>
        </dependency>
        <dependency>
            <groupId>com.theokanning.openai-gpt3-java</groupId>
            <artifactId>service</artifactId>
            <version>0.11.0</version>
        </dependency>

image

或者也可以在一些大型的java依赖库中搜索包名,得到相应的引入方式,例如阿里云仓库,这里在maven中央仓库直接搜索chatGPT就可以得到,这样的导入方式会介绍的更加详细,不只是maven形式的导入image


3.使用

将上面获取的open_ai_token存入常量token,使用下面命令即可连接到openAI的服务

OpenAiService service = new OpenAiService(token);

连接后用一个简单的命令测试一下:列出openAI的所有模型(对应官网)

image

public static void main(String[] args){
        showModels();
    }

    /**
     * 显示模型
     * 根据不同的功能和语言选择合适的模型,可以在官网的模型概述中查看
     * https://platform.openai.com/docs/models/overview
     */
    public static void showModels(){
        //列出所有模型实例
        System.out.println(service.listModels());
        //检索模型,得到模型实例,提供有关模型的基本信息,例如所有者和权限,应用场景等。
        System.out.println(service.getModel("text-davinci-003"));
    }

image

在测试证明了连接正常后,按照官网的结构开始尝试功能的实现,研究一下其实就可以发现这些javaAPI都已经在service里面封装好了,基本流程就是

创建request请求:在java中就是XXRequest request=XXRequest.builder.添加各种请求.build,这样就创建好了

发送请求获取响应结果:在java中就是XXResult result=service.createXX(request)

将响应结果中的数据取出:在java中就是按照响应结果的数据结构一层层拆开,result.getChoices()….

这里面的XX就对应了openAI的各种功能,现在看到这里可能看不懂,没关系,在后面各种功能实现时就会发现使用起来就是上面的步骤,十分简便易用。看完了回头再看这里就豁然开朗啦~


(1)文本补全

给定一个提示,该模型将返回一个或多个预测的完成,并且还可以返回每个位置的替代标记的概率

官方文档

(这里是用接口测试的方法通过controller层调用,在接口软件中测试,如果不使用controller层直接print输出即可,model使用的是text-davinci-003)

方法的重点就是解析请求和响应的结构以及其中的参数含义,这些在官网上非常完善,java和它契合的也很好,就不再赘述,下面只是我的一个简短实现,一些重要参数也做了注解。

image

public static DataResult getCompletion(String sentence){
//参数详细解释:https://platform.openai.com/docs/api-reference/completions/create
CompletionRequest completionRequest = CompletionRequest.builder()
//要使用的模型的ID
.model(completionModel)
//待补充的语句
.prompt(sentence)
//为每个提示生成多少完成结果
.n(2)
//API 将停止生成更多令牌的最多 4 个序列。返回的文本将不包含停止序列。
.echo(true)
.build();
CompletionResult result=service.createCompletion(completionRequest);
Map<String,String> r=new HashMap<>();
String text=result.getChoices().get(0).getText();
r.put("补全结果",text);
//添加令牌消耗结果
addToken(r, result);
return DataResult.data(r);
}

image


(2)聊天

给定聊天对话,模型将返回聊天完成响应
官方文档
消息必须是一个消息对象数组,其中每个对象都有一个角色(“系统”、“用户”或“助手”["system", "user", or "assistant"])和内容(消息的内容)
在一轮对话中,不断记录之前的聊天列表,并按照身份记录其发言,将chat列表传递给模型以实现聊天

(这个主要是注意记录对话过程,既要记录提问,又要记录回答,本质还是发送请求--记录响应,下面是我的实现思路)

public static List<ChatMessage> chatList=new ArrayList<>();
    public static String chatModel="gpt-3.5-turbo";
    public static String roleSystem="system";
    public static String roleUser="user";
    public static String roleAssistant="assistant";
/**
     * 一轮对话的完成
     * 以start为开始标志--true开始,以finish为结束标志--true结束,以chat为用户发送的聊天内容
     * @return 返回聊天回答和令牌消耗
     */
    public static DataResult getBatchChat(boolean start,boolean finish,String chat){
        if(start){
            //对话开始,初始化聊天列表为空
            chatList=new ArrayList<>();
        }
        if (finish){
            return DataResult.data(null);
        }
        //获取chatGPT的聊天结果,将结果添加到chat列表中
        Map<String,String> result=getOneChat(chat,roleUser);
        if (result != null) {
            getOneChat(result.get("回答"),roleAssistant);
        }
        return DataResult.data(result);
    }

    /**
     * 在一轮对话中,不断记录之前的聊天列表,并按照身份记录其发言,将chat列表传递给模型以实现聊天
     */
    public static Map<String,String> getOneChat(String newChat, String role){
        ChatMessage newMessage=new ChatMessage();
        newMessage.setRole(role);
        newMessage.setContent(newChat);
        chatList.add(newMessage);
        // 如果是助手角色,也就是chatGPT的回答结果,则不用发送request,只是用于存入chatList,不做其他工作
        if (roleAssistant.equals(role)){
            return null;
        }
        ChatCompletionRequest chatCompletionRequest= ChatCompletionRequest.builder()
                .model(chatModel)
                .messages(chatList)
                .build();
        ChatCompletionResult result=service.createChatCompletion(chatCompletionRequest);
        //根据响应的结构(可以在官网查看,也可以自行输出查看),获取返回结果中的第一个结果中的内容
        Map<String,String> r=new HashMap<>();
        String content=result.getChoices().get(0).getMessage().getContent();
        r.put("回答",content);
        addToken(r, result);
        return r;
    }

演示

image

image

image


(3)图像生成

根据语句描述获得图片
官方文档
返回图片url,创建图片的result返回中没有usage,可能图片API处于测试阶段没有消耗?

这个也是关注参数含义和返回结果就行了,比较简单,使用返回的url就可以访问图片

public static DataResult getNewImage(String information){
        CreateImageRequest createImageRequest= CreateImageRequest.builder()
                //所需图像的文本描述。最大长度为 1000 个字符。
                .prompt(information)
                //生成图像的大小。必须是256x256、512x512或1024x1024
                .size("1024x1024")
                //响应格式,生成的图像返回的格式。必须是url或b64_json,默认为url,url将在一小时后过期。
                .responseFormat("url")
                //要生成的图像数。必须介于 1 和 10 之间。
                .n(1)
                .build();
        ImageResult result=service.createImage(createImageRequest);
        Map<String,String> r=new HashMap<>();
        String url=result.getData().get(0).getUrl();
        r.put("图片链接",url);
        return DataResult.data(r);
    }

image

image

总之还是挺好玩的,其他的功能也都差不多,大家可以参照官方文档慢慢研究,这里就不再赘述了~


三、总结

果然,官方文档YYDS!



posted @ 2023-03-11 04:35  脑袋凉凉  阅读(11736)  评论(12编辑  收藏  举报