这段时间比较火的chatGPT,准确来说应该只是openAI的一个小部分,这里对openAI的功能接口进行一个java实现,以文本补全、聊天(也就是chatGPT)和图像生成作为演示,体会一下AI的强大力量。
一、openAI账号创建以及测试
1.账号
访问openai.com注册,按照提示输入注册就行,这里注意的就是需要外国手机号,还浪费了我几十块钱,可恶。。
2.创建token
在个人中心里面创建一下api密钥,这里要注意key只有创建时可以看到,创建完之后就不可见了,因此在创建时要注意复制保存,当然如果实在忘了,删除重新创建一个就行
3.简单测试demo
按照教程,下载zip,创建env文件并填写上面复制的API Key,然后,就可以使用指令运行了,这里我用的webstorm,在终端运行指令即可,得到地址在浏览器访问就可以看到一个简单的宠物起名字小网站啦
二、Java接口
1.官方推荐的各种社区开发语言接口
2.选择java客户端后导入依赖
可以看到版本为v0.11.0,在下面有maven的导入格式
<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>
或者也可以在一些大型的java依赖库中搜索包名,得到相应的引入方式,例如阿里云仓库,这里在maven中央仓库直接搜索chatGPT就可以得到,这样的导入方式会介绍的更加详细,不只是maven形式的导入
3.使用
将上面获取的open_ai_token存入常量token,使用下面命令即可连接到openAI的服务
OpenAiService service = new OpenAiService(token);
连接后用一个简单的命令测试一下:列出openAI的所有模型(对应官网)
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")); }
在测试证明了连接正常后,按照官网的结构开始尝试功能的实现,研究一下其实就可以发现这些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和它契合的也很好,就不再赘述,下面只是我的一个简短实现,一些重要参数也做了注解。
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); }
(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; }
演示
(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); }
总之还是挺好玩的,其他的功能也都差不多,大家可以参照官方文档慢慢研究,这里就不再赘述了~
三、总结
果然,官方文档YYDS!
转自:https://www.cnblogs.com/Studywith/p/17205139.html