Springboot接入OpenAi/Chat GPT的三种方式

这篇具有很好参考价值的文章主要介绍了Springboot接入OpenAi/Chat GPT的三种方式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

由于现在网上的相关教程并不多外加没有使用代理的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;
            }
        }
    }
}

如果没有代理的话,可以去购买一个香港的服务器,将服务部署在香港服务器中文章来源地址https://www.toymoban.com/news/detail-418560.html

畅爽使用~

到了这里,关于Springboot接入OpenAi/Chat GPT的三种方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【SpringBoot18】SpringBoot 调用外部接口的三种方式

    SpringBoot不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。在Spring-Boot项目开发中,存在着本模块的代码需要访问外面模块接口,或外部url链接的需求, 比如在apaas开发过程中需要封装接口在接口中调用apaas提供的接口(

    2023年04月11日
    浏览(77)
  • SpringBoot导出Word文档的三种方式

    1、直接在Java代码里创建Word文档,设置格式样式等,然后导出。(略) 需要的见:https://blog.csdn.net/qq_42682745/article/details/120867432 2、富文本转换后的HTML下载为Word文档。相当于把HTML转为Word导出 3、使用模板技术导出。固定格式、可以写入不同数据 其他: springboot版本:2.7.11 导

    2024年02月02日
    浏览(55)
  • SpringBoot获取HttpServletRequest、HttpServletResponse的三种方式

    仅仅适用在controller方法上。当Spring接收到HTTP请求时,会寻找一个合适的方法来处理该请求。如果该方法参数上标注了@RequestMapping或@Get、@Post等注解,Spring就会将HttpServletRequest对象注入到该参数中。 适用于所有的bean 通过调试可以看到,注入的Reques是一个代理类,而这个被代

    2024年02月19日
    浏览(48)
  • SpringBoot获取Request请求的三种方式

    Request对象包含了请求的各种信息,比如请求方法、请求URL、请求参数、请求内容等等,这些信息可以供服务器进行处理和响应。那么在SpringBoot中,怎么才能获取到Request对象? 本文将介绍三种方法,并提示例参考。 一、直接在Controller方法参数上注入HttpServletRequest 这是最常用

    2024年02月04日
    浏览(56)
  • Springboot中使用线程池的三种方式

    前言 多线程是每个程序员的噩梦,用得好可以提升效率很爽,用得不好就是埋汰的火葬场。 这里不深入介绍,主要是讲解一些标准用法,熟读唐诗三百首,不会作诗也会吟。 这里就介绍一下springboot中的多线程的使用,使用线程连接池去异步执行业务方法。 由于代码中包含详

    2024年02月08日
    浏览(46)
  • SpringBoot+MyBatis批量插入数据的三种方式

    最近导入表格数据时需要同时插入修改大量数据,研究了一下有三种实现方式 1、用for循环调用sql插入数据 这种方式插入大量数据时,效率非常底下,不推荐 2、利用mybatis的foreach来实现循环插入 这种方式插入大量数据时,好处是不用频繁访问数据库,一条sql搞定,效率比较

    2024年02月16日
    浏览(42)
  • SpringBoot实现过滤器Filter的三种方式

    过滤器 Filter 由 Servlet 提供,基于函数回调实现链式对网络请求与响应的拦截与修改。由于基于 Servlet ,其可以对web服务器管理的几乎所有资源进行拦截(JSP、图片文件、HTML 文件、CSS文件等)。 Filter 的生命周期 init(): 初始化Filter 实例,Filter 的生命周期与 Servlet 是相同的,

    2024年02月14日
    浏览(47)
  • idea社区版本创建springboot项目的三种方式

      文章目录 一、前言 一、方式1:spring 官方创建 springboot项目 1、打开在线的 spring initializr 2、选择项目的语言、版本、依赖等 3、 解压源码包,并使用IDEA打开 4、测试接口 二、方式2:社区idea安装Spring插件 1、添加插件 三、方式3:(麻烦)手动maven 创建springboot项目 一、前言

    2023年04月09日
    浏览(86)
  • 【SpringBoot】读取application.yml配置中的三种方式

    applicaiton.yml BootValueApplicationTests.java 打印如下所示 注意的地方 当对应的值不存在时,系统会报错。我们可以给定一个默认值即可。 如下所示: 在这里,sys.noValue这个值是不存在的,我们可以给定一个默认值为123,当然,我们如果不指定默认值的,它的默认值为空字符串。 优

    2024年02月13日
    浏览(53)
  • 生产项目中基于springboot项目解决循环依赖的三种方式

    在生产项目中,可以使用Spring Boot框架来快速开发Spring应用程序。Spring Boot提供了一种方便的方式来创建独立的,基于Spring的应用程序,并且有着高度的自动化配置和开箱即用的特性。 可以使用@Lazy注解来控制Bean的延迟初始化,同时可以使用AOP切面编程来解决循环依赖问题。

    2024年02月11日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包