成都市网站公司,网站建设制作介绍河南,自己没有货源怎么开网店,深圳网站制作公司兴田德润在哪里文章目录 前言导包基本说明请求参数响应参数创建请求和响应的VO类 代码编写使用最后说明 前言
今天突然突发奇想#xff0c;就想要用java来调用chatget的接口#xff0c;实现自己的聊天机器人#xff0c;但是网上找文章#xff0c;属实是少的可怜(可能是不让发吧)。找到了… 文章目录 前言导包基本说明请求参数响应参数创建请求和响应的VO类 代码编写使用最后说明 前言
今天突然突发奇想就想要用java来调用chatget的接口实现自己的聊天机器人但是网上找文章属实是少的可怜(可能是不让发吧)。找到了一些文章但是基本都是通过调用别人的库来完成的导入其他的jar还有不低的学习成本于是就自己使用HttpClient5写了一个在这里讲解一下思路。
导包
对于http调用我使用的是比较流行的httpclient5然后直接创建了一个springboot项目方便以后对外提供接口。 parentartifactIdspring-boot-starter-parent/artifactIdgroupIdorg.springframework.boot/groupIdversion2.5.3/version/parentdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactId/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependency!-- https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5 --dependencygroupIdorg.apache.httpcomponents.client5/groupIdartifactIdhttpclient5/artifactIdversion5.2.1/version/dependency/dependencies基本说明
在编写代码之前这个先给出HttpClient的Api文档 api文档 我们在编写代码之前需要了解官方提供的接口如何进行访问以及返回的结果是什么
请求参数
官方文档地址为 文档请求参数必须填写的内容如下
{model: gpt-3.5-turbo,messages: [{role: user, content: Hello!}]
}一个是model一个是messages。model根据自己的情况来选择聊天的话就是gpt-3.5-turbo下面的messages里面包含n个对象每个对象有role和contentrole表示角色content表示内容。 下面为官方文档中的解释 简单理解就是我们要问问题role就是user。如果要实现连续对话那么就将返回的返回内容设置到messages中role设置为返回的role。
响应参数
下面直接给出响应的内容
{id: chatcmpl-6p9XYPYSTTRi0xEviKjjilqrWU2Ve,object: chat.completion,created: 1677649420,model: gpt-3.5-turbo,usage: {prompt_tokens: 56, completion_tokens: 31, total_tokens: 87},choices: [{message: {role: assistant,content: The 2020 World Series was played in Arlington, Texas at the Globe Life Field, which was the new home stadium for the Texas Rangers.},finish_reason: stop,index: 0}]
}我们问问题的答案就在choices.message下的content中而role就代表了chatGpt扮演的角色。看到这我们就应该知道该干嘛了吧肯定是创建对应的VO类啊。
创建请求和响应的VO类
下面5个类就对应了我们发送和接收的各种信息
ChatGptMessage类
Data
NoArgsConstructor
AllArgsConstructor
public class ChatGptMessage {String role;String content;
}ChatGptRequestParameter 类
Data
NoArgsConstructor
AllArgsConstructor
public class ChatGptRequestParameter {String model gpt-3.5-turbo;ListChatGptMessage messages new ArrayList();public void addMessages(ChatGptMessage message) {this.messages.add(message);}}ChatGptResponseParameter 类
Data
NoArgsConstructor
AllArgsConstructor
public class ChatGptResponseParameter {String id;String object;String created;String model;Usage usage;ListChoices choices;
}
Choices 类
Data
NoArgsConstructor
AllArgsConstructor
public class Choices {ChatGptMessage message;String finish_reason;Integer index;
}
Usage 类
Data
NoArgsConstructor
AllArgsConstructor
public class Usage {String prompt_tokens;String completion_tokens;String total_tokens;
}代码编写
不说废话首先创建一个CustomChatGpt类
public class CustomChatGpt {}然后定义一些成员属性 /*** 自己chatGpt的ApiKey*/private String apiKey;/*** 使用的模型*/private String model gpt-3.5-turbo-0301;/*** 对应的请求接口*/private String url https://api.openai.com/v1/chat/completions;/*** 默认编码*/private Charset charset StandardCharsets.UTF_8;/*** 创建一个ChatGptRequestParameter用于携带请求参数*/private ChatGptRequestParameter chatGptRequestParameter new ChatGptRequestParameter();提供一个ApiKey的构造器创建该对象必须要传入ApiKey public CustomChatGpt(String apiKey) {this.apiKey apiKey;}定义一个响应超时时间 /*** 响应超时时间毫秒*/private int responseTimeout 10000;public void setResponseTimeout(int responseTimeout) {this.responseTimeout responseTimeout;}编写一个getAnswer方法要求传入一个CloseableHttpClient和一个问题 public String getAnswer(CloseableHttpClient client, String question) {}继续实现方法下面会完成一些参数的创建和设置 // 创建一个HttpPostHttpPost httpPost new HttpPost(url);// 创建一个ObjectMapper用于解析和创建jsonObjectMapper objectMapper new ObjectMapper();// 设置请求参数chatGptRequestParameter.addMessages(new ChatGptMessage(user, question));HttpEntity httpEntity null;try {// 对象转换为json字符串httpEntity new StringEntity(objectMapper.writeValueAsString(chatGptRequestParameter), charset);} catch (JsonProcessingException e) {System.out.println(question -json转换异常);return null;}httpPost.setEntity(httpEntity);下面会完成一些配置的设置 // 设置请求头httpPost.setHeader(HttpHeaders.CONTENT_TYPE, application/json);// 设置登录凭证httpPost.setHeader(HttpHeaders.AUTHORIZATION, Bearer apiKey);// 用于设置超时时间RequestConfig config RequestConfig.custom().setResponseTimeout(responseTimeout, TimeUnit.MILLISECONDS).build();httpPost.setConfig(config);下面代码会提交请求解析响应最后返回对应问题的答案 try {// 提交请求return client.execute(httpPost, response - {// 得到返回的内容String resStr EntityUtils.toString(response.getEntity(), charset);// 转换为对象ChatGptResponseParameter responseParameter objectMapper.readValue(resStr, ChatGptResponseParameter.class);String ans ;// 遍历所有的Choices一般都只有一个for (Choices choice : responseParameter.getChoices()) {ChatGptMessage message choice.getMessage();chatGptRequestParameter.addMessages(new ChatGptMessage(message.getRole(), message.getContent()));String s message.getContent().replaceAll(\n, \n);ans s;}// 返回信息return ans;});} catch (IOException e) {e.printStackTrace();}// 发生异常移除刚刚添加的ChatGptMessagechatGptRequestParameter.getMessages().remove(chatGptRequestParameter.getMessages().size()-1);return 您当前的网络无法访问;下面给出这个类的完整代码
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ttpfx.vo.ChatGptMessage;
import com.ttpfx.vo.ChatGptRequestParameter;
import com.ttpfx.vo.ChatGptResponseParameter;
import com.ttpfx.vo.Choices;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;/*** author ttpfx* date 2023/3/23*/
public class CustomChatGpt {/*** 自己chatGpt的ApiKey*/private String apiKey;/*** 使用的模型*/private String model gpt-3.5-turbo-0301;/*** 对应的请求接口*/private String url https://api.openai.com/v1/chat/completions;/*** 默认编码*/private Charset charset StandardCharsets.UTF_8;/*** 创建一个ChatGptRequestParameter用于携带请求参数*/private ChatGptRequestParameter chatGptRequestParameter new ChatGptRequestParameter();/*** 相应超时时间毫秒*/private int responseTimeout 1000;public void setResponseTimeout(int responseTimeout) {this.responseTimeout responseTimeout;}public CustomChatGpt(String apiKey) {this.apiKey apiKey;}public String getAnswer(CloseableHttpClient client, String question) {// 创建一个HttpPostHttpPost httpPost new HttpPost(url);// 创建一个ObjectMapper用于解析和创建jsonObjectMapper objectMapper new ObjectMapper();// 设置请求参数chatGptRequestParameter.addMessages(new ChatGptMessage(user, question));HttpEntity httpEntity null;try {// 对象转换为json字符串httpEntity new StringEntity(objectMapper.writeValueAsString(chatGptRequestParameter), charset);} catch (JsonProcessingException e) {System.out.println(question -json转换异常);return null;}httpPost.setEntity(httpEntity);// 设置请求头httpPost.setHeader(HttpHeaders.CONTENT_TYPE, application/json);// 设置登录凭证httpPost.setHeader(HttpHeaders.AUTHORIZATION, Bearer apiKey);// 用于设置超时时间RequestConfig config RequestConfig.custom().setResponseTimeout(responseTimeout, TimeUnit.MILLISECONDS).build();httpPost.setConfig(config);try {// 提交请求return client.execute(httpPost, response - {// 得到返回的内容String resStr EntityUtils.toString(response.getEntity(), charset);// 转换为对象ChatGptResponseParameter responseParameter objectMapper.readValue(resStr, ChatGptResponseParameter.class);String ans ;// 遍历所有的Choices一般都只有一个for (Choices choice : responseParameter.getChoices()) {ChatGptMessage message choice.getMessage();chatGptRequestParameter.addMessages(new ChatGptMessage(message.getRole(), message.getContent()));String s message.getContent().replaceAll(\n, \n);ans s;}// 返回信息return ans;});} catch (IOException e) {e.printStackTrace();}// 发生异常移除刚刚添加的ChatGptMessagechatGptRequestParameter.getMessages().remove(chatGptRequestParameter.getMessages().size()-1);return 您当前的网络无法访问;}
}使用
下面就是测试代码我们只需要传入一个CloseableHttpClient 和 question 即可
public class Test {public static void main(String[] args) throws IOException {CloseableHttpClient httpClient HttpClients.createDefault();String apiKey 自己的ApiKey;CustomChatGpt customChatGpt new CustomChatGpt(apiKey);// 根据自己的网络设置吧customChatGpt.setResponseTimeout(20000);while (true) {System.out.print(\n请输入问题(q退出));String question new Scanner(System.in).nextLine();if (q.equals(question)) break;long start System.currentTimeMillis();String answer customChatGpt.getAnswer(httpClient, question);long end System.currentTimeMillis();System.out.println(该回答花费时间为 (end - start) / 1000.0 秒);System.out.println(answer);}httpClient.close();}
}下面为运行图片 最后说明
对于ApiKey只能说难者不会会者不难这个没办法教。
如果代码无法运行或者运行速度及其缓慢请使用代理在HttpClient里面可以很轻松的使用代理 String proxyIp 127.0.0.1;int proxyPort 7890;HttpHost httpHost new HttpHost(proxyIp, proxyPort);上面就是一个示例对于代理这里也就无法继续进行说明了。
如果我们完成了上面的功能是不是就能够对外提供接口然后写一个自己的网页端的ChatGpt或者弄一个聊天机器人呢当然没问题啊 2023/3/27 23:27更新
很多人找我要这个小程序的demo其实源代码上面都已经给出了。既然有人问那么就给出这个demo的github地址 git地址
使用指令 git clone https://github.com/c-ttpfx/chatGPT.git 可以轻松的下载到本地 2023/3/31 19:54更新 上面这个代码大家应该发现了问题就是返回很慢原因就是我们请求不是异步的是等待所有答案都给出了再返回所以速度很慢并且容易出现超时。
解决方法就是使用异步请求大家请参照 使用chatgpt实现微信聊天小程序(秒回复)github开源(附带链接) 基本可以实现秒回复
2023/3/31 14:40更新 最新的代码已经支持代理参考使用chatgpt实现微信聊天小程序(秒回复)github开源(附带链接)