当前位置: 首页 > news >正文

【开源免费】ChatGPT-Java版SDK重磅更新收获2.3k,支持插件模式、实现ChatGpt联网操作。

everybody 七夕来了还单着么?

一、简介

ChatGPT Java版SDK开源地址:https://github.com/Grt1228/chatgpt-java,目前收获将近2200+个star🌟。

最新版:1.1.1-beta0

<dependency><groupId>com.unfbx</groupId><artifactId>chatgpt-java</artifactId><version>1.1.1-beta0</version>
</dependency>

二、特性支持

  • 支持GPT插件模式 参考实现 PluginTest
  • 支持当key异常(失效、过期、封禁)时,自定义动态处理key 参考实现DynamicKeyOpenAiAuthInterceptor
  • 支持当key异常时的告警处理(钉钉、飞书、email、企业微信等等需要自定义开发)参考实现DynamicKeyOpenAiAuthInterceptor
  • 支持多种Tokens计算方式
  • 支持自定义OkhttpClient
  • 支持自定义多Apikey
  • 支持自定义ApiKey的获取策略
  • 支持余额查询
  • 支持个人账户信息查询
  • 支持GPT3、GPT3.5、GPT4.0、GPT3.5—0614、GPT4.0—0614…
  • 支持全部OpenAI的Api

三、插件机制

本文重点介绍插件机制,原有功能使用可以参考官方文档

https://chatgpt-java.unfbx.com/

3.1、插件原理

ChatGpt在早些时候推出function call功能,这个在我看来其实就是插件的本质,通过自定义function实现插件的功能,SDK在1.0.14+版本的时候已经支持了原生的function call调用。但是function call调用逻辑比较复杂难懂,很多小伙伴反应不太会使用。于是我基于function call做了下定制封装实现Plugin功能。(可能存在不合理的地方欢迎指正)

3.2、使用步骤

想看示例的朋友可以直接看:PluginTest

3.2.1、简介——插件抽象类

插件抽象类,定义了插件的必须参数:插件名称,方法,描述,参数,必须参数,插件的请求值R,插件的返回值T
需要重点关注R和T两个泛型。

插件抽象类还包含两个重要的抽象方法: func和content方法。这两个方法需要自己实现。

方法功能
public abstract T func(R args);接受一个插件参数,返回插件返回值。后面有示例演示。
public abstract String content(T t);构建给gpt的参数信息

@Data
@AllArgsConstructor
public abstract class PluginAbstract<R extends PluginParam, T> {private Class<?> R;private String name;private String function;private String description;private List<Arg> args;private List<String> required;private Parameters parameters;public PluginAbstract(Class<?> r) {R = r;}public void setRequired(List<String> required) {if (CollectionUtil.isEmpty(required)) {this.required = this.getArgs().stream().filter(e -> e.isRequired()).map(Arg::getName).collect(Collectors.toList());return;}this.required = required;}private void setRequired() {if (CollectionUtil.isEmpty(required)) {this.required = this.getArgs().stream().filter(e -> e.isRequired()).map(Arg::getName).collect(Collectors.toList());}}private void setParameters() {JSONObject properties = new JSONObject();args.forEach(e -> {JSONObject param = new JSONObject();param.putOpt("type", e.getType());param.putOpt("enum", e.getEnumDictValue());param.putOpt("description", e.getDescription());properties.putOpt(e.getName(), param);});this.parameters = Parameters.builder().type("object").properties(properties).required(this.getRequired()).build();}public void setArgs(List<Arg> args) {this.args = args;setRequired();setParameters();}@Datapublic static class Arg {private String name;private String type;private String description;@JsonIgnoreprivate boolean enumDict;@JsonProperty("enum")private List<String> enumDictValue;@JsonIgnoreprivate boolean required;}public abstract T func(R args);public abstract String content(T t);
}

3.2.2、创建插件

创建自定义插件继承PluginAbstract抽象类。
WeatherReq,WeatherResp在这省略 。完整测试源码请看:https://github.com/Grt1228/chatgpt-java test包目录。

举例实现天气查询插件。

