赞
踩
由于现在网上的相关教程并不多外加没有使用代理的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 */ public class TalkDto { @ApiModelProperty("内容") private String content; public String getContent() { return content; } public void setContent(String content) { this.content = content; } }
1、直接访问
优点
自定义且简便,具有高度的可玩性,所有openAi新增的入参都可以直接用。
缺点
过于硬核,官方文档为纯英文。已经有轮子了为什么还要自行造车轮呢?
正文
由于我自行封装了请求方式,所以不展示代理怎么进行插入,主要展示Body层,这里是最简单的Body入参。
Map<String, Object> bodyMap = new HashMap<>(); bodyMap.put("model", "gpt-3.5-turbo"); bodyMap.put("max_tokens", "4096"); { List<Map<String, String>> maps = new ArrayList<>(); // Map<String, String> systemMap = new HashMap<>(); // systemMap.put("role", "system"); // systemMap.put("content", "你是一个分析师"); // maps.add(systemMap); Map<String, String> contentMap = new HashMap<>(); contentMap.put("role", "user"); contentMap.put("content", talkDto.getContent()); maps.add(contentMap); bodyMap.put("messages", maps); } Map<String, String> headerMap = new HashMap<>(); 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") public ReTurnDto<String> talkByService(@RequestBody TalkDto talkDto) { //国内访问需要做代理,国外服务器不需要 Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("192.168.111.111", 1080)); HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new OpenAILogger()); httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient okHttpClient = new OkHttpClient.Builder().proxy(proxy)//自定义代理 .addInterceptor(httpLoggingInterceptor)//自定义日志输出 .addInterceptor(new OpenAiResponseInterceptor())//自定义返回值拦截 .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); return new ReTurnDto<>(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") public ReTurnDto<String> talkByOpen(@RequestBody TalkDto talkDto) { ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); //国内访问需要做代理,国外服务器不需要 Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 1549)); HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new OpenAILogger()); httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient client = new OkHttpClient.Builder().proxy(proxy)//自定义代理 .addInterceptor(new HttpLoggingInterceptor()).addInterceptor(httpLoggingInterceptor)//自定义日志输出 .addInterceptor(new AuthOpenAiInterceptor("123456789000"))//token .connectTimeout(10, TimeUnit.SECONDS)//自定义超时时间 .writeTimeout(3000, TimeUnit.SECONDS)//自定义超时时间 .readTimeout(3000, TimeUnit.SECONDS)//自定义超时时间 .build(); Retrofit retrofit = new Retrofit.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 = new OpenAiService(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-turbo ChatCompletionRequest chatCompletionRequest = new ChatCompletionRequest(); ChatMessage chatMessage = new ChatMessage(); 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); return new ReTurnDto<>(chatCompletion.getChoices().get(0).getMessage().getContent()); }
AuthOpenAiInterceptor 如下
import okhttp3.Interceptor; import okhttp3.Request; import okhttp3.Response; import java.io.IOException; /** * @author panx * @date 2023/3/30 14:22 */ public class AuthOpenAiInterceptor implements Interceptor { private final String token; public AuthOpenAiInterceptor(String token) { this.token = token; } public Response intercept(Interceptor.Chain chain) throws IOException { Request request = chain.request().newBuilder().header("Authorization", "Bearer " + this.token).build(); return chain.proceed(request); } }
TalkResultDto 如下
/** * @author panx * @date 2023/3/29 14:35 */ public class TalkResultDto { private String id; private String object; private Integer created; private String model; private UsageDto usage; private List<ChoicesDto> choices; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getObject() { return object; } public void setObject(String object) { this.object = object; } public Integer getCreated() { return created; } public void setCreated(Integer created) { this.created = created; } public String getModel() { return model; } public void setModel(String model) { this.model = model; } public UsageDto getUsage() { return usage; } public void setUsage(UsageDto usage) { this.usage = usage; } public List<ChoicesDto> getChoices() { return choices; } public void setChoices(List<ChoicesDto> choices) { this.choices = choices; } public static class UsageDto { private Integer prompt_tokens; private Integer completion_tokens; private Integer total_tokens; public Integer getPrompt_tokens() { return prompt_tokens; } public void setPrompt_tokens(Integer prompt_tokens) { this.prompt_tokens = prompt_tokens; } public Integer getCompletion_tokens() { return completion_tokens; } public void setCompletion_tokens(Integer completion_tokens) { this.completion_tokens = completion_tokens; } public Integer getTotal_tokens() { return total_tokens; } public void setTotal_tokens(Integer total_tokens) { this.total_tokens = total_tokens; } } public static class ChoicesDto { private MessageDto message; private String finish_reason; private Integer index; public MessageDto getMessage() { return message; } public void setMessage(MessageDto message) { this.message = message; } public String getFinish_reason() { return finish_reason; } public void setFinish_reason(String finish_reason) { this.finish_reason = finish_reason; } public Integer getIndex() { return index; } public void setIndex(Integer index) { this.index = index; } public static class MessageDto { private String role; private String content; public String getRole() { return role; } public void setRole(String role) { this.role = role; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } } } }
如果没有代理的话,可以去购买一个香港的服务器,将服务部署在香港服务器中
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。