java接入gpt开发

前情提要

本次文章使用编译器为IDEA2020

使用GPT模型为百度旗下的千帆大模型

如果是个人用或者不流传出去,可以无脑入,因为会免费送20块钱(够用上万次)

代金卷查看

正式教程:

百度智能云控制台 (baidu.com)

按照步骤创建什么都不要担心

获取AccessToken 
无论是实现调用免费的接口还是付费接口,都要先获取AccessToken,目的是鉴权。

查看对应文档获取access_token 获取access_token - 千帆大模型平台 | 百度智能云文档 (baidu.com)

根据文档我们知道我们向接口发起一个POST请求。一个请求头以及三个Query参数。

首先我们在pom文件中导入了如下jar包

    <dependencies>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.8.1</version>
        </dependency>
 
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.19</version>
        </dependency>
 
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.36</version>
        </dependency>
 
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
        </dependency>
    </dependencies>

编写测试获取AccessToken的方法 

@Slf4j
public class Chat {
    private final String ACCESS_TOKEN_URI = "https://aip.baidubce.com/oauth/2.0/token";
 
    private String apiKey = "yourApikey";
    private String secretKey = "yourSecetkey";
    private String accessToken;
 
    private OkHttpClient client = new OkHttpClient();
 
    public boolean getAccessToken(){
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, "");
        //创建一个请求
        Request request = new Request.Builder()
                .url(ACCESS_TOKEN_URI+"?client_id=" + apiKey + "&client_secret=" + secretKey + "&grant_type=client_credentials")
                .method("POST",body)
                .addHeader("Content-Type", "application/json")
                .build();
        try {
            //使用浏览器对象发起请求
            Response response = client.newCall(request).execute();
            //只能执行一次response.body().string()。下次再执行会抛出流关闭异常,因此需要一个对象存储返回结果
            String responseMessage = response.body().string();
            log.debug("获取accessToken成功");
            JSONObject jsonObject = JSON.parseObject(responseMessage);
            accessToken = (String) jsonObject.get("access_token");
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
}

我们将调用的获取AccessToken接口获取到的信息转为JSON格式后,获取access_token属性值,复制给类属性。 

测试

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Chat chat = new Chat();
        boolean result = chat.getAccessToken();
        System.out.println(result);
    }
}

19:46:13,387 DEBUG Chat:48 - 获取accessToken成功
true

实现Prompt模板接口调用

Prompt模板 - 千帆大模型平台 | 百度智能云文档 (baidu.com)查看对应文档Prompt模板 - 千帆大模型平台 | 百度智能云文档 (baidu.com)

要想调用该接口,我们需要事先创建好Promet模板。创建模板过程如下

创建好模板后,我们后续需要调用模板ID。

