由于现在网上的相关教程并不多外加没有使用代理的demo,所以抛砖引玉,写了三种调用方式,分别是直接访问、非官方SDK访问、官方开源的SDK访问
准备工作
1、导入pom文件(2023.3.30最新版本)
<dependency><groupId>com.unfbx</groupId><artifactId>chatgpt-java</artifactId><version>1.0.8</version></dependency><dependency><groupId>com.theokanning.openai-gpt3-java</groupId><artifactId>service</artifactId><version>0.11.1</version></dependency>
2、入参
这里的TalkDto 还可以入参maxToken,用于返回最大量的数据,官方计算token大小的方式:中文1字=3token 英文4字=1token。例如: 哈 = 3;ha=1;哈ha=4;哈ha哈h=8
官方计算token地址:https://platform.openai.com/tokenizer
/**
* @author panx
* @date 2023/3/29 13:52
*/publicclassTalkDto{@ApiModelProperty("内容")privateString content;publicStringgetContent(){return content;}publicvoidsetContent(String content){this.content = content;}}
正文
1、直接访问
- 优点自定义且简便,具有高度的可玩性,所有openAi新增的入参都可以直接用。
- 缺点过于硬核,官方文档为纯英文。已经有轮子了为什么还要自行造车轮呢?
- 正文
由于我自行封装了请求方式,所以不展示代理怎么进行插入,主要展示Body层,这里是最简单的Body入参。
Map<String,Object> bodyMap =newHashMap<>();
bodyMap.put("model","gpt-3.5-turbo");
bodyMap.put("max_tokens","4096");{List<Map<String,String>> maps =newArrayList<>();// Map<String, String> systemMap = new HashMap<>();// systemMap.put("role", "system");// systemMap.put("content", "你是一个分析师");// maps.add(systemMap);Map<String,String> contentMap =newHashMap<>();
contentMap.put("role","user");
contentMap.put("content", talkDto.getContent());
maps.add(contentMap);
bodyMap.put("messages", maps);}Map<String,String> headerMap =newHashMap<>();
headerMap.put("Content-Type","application/json");
headerMap.put("Authorization","Bearer 123456789");
出参可以参考官方文档(https://platform.openai.com/docs/api-reference/chat)或下面的TalkResultDto
2、使用com.unfbx.chatgpt-java
- 项目地址
https://github.com/Grt1228/chatgpt-java
- 优点
纯中文文档,网上的demo也很多,更新速度也快,针对中国玩家的使用更便捷。
- 缺点
不支持别的类型的请求?粗略的找了一下没有找到。
有一些默认值无法去除,而不去除某一些值在长段入参中可能会报错,如果需要去除可能要等更新或自行去https://platform.openai.com/playground调试模型。
- 正文
@ApiOperation("非官方聊天api捏")@PostMapping("/talkByService")publicReTurnDto<String>talkByService(@RequestBodyTalkDto talkDto){//国内访问需要做代理,国外服务器不需要Proxy proxy =newProxy(Proxy.Type.HTTP,newInetSocketAddress("192.168.111.111",1080));HttpLoggingInterceptor httpLoggingInterceptor =newHttpLoggingInterceptor(newOpenAILogger());
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);OkHttpClient okHttpClient =newOkHttpClient.Builder().proxy(proxy)//自定义代理.addInterceptor(httpLoggingInterceptor)//自定义日志输出.addInterceptor(newOpenAiResponseInterceptor())//自定义返回值拦截.connectTimeout(10,TimeUnit.SECONDS)//自定义超时时间.writeTimeout(3000,TimeUnit.SECONDS)//自定义超时时间.readTimeout(3000,TimeUnit.SECONDS)//自定义超时时间.build();//构建客户端OpenAiClient openAiClient =OpenAiClient.builder()//构建.apiKey(Collections.singletonList("1234577987645"))//token.okHttpClient(okHttpClient)//注入okhttp.build();Message message =Message.builder().role(Message.Role.USER).content(talkDto.getContent()).build();ChatCompletion.ChatCompletionBuilder builder =ChatCompletion.builder();//聊天模型:gpt-3.5
builder.model("gpt-3.5-turbo");
builder.messages(Arrays.asList(message));ChatCompletion chatCompletion = builder.build();ChatCompletionResponse chatCompletionResponse = openAiClient.chatCompletion(chatCompletion);returnnewReTurnDto<>(chatCompletionResponse.getChoices().get(0).getMessage().getContent());}
3、使用com.theokanning.openai-gpt3-java.service
- 项目地址
https://github.com/TheoKanning/openai-java
- 优点
官方SDK。各种类型的请求都有单独的实体类,使用起来非常便捷。
- 缺点
更新速度没有上面的快,官方文档不太清晰。由于使用了 Retrofit+OkHttp 中国玩家需要进行繁琐的配置才能使用。
- 正文
@ApiOperation("官方api聊天捏")@PostMapping("/talkByOpen")publicReTurnDto<String>talkByOpen(@RequestBodyTalkDto talkDto){ObjectMapper mapper =newObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);//国内访问需要做代理,国外服务器不需要Proxy proxy =newProxy(Proxy.Type.HTTP,newInetSocketAddress("127.0.0.1",1549));HttpLoggingInterceptor httpLoggingInterceptor =newHttpLoggingInterceptor(newOpenAILogger());
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);OkHttpClient client =newOkHttpClient.Builder().proxy(proxy)//自定义代理.addInterceptor(newHttpLoggingInterceptor()).addInterceptor(httpLoggingInterceptor)//自定义日志输出.addInterceptor(newAuthOpenAiInterceptor("123456789000"))//token.connectTimeout(10,TimeUnit.SECONDS)//自定义超时时间.writeTimeout(3000,TimeUnit.SECONDS)//自定义超时时间.readTimeout(3000,TimeUnit.SECONDS)//自定义超时时间.build();Retrofit retrofit =newRetrofit.Builder()//构建者.client(client).baseUrl("https://api.openai.com/")//url.addConverterFactory(JacksonConverterFactory.create(mapper))//jackson.addCallAdapterFactory(RxJava2CallAdapterFactory.create())//.build();OpenAiApi api = retrofit.create(OpenAiApi.class);OpenAiService service =newOpenAiService(api);//text-davinci-003/* CompletionRequest completionRequest = CompletionRequest.builder()
.prompt(talkDto.getContent())
.model("text-davinci-003")
.maxTokens(2060)
.build();
CompletionResult completion = service.createCompletion(completionRequest);
return new ResponseVo<>(completion.getChoices().get(0).getText());*///gpt-3.5-turboChatCompletionRequest chatCompletionRequest =newChatCompletionRequest();ChatMessage chatMessage =newChatMessage();
chatMessage.setRole(ChatMessageRole.USER.value());
chatMessage.setContent(talkDto.getContent());
chatCompletionRequest.setModel("gpt-3.5-turbo");
chatCompletionRequest.setMessages(Collections.singletonList(chatMessage));ChatCompletionResult chatCompletion = service.createChatCompletion(chatCompletionRequest);returnnewReTurnDto<>(chatCompletion.getChoices().get(0).getMessage().getContent());}
后期工作
AuthOpenAiInterceptor 如下
importokhttp3.Interceptor;importokhttp3.Request;importokhttp3.Response;importjava.io.IOException;/**
* @author panx
* @date 2023/3/30 14:22
*/publicclassAuthOpenAiInterceptorimplementsInterceptor{privatefinalString token;publicAuthOpenAiInterceptor(String token){this.token = token;}publicResponseintercept(Interceptor.Chain chain)throwsIOException{Request request = chain.request().newBuilder().header("Authorization","Bearer "+this.token).build();return chain.proceed(request);}}
TalkResultDto 如下
/**
* @author panx
* @date 2023/3/29 14:35
*/publicclassTalkResultDto{privateString id;privateString object;privateInteger created;privateString model;privateUsageDto usage;privateList<ChoicesDto> choices;publicStringgetId(){return id;}publicvoidsetId(String id){this.id = id;}publicStringgetObject(){return object;}publicvoidsetObject(String object){this.object = object;}publicIntegergetCreated(){return created;}publicvoidsetCreated(Integer created){this.created = created;}publicStringgetModel(){return model;}publicvoidsetModel(String model){this.model = model;}publicUsageDtogetUsage(){return usage;}publicvoidsetUsage(UsageDto usage){this.usage = usage;}publicList<ChoicesDto>getChoices(){return choices;}publicvoidsetChoices(List<ChoicesDto> choices){this.choices = choices;}publicstaticclassUsageDto{privateInteger prompt_tokens;privateInteger completion_tokens;privateInteger total_tokens;publicIntegergetPrompt_tokens(){return prompt_tokens;}publicvoidsetPrompt_tokens(Integer prompt_tokens){this.prompt_tokens = prompt_tokens;}publicIntegergetCompletion_tokens(){return completion_tokens;}publicvoidsetCompletion_tokens(Integer completion_tokens){this.completion_tokens = completion_tokens;}publicIntegergetTotal_tokens(){return total_tokens;}publicvoidsetTotal_tokens(Integer total_tokens){this.total_tokens = total_tokens;}}publicstaticclassChoicesDto{privateMessageDto message;privateString finish_reason;privateInteger index;publicMessageDtogetMessage(){return message;}publicvoidsetMessage(MessageDto message){this.message = message;}publicStringgetFinish_reason(){return finish_reason;}publicvoidsetFinish_reason(String finish_reason){this.finish_reason = finish_reason;}publicIntegergetIndex(){return index;}publicvoidsetIndex(Integer index){this.index = index;}publicstaticclassMessageDto{privateString role;privateString content;publicStringgetRole(){return role;}publicvoidsetRole(String role){this.role = role;}publicStringgetContent(){return content;}publicvoidsetContent(String content){this.content = content;}}}}
如果没有代理的话,可以去购买一个香港的服务器,将服务部署在香港服务器中
畅爽使用~
版权归原作者 紫薯千层糕 所有, 如有侵权,请联系我们删除。