public class WeatherPlugin extends PluginAbstract<WeatherReq, WeatherResp> {public WeatherPlugin(Class<?> r) {super(r);}@Overridepublic WeatherResp func(WeatherReq args) {//模拟天气查询,真实使用场景需要调用第三方接口查询真实天气WeatherResp weatherResp = new WeatherResp();weatherResp.setTemp("25到28摄氏度");weatherResp.setLevel(3);return weatherResp;}@Overridepublic String content(WeatherResp weatherResp) {//构建chatgpt需要的content参数return "当前天气温度:" + weatherResp.getTemp() + ",风力等级:" + weatherResp.getLevel();}
}

3.2.3、使用插件

插件使用同样支持阻塞输出和流式输出两种方式,可以自己根据实际场景使用。

创建OpenAi客户端

客户端的创建和原来保持一致


/*** 描述: 插件测试类** @author https:www.unfbx.com* 2023-08-18*/
@Slf4j
public class PluginTest {private OpenAiClient openAiClient;private OpenAiStreamClient openAiStreamClient;@Beforepublic void before() {HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new OpenAILogger());//!!!!千万别再生产或者测试环境打开BODY级别日志!!!!//!!!生产或者测试环境建议设置为这三种级别:NONE,BASIC,HEADERS,!!!httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(httpLoggingInterceptor).addInterceptor(new OpenAiResponseInterceptor()).connectTimeout(10, TimeUnit.SECONDS).writeTimeout(30, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS).build();openAiClient = OpenAiClient.builder().okHttpClient(okHttpClient).apiKey(Arrays.asList("sk-********************************")).apiHost("https://dgr.life/").build();openAiStreamClient = OpenAiStreamClient.builder()//支持多key传入,请求时候随机选择.apiKey(Arrays.asList("sk-********************************")).apiHost("https://dgr.life/").build();}
}

流式输出

@Testpublic void streamPlugin() {WeatherPlugin plugin = new WeatherPlugin(WeatherReq.class);plugin.setName("知心天气");plugin.setFunction("getLocationWeather");plugin.setDescription("提供一个地址,方法将会获取该地址的天气的实时温度信息。");PluginAbstract.Arg arg = new PluginAbstract.Arg();arg.setName("location");arg.setDescription("地名");arg.setType("string");arg.setRequired(true);plugin.setArgs(Collections.singletonList(arg));//        Message message1 = Message.builder().role(Message.Role.USER).content("秦始皇统一了哪六国。").build();Message message2 = Message.builder().role(Message.Role.USER).content("获取上海市的天气现在多少度,然后再给出3个推荐的户外运动。").build();List<Message> messages = new ArrayList<>();
//        messages.add(message1);messages.add(message2);//默认模型:GPT_3_5_TURBO_16K_0613//有四个重载方法,都可以使用openAiStreamClient.streamChatCompletionWithPlugin(messages, new ConsoleEventSourceListener(), plugin);CountDownLatch countDownLatch = new CountDownLatch(1);try {countDownLatch.await();} catch (InterruptedException e) {e.printStackTrace();}}

阻塞输出

@Testpublic void plugin() {WeatherPlugin plugin = new WeatherPlugin(WeatherReq.class);plugin.setName("知心天气");plugin.setFunction("getLocationWeather");plugin.setDescription("提供一个地址,方法将会获取该地址的天气的实时温度信息。");PluginAbstract.Arg arg = new PluginAbstract.Arg();arg.setName("location");arg.setDescription("地名");arg.setType("string");arg.setRequired(true);plugin.setArgs(Collections.singletonList(arg));//        Message message1 = Message.builder().role(Message.Role.USER).content("秦始皇统一了哪六国。").build();Message message2 = Message.builder().role(Message.Role.USER).content("获取上海市的天气现在多少度,然后再给出3个推荐的户外运动。").build();List<Message> messages = new ArrayList<>();
//        messages.add(message1);messages.add(message2);//默认模型:GPT_3_5_TURBO_16K_0613//有四个重载方法,都可以使用ChatCompletionResponse response = openAiClient.chatCompletionWithPlugin(messages, plugin);log.info("自定义的方法返回值:{}", response.getChoices().get(0).getMessage().getContent());}

四、完结

上面已经完整介绍了整个插件的使用过程,方案不一定是最合理的,也是beat版本,欢迎交流。
如果觉的文章对你有帮助帮忙点个赞。

完整测试源码请看:https://github.com/Grt1228/chatgpt-java

记得帮忙点个star 🌟🌟🌟哦

首发微信号:程序员的黑洞

相关文章:

【开源免费】ChatGPT-Java版SDK重磅更新收获2.3k,支持插件模式、实现ChatGpt联网操作。

everybody 七夕来了还单着么&#xff1f; 一、简介 ChatGPT Java版SDK开源地址&#xff1a;https://github.com/Grt1228/chatgpt-java&#xff0c;目前收获将近2200个star&#x1f31f;。 最新版&#xff1a;1.1.1-beta0 <dependency><groupId>com.unfbx</g…...

情报与GPT技术大幅降低鱼叉攻击成本

邮件鱼叉攻击&#xff08;spear phishing attack&#xff09;是一种高度定制化的网络诈骗手段&#xff0c;攻击者通常假装是受害人所熟知的公司或组织发送电子邮件&#xff0c;以骗取受害人的个人信息或企业机密。 以往邮件鱼叉攻击需要花费较多的时间去采集情报、深入了解受…...

Swift 周报 第三十五期

文章目录 前言新闻和社区五天市值蒸发 2000 亿美元&#xff0c;苹果公司怎么了&#xff1f;在你的 App 中帮助顾客解决账单问题需要声明原因的 API 列表现已推出 提案通过的提案正在审查的提案 Swift论坛推荐博文话题讨论关于我们 前言 本期是 Swift 编辑组整理周报的第三十五…...

uni-app + SpringBoot +stomp 支持websocket 打包app

文章目录 一、概述&#xff1a;二、配置&#xff1a;1. 后端配置2. uni-app(app端)3. 使用 一、概述&#xff1a; websocket 协议是在http 协议的基础上的升级&#xff0c;通过一次http 请求建立长连接&#xff0c;转而变为TCP 的全双工通信&#xff1b;而http 协议是一问一答…...

LeetCode--HOT100题(35)

目录 题目描述&#xff1a;23. 合并 K 个升序链表&#xff08;困难&#xff09;题目接口解题思路1代码解题思路2代码 PS: 题目描述&#xff1a;23. 合并 K 个升序链表&#xff08;困难&#xff09; 给你一个链表数组&#xff0c;每个链表都已经按升序排列。 请你将所有链表合…...

idea插件grep console最佳实践

首发博客地址 https://blog.zysicyj.top/ 参考博客&#xff1a;https://blog.csdn.net/ayunnuo/article/details/123997304 效果 配置 具体颜色 日志级别前景色背景色Error#FF0000#370000Warn#FFC033#1A0037Info#00FFF3无Debug#808080无 本文由 mdnice 多平台发布...

Android 12 源码分析 —— 应用层 二(SystemUI大体组织和启动过程)

Android 12 源码分析 —— 应用层 二&#xff08;SystemUI大体组织和启动过程&#xff09; 在前一篇文章中&#xff0c;我们介绍了SystemUI怎么使用IDE进行编辑和调试。这是分析SystemUI的最基础&#xff0c;希望读者能尽量掌握。 本篇文章&#xff0c;将会介绍SystemUI的大概…...

【C#】通用类型转换

【C#】通用类型转换 自动类型转换&#xff08;隐式类型转换&#xff09;强制类型转换&#xff08;显式类型转换&#xff09;通过函数进行转换&#xff08;通过方法进行类型转换&#xff09;使用 as 操作符转换通用类型转换方法实现 数据类型转换就是将数据&#xff08;变量、数…...

传统DNS、负载均衡服务发现框架与专业服务发现框架(Eurek、nacos)分析

1、DNS 服务器 DNS 服务器可以在一定程度上用作服务发现的机制&#xff0c;以下是其冲动服务发现的一些利弊 优势 广泛性&#xff1a; DNS是互联网的标准协议之一&#xff0c;已经广泛地被支持和使用。因此&#xff0c;使用DNS作为服务发现的机制可以借助现有的网络基础设施…...

js中数组常用操作函数

js数组经常会用到&#xff0c;当涉及到 JavaScript 数组的函数&#xff0c;有许多常用的函数可用于对数组进行操作和转换。以下是一些常见的数组函数的讲解 splice() splice() 函数用于修改数组&#xff0c;可以删除、插入或替换数组中的元素。 var fruits [apple, banana,…...

Windows、Mac、Linux端口占用解决

Windows、Mac、Linux端口占用解决 简介 在使用计算机网络时&#xff0c;经常会遇到端口被占用的问题。当一个应用程序尝试使用已经被其他程序占用的端口时&#xff0c;会导致端口冲突&#xff0c;使应用程序无法正常运行。本文将介绍在Windows、Mac和Linux操作系统上解决端口…...

企业文件透明加密软件——「天锐绿盾」数据防泄密管理软件系统

PC访问地址&#xff1a; 首页 一、文档透明加密软件 文档透明加密功能&#xff1a;在不影响单位内部员工对电脑任何正常操作的前提下&#xff0c;文档在复制、新建、修改时被系统强制自动加密。文档只能在单位内部电脑上正常使用&#xff0c;在外部电脑上使用是乱码或无法打…...

Postman接口自动化测试实例

一.实例背景 在实际业务中&#xff0c;经常会出现让用户输入用户密码进行验证的场景。而为了安全&#xff0c;一般都会先请求后台服务器获取一个随机数做为盐值&#xff0c;然后将盐值和用户输入的密码通过前端的加密算法生成加密后串传给后台服务器&#xff0c;后台服务器接到…...

软件团队降本增效-构建人员评价体系

在软件团队中&#xff0c;最大成本往往来自于人力。这是因为软件开发是一项高度技术密集和智力密集的工作&#xff0c;需要研发人员具备较高的专业知识和技能。研发人员的工作状态和主动性对产出和质量具有极大的影响。如果研发人员缺乏积极性和投入度&#xff0c;可能会导致项…...

Python实现SSA智能麻雀搜索算法优化随机森林分类模型(RandomForestClassifier算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 麻雀搜索算法(Sparrow Search Algorithm, SSA)是一种新型的群智能优化算法&#xff0c;在2020年提出&a…...

web JS高德地图标点、点聚合、自定义图标、自定义窗体信息、换肤等功能实现和高复用性组件封装教程

文章目录 前言一、点聚合是什么&#xff1f;二、开发前准备三、API示例1.引入高德地图2.创建地图实例3.添加标点4.删除标点5.删除所有标点&#xff08;覆盖物&#xff09;6.聚合点7.自定义聚合点样式8.清除聚合9.打开窗体信息 四、实战开发需求要求效果图如下&#xff1a;封装思…...

AlpacaFarm: A Simulation Framework for Methods that Learn from Human Feedback

本文是LLM系列文章&#xff0c;针对《》的翻译。 AlpacaFarm:从人类反馈中学习方法的模拟框架 摘要1 引言2 背景与问题描述3 构造AlpacaFarm4 验证AlpacaFarm模拟器5 AlpacaFarm的基准参考方法6 相关工作7 不足和未来方向 摘要 像ChatGPT这样的大型语言模型由于能够很好地遵循…...

【Linux】Linux工具篇(yum、vim、gcc/g++、gdb、Makefile、git)

&#x1f680; 作者简介&#xff1a;一名在后端领域学习&#xff0c;并渴望能够学有所成的追梦人。 &#x1f681; 个人主页&#xff1a;不 良 &#x1f525; 系列专栏&#xff1a;&#x1f6f9;Linux &#x1f6f8;C &#x1f4d5; 学习格言&#xff1a;博观而约取&#xff…...

自己实现 SpringMVC 底层机制 系列之-实现任务阶段 5- 完成 Spring 容器对象的自动装配 -@Autowried

&#x1f600;前言 自己实现 SpringMVC 底层机制 系列之-实现任务阶段 5- 完成 Spring 容器对象的自动装配 -Autowried &#x1f3e0;个人主页&#xff1a;尘觉主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是尘觉&#xff0c;希望我的文章可以帮助到大家&…...

linux的http服务

Web通信基本概念 基于B/S&#xff08;Browser/Server&#xff09;架构的网页服务 服务端提供网页 浏览器下载并显示网页 Hyper Text Markup Lanuage,超文本标记语言 Hyper Text Transfer Protocol&#xff0c;超文本传输协议 虚拟机A&#xff1a;构建基本的Web服务 [root…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...