具体实现代码如下

    /**
     * 调用Prompt接口
     * @param param
     */
    public void getPrompt(int id,String param){
        Request request = new Request.Builder()
//        https://aip.baidubce.com/rest/2.0/wenxinworkshop/api/v1/template/info?access_token=xxx&id=7964&name=value
                .url(CHAT_URI + "?access_token="+accessToken+"&id="+id+"&name="+param)
                .addHeader("Content-Type", "application/json")
                .method("GET",null)
                .build();
        try {
            Response responseMessage = client.newCall(request).execute();
            JSONObject jsonObject = JSON.parseObject(responseMessage.body().string());
            log.debug(jsonObject.toString());
            Object result = jsonObject.get("result");
            log.debug("{}",result.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

测试

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Chat chat = new Chat();
        boolean result = chat.getAccessToken();
        if (result){
            chat.getPrompt(7964,"zmbwcx");
        }
    }
}

19:48:04,906 DEBUG Chat:48 - 获取accessToken成功
19:48:05,144 DEBUG Chat:99 - {"result":{"templateName":"测试接口调用","templateContent":"文章内容:{name}测试接口调用成功","templateId":7964,"content":"文章内容:zmbwcx测试接口调用成功","templateVariables":"name"},"log_id":"0hkyy9izb4azvsgp","success":true,"status":200}
19:48:05,145 DEBUG Chat:101 - {"templateName":"测试接口调用","templateContent":"文章内容:{name}测试接口调用成功","templateId":7964,"content":"文章内容:zmbwcx测试接口调用成功","templateVariables":"name"}

实现对话接口调用

同样是观察文档,不过实现对话接口调用比实现调用Prompt接口稍微复杂一些。需要创建一些类来设置我们的参数。

创建请求参数类

@Data
public class RequestMessage {
    /**
     * 聊天上下文
     */
    List<Message> messages = new ArrayList<>();
 
    /**
     * 范围(0~1.0]
     * 较高的数值会使输出更加随机
     */
    float temperature = Float.parseFloat("0.95");
 
    /**
     * 影响文本的多样性,取值越大生成的文本多样性越强
     * 建议该参数与temperature只设置一个。建议top_p和temperature不要同时更改
     */
    float top_p = Float.parseFloat("0.8");
 
    /**
     * 通过对已生成的token增加惩罚,减少重复生成的现象
     * 值越大,惩罚越大
     * 取值范围[1,2]
     */
    float penalty_score = Float.parseFloat("1.0");
 
    /**
     * 是否以流式接口形式返回数据
     */
    boolean stream = false;
 
    /**
     * 模型人设
     */
    String system = null;
 
    /**
     * 表示用户唯一标识符,用于监测和检测滥用行为。防止接口恶意调用。
     */
    String user_id = "";
 
    public void addMessage(Message message){
        this.messages.add(message);
    }
}

创建Message类 

@Data
public class Message {
    /**
     * 用户角色
     * 目前支持:
     * user 用户
     * assistant 对话助手
     */
    String role;
 
    /**
     * 对话内容。
     */
    String content;
 
    public Message(String role, String content) {
        this.role = role;
        this.content = content;
    }
}

设置接收响应信息类

@Data
public class ResponseMessage {
    //本轮对话id
    String id;
 
    //回包类型。 chat.completion:多轮对话返回
    String object;
 
    //时间戳
    int created;
 
    //表示当前子句的序号。只有在流式接口模式下才会返回该字段
    int sentence_id;
 
    //表示当前子句是否是最后一句。只有在流式接口模式下会返回该字段。
    boolean is_end;
 
    //对话返回结果。
    String result;
 
    /**
     * 表示用户输入是否存在安全,是否关闭当前会话,清理历史回话信息。
     * true:是,表示用户输入存在安全风险,建议关闭当前会话,清理历史会话信息。
     * false:否,表示用户输入无安全风险。
     */
    boolean need_clear_history;
 
    //token统计信息,token数 = 汉字数+单词数*1.3 (仅为估算逻辑)。
    Usage usage;
}

 设置Usage类

public class Usage {
    //问题token数
    int prompt_tokens;
    //回答token数
    int completion_tokens;
    //token总数
    int total_tokens;
}

 如果看文档不太清楚的话,我们可以通过在线调试平台观察一下请求所需要的必须参数与响应过来的参数结构。

接下来我们编写Chat类 

@Slf4j
public class Chat {
    private final String ACCESS_TOKEN_URI = "https://aip.baidubce.com/oauth/2.0/token";
    private final String CHAT_URI = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/eb-instant";
 
    private String apiKey = "yourApikey";
    private String secretKey = "yourSecretkey";
    private String accessToken = "";
 
    private OkHttpClient client ;
 
    //请求参数
    private RequestMessage requestBody = new RequestMessage();
    //响应超时时间
    private int responseTimeOut = 5000;
 
    public Chat(){
        this.client = new OkHttpClient.Builder().readTimeout(responseTimeOut,TimeUnit.SECONDS).build();
    }
 
    public Chat(int responseTimeOut){
        this.client = new OkHttpClient.Builder().readTimeout(responseTimeOut,TimeUnit.SECONDS).build();
    }
 
     public boolean getAccessToken(){
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, "");
        //创建一个请求
        Request request = new Request.Builder()
                .url(ACCESS_TOKEN_URI+"?client_id=" + apiKey + "&client_secret=" + secretKey + "&grant_type=client_credentials")
                .method("POST",body)
                .addHeader("Content-Type", "application/json")
                .build();
        try {
            //使用浏览器对象发起请求
            Response response = client.newCall(request).execute();
            //只能执行一次response.body().string()。下次再执行会抛出流关闭异常,因此需要一个对象存储返回结果
            String responseMessage = response.body().string();
            log.debug("获取accessToken成功");
            JSONObject jsonObject = JSON.parseObject(responseMessage);
            accessToken = (String) jsonObject.get("access_token");
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
 
    /**
     *
     * 获取问题参数,返回答案
     * @param question
     */
    public void getAnswer(String question){
        //通过参数获取一个Message
        Message message = new Message("user",question);
        //将新的问题添加到消息上下文
        requestBody.addMessage(message);
        String jsonStr = JSON.toJSONString(requestBody);
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, jsonStr);
        Request request = new Request.Builder()
                .url(CHAT_URI + "?access_token="+accessToken)
                .addHeader("Content-Type", "application/json")
                .method("POST",body)
                .build();
        try {
            Response response = client.newCall(request).execute();
            log.debug("发送一次请求,询问问题:{}",question);
            String responseJsonStr = response.body().string();
            ResponseMessage responseMessage = JSON.parseObject(responseJsonStr, ResponseMessage.class);
            System.out.println("返回的响应结果为:"+responseJsonStr);
            String result = responseMessage.getResult();
            String answer = result.replaceAll("\n+", "\n");
            log.debug("{}",answer);
            Message assistant = new Message("assistant", answer);
            requestBody.addMessage(assistant);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    public void getRequestBody(){
        System.out.println(JSON.toJSONString(requestBody));
    }    
}

测试

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Chat chat = new Chat();
        boolean result = chat.getAccessToken();
        if (result){
            Scanner scanner = new Scanner(System.in);
            String question = scanner.nextLine();
            while(!"q".equals(question)){
                chat.getAnswer(question);
                chat.getRequestBody();
                question = scanner.nextLine();
            }
        }
    }
}

注意!!

以上信息均为使用Java调用千帆大模型接口-CSDN博客大佬教程(此处抄袭仅为整合自用)

但是我需要的是可以提供阅读背景式的调用,接下来以我的web作业为例:

我需要gpt扮演我的网站客服为用户回答问题:实现场景如下

ok,进入正题:

根据要求配置插件后在插件详情页面有

我们来看一下开发文档域内知识搜索增强插件API调用说明 - 千帆大模型平台 | 百度智能云文档 (baidu.com)

注意请求体发生了改变!!!

我一直以为一样结果在这里被坑惨了

java代码简单修改一下

 /**
     *
     * 获取问题参数,返回答案
     * @param question
     */
    public String getAnswer(String question) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();

        Map<String, Object> payload = new HashMap<>();
        payload.put("query", question);
        payload.put("verbose", true);
        String jsonString = mapper.writeValueAsString(payload);
        
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, jsonString);
        Request request = new Request.Builder()
                .url(CHAT_URI + "?access_token="+accessToken)
                .addHeader("Content-Type", "application/json")
                .method("POST",body)
                .build();
        try {
            Response response = client.newCall(request).execute();
            log.debug("发送一次请求,询问问题:{}",question);
            String responseJsonStr = response.body().string();
            ResponseMessage responseMessage = JSON.parseObject(responseJsonStr, ResponseMessage.class);
            System.out.println("返回的响应结果为:"+responseJsonStr);
            String result = responseMessage.getResult();

            return result;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

Controller层代码:

 @PostMapping
    public String ai(@RequestBody String text) throws JsonProcessingException {
        log.info("沟通文本为:{}",text);

        //ai接口
        Chat chat = new Chat();
        boolean result = chat.getAccessToken();
        if(result) {
            String ai = chat.getAnswer(text);
            return  "美女客服:"+ai;
        }
        return  "客服忙去了~";
    }

ok,完美解决

最后总结!

遇到一个新东西,不要想当然的操作,还是要去看一下开发者文档!!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/234477.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

c++-定长内存池

文章目录 前言一、定长内存池 前言 一、定长内存池 我们知道申请内存使用的是malloc&#xff0c;malloc其实就是一个通用的申请函数&#xff0c;什么场景下都可以用&#xff0c;但是什么场景下都可以用就意味着什么场景下都不会有很高的性能&#xff0c;下面我们来设计一个定…

Diffusion Models: A Comprehensive Survey of Methods and Applications

摘要 扩散模型作为一个强大的新的深度生成模型系列出现&#xff0c;在许多应用中具有破纪录的性能&#xff0c;包括图像合成、视频生成和分子设计。在这项调查中&#xff0c;我们对迅速扩大的扩散模型的工作进行了概述&#xff0c;将研究分为三个关键领域&#xff1a;有效采样…

HCIP —— BGP 基础 (下)

BGP 的状态机 --- 建立对等体之间的TCP会话&#xff1a;指定建立对等体的对象 六种状态机 Idle状态 Idle 等待状态&#xff08;相当于OSPF的down状态&#xff09;--- 采用TCP单播建邻 Idle 状态下&#xff0c;启动BGP协议后必须指定建立对等体的目标之后&#xff0c;才能进入…

python中getattr

一、getattr的基本概念 getattr是python的一个内置函数&#xff0c;说白了也很简单&#xff0c;就是判断一个方法或者属性是否存在于一个对象中若是存在则运行这个属性或者方法。 getattr(object, name[, default])object&#xff1a;对象名称 name&#xff1a;属性或者方法名…

uniappp框架——初始化vue3项目(搭建ai项目第一步)

文章目录 ⭐前言&#x1f496; 小程序系列文章 ⭐uniapp创建项目&#x1f496; 初始化项目&#x1f496; uni实例生命周期&#x1f496; 组件生命周期&#x1f496; 页面调用&#x1f496; 页面通讯&#x1f496; 路由 ⭐搭建首页⭐form表单校验页面⭐总结⭐结束 ⭐前言 大家好…

6.题目:编号2490 小蓝的括号串1

题目: ### 这道题主要考察stack #include<bits/stdc.h> using namespace std; const int N105; stack<char> stk; char s[N]; int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int n;cin>>n;cin>>s1;bool anstrue;for(int i1;i<n;i){…

Verilog基础:$random系统函数的使用

相关阅读 Verilog基础​编辑https://blog.csdn.net/weixin_45791458/category_12263729.html $random系统函数语法的BNF范式如下所示&#xff0c;有关BNF范式相关内容&#xff0c;可以浏览以往文章Verilog基础&#xff1a;巴科斯范式(BNF)。 $random系统函数在每次调用时返回一…

第四节JavaScript 条件语句、循环语句、break与continue语句

一、JavaScript条件语句 在通常的代码中&#xff0c;我们有一些需要决定执行不同动作&#xff0c;这就可以在代码中使用条件语句来完成。 下面是我们常使用的条件语句&#xff1a; if语句&#xff1a;只有当指定条件是true时&#xff0c;执行条件内代码。if…else语句&#…

【Unity动画】什么是任意状态(Any state)

&#xff08;Any state&#xff09;可以从某个状态A直接切换到另一个状态 B\C\D\E\F 比如A到C的过渡&#xff0c;直接设置从Any state 到C的过渡线触发参数即可。而不需要让A到C直接在连接&#xff0c;同样&#xff0c;B到C之间也无需直接链接。 这样设计是在每一个动画之间都…

Redis 持久化 —— 超详细操作演示!

四、Redis 持久化 四、Redis 持久化4.1 持久化基本原理4.2 RDB持久化4.3 AOF持久化4.4 RDB与AOF对比4.5 持久化技术转型 五、Redis 主从集群六、Redis 分布式系统七、Redis 缓存八、Lua脚本详解九、分布式锁 数据库系列文章&#xff1a; 关系型数据库: MySQL —— 基础语法大全…

kotlin - ViewBinding

前言 为什么用ViewBinding&#xff0c;而不用findViewById()&#xff0c;这个有很多优秀的博主都做了讲解&#xff0c;就不再列出了。 可参考下列博主的文章&#xff1a; kotlin ViewBinding的使用 文章里也给出了如何在gradle中做出相应的配置。 &#xff08;我建议先看这位博…

windows 10多用户同时远程登陆配置【笔记】

系统环境&多用户访问情况&#xff1a; 1、【win】【R】键入【gpedit.msc】 2、依次选择【计算机配置】→ 【管理模板】 → 【Windows组件】 → 【远程桌面服务】 → 【远程桌面会话主机】 →【连接】 2.1、右键 【允许用户通过使用远程桌面服务进行远程连接】 编辑 …

Python字典去重竟然比集合去重快速40多倍

这里写目录标题 对比代码结果图代码解析 对比代码 from glob import glob from tqdm import tqdm import time path_listglob("E:/sky_150b/任务组_20231207_2023/*.jsonl") # for two in tqdm(path_list): onepath_list[0]with open(one,"r",encoding&q…

基于SpringBoot 2+Layui实现的管理后台系统源码+数据库+安装使用说明

springboot-plus 一个基于SpringBoot 2 的管理后台系统,包含了用户管理&#xff0c;组织机构管理&#xff0c;角色管理&#xff0c;功能点管理&#xff0c;菜单管理&#xff0c;权限分配&#xff0c;数据权限分配&#xff0c;代码生成等功能 相比其他开源的后台系统&#xff0…

MATLAB | 官方举办的动图绘制大赛 | 第四周(收官周)赛情回顾

MATHWORKS官方举办的迷你黑客大赛第三期(MATLAB Flipbook Mini Hack)圆满结束&#xff0c;虽然我的水平和很多大佬还有比较大的差距&#xff0c;但所有奖也算是拿满了&#xff1a; 专家评选前三名&#xff0c;以及投票榜前十&#xff1a;~ 每周的阶段性获奖者&#xff1a; 下面…

c++实现ros通信

这里用的到是自定义的msgcpp发布消息 主要包括两个msg&#xff0c;一个订阅者和一个发布者&#xff0c;以及cmakelists的相应修改。 首先是自定义的msg&#xff0c;功能包里面来自定义msg也是可以的&#xff1a; 新建功能包 catkin_create_pkg pkg roscpp std_msgs message_g…

模块一——双指针:611.有效三角形的个数

文章目录 题目描述算法原理解法一&#xff1a;暴力求解(超时&#xff09;解法二&#xff1a;排序&#xff0b;双指针 代码实现 题目描述 题目链接&#xff1a;611.有效三角形的个数 算法原理 解法一&#xff1a;暴力求解(超时&#xff09; 三层for循环枚举出所有的三元组&…

一款基于ESP32的迷你四足机器人

一、软件介绍 增加自定义动作模式&#xff0c;可以在小程序中自定义一个最多10个步骤的动作。 附件中&#xff1a;带自定模式固件bin.zip esp32c3固件文件 烧录下图设置 无串口版本esp32c3开发板烧录前先按住BOOT键再插线进入烧录模式&#xff0c;LoadMode选择USB。 二、AP…

5_CSS三大特性盒子模型

第5章-盒子模型【比屋教育】 本课目标&#xff08;Objective&#xff09; 掌握CSS三大特性理解什么是盒子模型掌握内边距padding的用法掌握外边距margin的用法 1. CSS的层叠&#xff0c;继承&#xff0c;优先级 1.1 CSS层叠 层叠&#xff1a;是指多个CSS样式叠加到同一个元…

详解ZNS SSD基本原理

ZNS SSD的原理是把namespace空间划分多个zone空间&#xff0c;zone空间内部执行顺序写。这样做的优势&#xff1a; 降低SSD内部的写放大&#xff0c;提升SSD的寿命 降低OP空间&#xff0c;host可以获得更大的使用空间 降低SSD内部DRAM的容量&#xff0c;降低整体的SSD成本 降…