前期寻找java连接chatGPT的工具真的是找了很久,苦苦寻找。
最终在github找到了一个合适的,看得懂而且好用。
附上地址:
chatGPT API
懒得看的,直接看我代码,找核心代码自己copy使用即可。
先用maven导入依赖,不是maven的自己看上面github地址找。
gpt3.5 和 gpt4 都支持,api是这么写的。
Maven依赖:
<!-- 连接chatGPT工具-->
<!-- https://mvnrepository.com/artifact/com.theokanning.openai-gpt3-java/service -->
<dependency>
<groupId>com.theokanning.openai-gpt3-java</groupId>
<artifactId>service</artifactId>
<version>0.14.0</version>
</dependency>
核心代码:
//ChatMessage类很重要,是api中的。
List<ChatMessage> messages = new ArrayList<>();
//可以指定User角色或者System等角色,具体自行查询。
//有兴趣的可以了解langchain.
messages.add(new ChatMessage(ChatMessageRole.USER.value(), "给gpt发送的消息"));
ChatFunction build = ChatFunction.builder()
.name("Create_open_questions_to_the_text")
.description("Create a list of open questions and answers to the text")
.executor(ChatParameters.class, w -> new ChatParameters.OpenQuestionsToTxt(text, "text"))
.build();
//ChatParameters类看下面的代码块
List<ChatFunction> functionList = new ArrayList<>();
functionList.add(build);
FunctionExecutor functionExecutor = new FunctionExecutor(functionList);
ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
.model("gpt-3.5-turbo-16k")//引擎名,这里我使用的是3.5-16k的
.messages(messages)//消息列表,想要上下文聊天就在该list按顺序添加消息对象,自己研究下,比较简单
.maxTokens(10000) //最大token数 1个中文应该算3个token,具体看openAI官网,有计数器,可以换算token的数量,找不到的可以留言。
.functions(functionExecutor.getFunctions())//json返回
.functionCall(new ChatCompletionRequest.ChatCompletionRequestFunctionCall("auto"))//自动选择调用哪个函数
//auto : 代表让chatGPT自己决定调用你写的函数
//name代表函数的名字,在上面。
//Create_open_questions_to_the_text 就是一个函数
//这里例子只写了一个函数,如果有多个就涉及到如何调用,这个有些复杂,后面再讲。
.build();
List<ChatCompletionChoice> choices = null;
try {
//这里就是直接发送消息了,util文件我后面代码块也会附上
choices = OpenAiUtil.service.createChatCompletion(chatCompletionRequest).getChoices();
} catch (Exception e) {
e.printStackTrace();
}
if (choices != null && choices.size() > 0) {
// ObjectMapper 用来把chatGPT按我们要求返回的json数据转换
// gpt返回的是JsonNode,很难处理和提取数据,按照我这种方式可以轻松提取
ObjectMapper mapper = new ObjectMapper();
ChatMessage gptMessage = choices.get(0).getMessage();
gptMessage.getContent();//获取gpt回复的消息,这里是普通文本去处理,不使用函数就可以直接用这个拿到gpt的返回值即可。
ChatFunctionCall functionCall = gptMessage.getFunctionCall();
JsonNode arguments = functionCall.getArguments();
try {
String string = mapper.writeValueAsString(arguments);
//这里用的是hutool的JSONObject
//直接get key 就可以获取到对应的value,具体的自己试一下看看结构即可。
JSONObject entries = JSONUtil.parseObj(string);
System.out.println(entries);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
OpenAiUtil:
public class OpenAiUtil {
// 访问chatGPT 的key
private static final String token = "自己在openAi官网注册后获取自己的key,这里我取名叫token,也差不多意思吧,有免费试用额度,但是很少,花钱最合适,tb代充容易被封号,我被封过,建议尝试其他办法";
// 自动开启代理 自行修改端口
public static final Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7891));
// windows环境运行的时候,我自己电脑开了梯子,端口设置和上面这里的7891对应即可,也可以自己改自己喜欢的,无所谓的。
// 访问openai的json转化
public static final ObjectMapper mapper = defaultObjectMapper();
// 从gpt获取回复过期时间
public static final OkHttpClient client = defaultClient(token, Duration.ofSeconds(60))//这里我设置了60秒,自己可以换,小时,分钟,都可以
.newBuilder()
.proxy(proxy)
.build();
// 将json转化后进行http访问的规范化
public static final Retrofit retrofit = defaultRetrofit(client, mapper);
// 连接openAi
public static final OpenAiApi api = retrofit.create(OpenAiApi.class);
// 启动openAi服务
public static final OpenAiService service = new OpenAiService(api);
}
ChatParameters:
public class ChatParameters {
//这个类描述和使用起来比较复杂我会详细说明一下:
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 这里的参数都放需要chatGPT需要返回的json参数↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// @JsonPropertyDescription("questions")
// public List<String> questions;//多个问题,所以用list
//
// @JsonPropertyDescription("answers")
// public List<String> answers;//多个答案,所以用list
// 本例子中,我要做的是发送一段话,让gpt根据这段话自己创建问题和对应的答案,所有就会有questions和answers
// 上面这2个参数,如果用String类型,则只会生成一个问题和答案
// 如果用List的话就会有多个,但是问题和答案对应起来很麻烦
// 想知道结构的,自己试一下就知道了
// 所以我换成了JsonNode,其他的K - V 格式的参数应该也是可以,我没有试
// 最重要的是@JsonPropertyDescription注解
// 这个注解主要是告诉gpt你需要他把他生成的结果怎么展示
// 比如这里我就用一个qaMap来接收,我告诉他key放question,value放answer,他就直接每一条对应好了返回给我,非常智能。
@JsonPropertyDescription("questions and answers,key is question,value is answer")
public JsonNode qaMap;
// 这个内部类一定要创建,并且这是根据你自己的需求来传递参数的
// 在本例子中,我只需要传递给gpt一段文本即可,所以我用了text
// description是指对text这个参数的描述,在实际使用时可以加也可以不加,看你自己需求,这个无所谓的,function_all主要是指定使用哪个函数.
// 用一个类的构造器来传递需要告诉gpt的动态参数
public static class OpenQuestionsToTxt {
public String text;
public String description;
// 构造器
public OpenQuestionsToTxt(String text, String description) {
this.text = text;
this.description = description;
}
}
}
可能有些人有点懵逼了,这里放一下我参考的资料,大家比对着去看,了解下基础知识,function,function_all,name,等等.
https://zhuanlan.zhihu.com/p/637122720
https://zhuanlan.zhihu.com/p/641645157
2个url,自己看下。
教学到此结束.