对接ChatGPT开发对话机器人小程序

前言

ChatGPT已经非常火爆了,企业开始招聘ChatGPT工程师,可能对接ChatGPT接口进行企业级开发是程序员必备的技能了。本篇文章主要是基于ChatGPT开发接口进行对接,使用微信小程序制作一款自己的聊天机器人,通过这一案例你可以展开无限的扩展

整体设计

整体设计比较简单,我们使用微信小程序作为客户端界面提供用户使用,小程序和后台使用WebSocket进行通信。
在这里插入图片描述
最终效果如下
在这里插入图片描述

ChatGPT接口对接

注意要有梯子才可以访问,接口参考文档:https://platform.openai.com/docs/api-reference/chat ,在Api Reference 接口文档中找到Chat ,里面有Chat对话接口的请求说明

在这里插入图片描述
根据文档说明,我们需要构建一个请求地址为:https://api.openai.com:443/v1/chat/completions ,post请求提交,参数为:

{
    "model":"gpt-3.5-turbo",
    "messages":[
        {
            "role":"user",
            "content":"SpringBoot是什么"
        }
    ]
}

这样还不够,如果直接访问会报错:apikey不存在,我们还需要创建一个APIKEY,地址:https://platform.openai.com/account/api-keys

在这里插入图片描述

然后我这里使用Postmain做一个简单测试,请求头加上APIKEY
在这里插入图片描述
在Body中构建请求参数效果如下
在这里插入图片描述
根据结果可以看到返回的格式为

{
    "id": "chatcmpl-7A6KvI2ybOjR2xHvejz3ysoDFmA54",
    "object": "chat.completion",
    "created": 1682641993,
    "model": "gpt-3.5-turbo-0301",
    "usage": {
        "prompt_tokens": 14,
        "completion_tokens": 147,
        "total_tokens": 161
    },
    "choices": [
        {
            "message": {
                "role": "assistant",
                "content": "Spring Boot 是 Spring 框架的一部分,是一个快速开发框架,可以从头开始构建独立的 Spring 应用程序。它通过自动配置功能和嵌入式 Web 服务器可以快速地开发出一个基于 Spring 框架的 Web 应用程序。Spring Boot 构建于 Spring 框架之上,使得开发者可以更方便地集成 Spring 框架的各种组件和其他第三方库,同时避免了繁琐的 XML 配置。"
            },
            "finish_reason": "stop",
            "index": 0
        }
    ]
}

编写后台

后台我们使用SpringBoot快速开发,主要是整合websocket收发消息,需要导入的pom如下

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>



        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>


        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.78</version>
        </dependency>
        
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

第二步,启动类中定义RestTemplate,方便后续向ChatGPT发请求

@SpringBootApplication
public class ChatGptApp {
    public static void main(String[] args) {
        SpringApplication.run(ChatGptApp.class);
    }


    @Bean
    public RestTemplate restTemplate(){
        
        return new RestTemplate();
    }

}

第三步,配置websocket,如下

@Configuration
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

第四步:编写请求实体类,根据ChatGPT要求的请求参数来封装

@Data
public class ChatMessageParam {
    //model 代表了使用chatgpt的哪个模型
    private String model = "gpt-3.5-turbo";
    //请求消息,要去以数组格式
    private List<ChatMessage> messages = new ArrayList<>();
    //往message中添加message
    public void addMessages(ChatMessage message) {
        this.messages.add(message);
    }

    public ChatMessageParam(){}

    public ChatMessageParam(ChatMessage message){
        this.messages.add(message);
    }
}

@Data
@NoArgsConstructor
@AllArgsConstructor
public class ChatMessage {
    private String role;
    private String content;
}

下面是参数配置application.yaml中的配置和属性对象

server:
  port: 80
chatgpt:
  apikey: 你的apikey
  apiurl: "https://api.openai.com:443/v1/chat/completions"


//参数对象
@Component
@ConfigurationProperties(prefix = "chatgpt")
@Data
public class ChatGptProperties {
    private String apikey;
    private String apiurl;
}


第五步:编写请求发送逻辑,底层使用的是RestTmpalte来发送.这里需要两个参数 APIKEY和URL地址,我在yaml中进行了配置,并使用对象进行绑定


@Component
@Slf4j
public class ChatHttpSender {
	//HTTP客户端
    @Autowired
    private RestTemplate restTemplate;

    //ChtGPT配置
    @Autowired
    private ChatGptProperties chatProperties;

    public String post(String message){
        //封装参数对象
        ChatMessageParam param = new ChatMessageParam(new ChatMessage(ChatGptConstants.ROLE,message));
        //添加请求头
        HttpHeaders httpHeaders = new HttpHeaders();
        //设置apikey
        httpHeaders.add(AUTHORIZATION,String.format(PRE_BEARER,chatProperties.getApikey()));
        httpHeaders.add("text/plain", StandardCharsets.UTF_8.toString());
        httpHeaders.add("Content-Type", "application/json");
        //构建Post请求
        HttpEntity entity = new HttpEntity(param,httpHeaders);
        log.info("发送请求 {}",entity);
        //向ChatGPT发送请求
        String json = restTemplate.postForObject(chatProperties.getApiurl(), entity, String.class);
        //解析结果,拿到message
        JSONArray choices = JSON.parseObject(json).getJSONArray("choices");
        JSONObject jsonObject = choices.getJSONObject(0);
        String content = jsonObject.getJSONObject("message").getString("content");
        log.info("拿到结果 {}",content);
        return content;
    }
}

//常量类
public class ChatGptConstants {

    public static final String MODEL = "gpt-3.5-turbo";
    public static final String ROLE = "user";

    public static final String AUTHORIZATION = "Authorization";
    public static final String PRE_BEARER  = "Bearer %s";
}

第六步,编写websocket服务端,主需要是收到消息后调用ChatHttpSender发送请求,然后把结果写回给客户端。这里我使用的是RedsTemplate调用ChatGpt接口,因为是同步,会出现等待的情况

package org.example.socket;

import lombok.extern.slf4j.Slf4j;
import org.example.http.ChatHttpSender;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;


@Component
//服务器端点
@ServerEndpoint("/chatWebSocket/{uid}")
@Slf4j
public class ChatSocketServer {
    //定义了一个请求发送器
    private static ChatHttpSender httpSender;

    //用map把websocket客户端存储七年,客户端集合,key是uid
    private static ConcurrentHashMap<String, ChatSocketServer> socketClients = new ConcurrentHashMap<>();

    //会话对象,通过他来向客户端发请求
    private Session session;

    //接收uid,代表客户端用户
    private String uid = "";

    //注入sender
    @Resource
    public void setHttpSender(ChatHttpSender httpSender){
        this.httpSender = httpSender;
    }

    /**
     * 建立连接
     * @param session 会话
     * @param uid 连接用户名称
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("uid") String uid) {
        this.session = session;
        this.uid = uid;
        socketClients.put(uid, this);
        log.info("客户端{} , 建立连接",uid);
    }

    @OnClose
    public void onClose() {
        socketClients.remove(uid);
        log.info("客户端{} , 关闭连接",uid);
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("收到消息,UID:{} 内容: {} ",uid,message);
        try {
            //httpSender向chatGPT发起请求,拿到结果
            String result = httpSender.post(message);
            //给客户端返回结果
            sendMessage(result);
        }catch (Exception e){
            e.printStackTrace();
            sendMessage("服务器故障");
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
        log.error("发生错误,{} ",uid,error.getMessage());
    }

    public void sendMessage(String message)  {
        log.error("发送消息,UID:{} ,内容:{} ",uid,message);
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}

服务端上云

ChatGPT需要梯子才能访问,所以在本地是测不通的,建议直接买一台国外的服务器进行部署。购买云服务器可以看这篇文章《购买一台云服务器》,记得买国外的服务器。然后把项目打成jar包,进入项目根目录执行:mvn install ,在target目录找到项目比如:springboot-chatgpt-1.0-SNAPSHOT.jar 。然后上传到云服务器上,执行Java -jar 即可

在这里插入图片描述
到此服务器端搞定。

小程序端

微信小程序大家可以根据微信小程序官网教程去下载客户端工具,然后导入已有前端代码来测试。前端主要是布局和写websocket客户端,这里截一下核心代码

onShow: function () {
    //链接服务器端
    wx.connectSocket({
      url: 'ws://170.106.152.44/chatWebSocket/uid' + Math.round(Math.random()*10)
    })

    wx.onSocketOpen((res) => {
      socketOpen = true
      
      wx.showToast({
        icon: 'none',
        title: '会话建立成功',
        duration: 500
      })
      socketMsgQueue = []
      //处理返回的消息
      wx.onSocketMessage((result) => {
        result.data = result.data.replace(" ", "&nbsp;");
        curAnsCount++;
        if (curAnsCount % lineCount == 0) {
          wx.createSelectorQuery().select('#chatPage').boundingClientRect(function (rect) {
            // 使页面滚动到底部
            wx.pageScrollTo({
              scrollTop: rect.bottom
            })
          }).exec()
        }
        msgList[msgList.length - 1].content = result.data
        this.setData({
          msgList
        })
      })
    })
  },

所有代码我已经上传的Gitee,有兴趣可以去参考一下。地址:https://gitee.com/baidu11.com/chatgpt

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

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

相关文章

对称加密/非对称加密

古典密码学 起源于古代战争:在战争中&#xff0c;为了防止书信被截获后重要信息泄露&#xff0c;人们开始对书信进行加密。 移位式加密 如密码棒&#xff0c;使用布条缠绕在木棒上的方式来对书信进行加密。 加密算法&#xff1a;缠绕后书写 密钥&#xff1a; 木棒的尺寸 替…

chatgpt如何引入领域知识?mit团队利用gpt4做数据增强来提升小模型在特定领域的效果

一、概述 title&#xff1a;Dr. LLaMA: Improving Small Language Models in Domain-Specific QA via Generative Data Augmentation 论文地址&#xff1a;Paper page - Dr. LLaMA: Improving Small Language Models in Domain-Specific QA via Generative Data Augmentation…

[网络安全]DVWA之XSS(Reflected)攻击姿势及解题详析合集

[网络安全]DVWA之XSS&#xff08;Reflected&#xff09;攻击姿势及解题详析合集 XSS(Reflected)-low level源代码姿势 XSS(Reflected)-medium level源代码姿势1.双写绕过2.大小写绕过 XSS(Reflected)-high level源代码str_replace函数 姿势 XSS(Reflected)-Impossible level源代…

Linux---相关介绍、相关下载、连接Linux系统、虚拟机快照

1. Linux系统相关 内核提供了Linux系统的主要功能&#xff0c;如硬件调度管理的能力。 Linux内核是免费开源的&#xff0c;是由林纳斯托瓦兹在1991年创立并发展至今成为服务器操作系统领域的 核心系统。 内核无法被用户直接使用&#xff0c;需要配合应用程序才能被用户使用…

简单网络管理协议 SNMP

文章目录 1 概述1.1 结构1.2 操作 2 SNMP2.1 报文格式2.2 五大报文类型 3 扩展3.1 网工软考真题 1 概述 #mermaid-svg-95KMV1m3prKJgwv1 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-95KMV1m3prKJgwv1 .error-ico…

spring 容器结构/机制debug分析--Spring 学习的核心内容和几个重要概念--IOC 的开发模式--综合解图

目录 Spring Spring 学习的核心内容 解读上图: Spring 几个重要概念 ● 传统的开发模式 解读上图 ● IOC 的开发模式 解读上图 代码示例—入门 xml代码 注意事项和细节 1、说明 2、解释一下类加载路径 3、debug 看看 spring 容器结构/机制 综合解图 Spring Spr…

ChatGpt使用、小白上手指南,整理5个ChatGpt学习文库和平台

ChatGpt目前很火&#xff0c;话题度很高&#xff0c;关于它的账号售卖、视频课程网上遍地都是&#xff0c;尝试没有窍门&#xff0c;学习付费太高&#xff0c;一不小心就会被割韭菜。 闲暇之余也从网上搜集整理了5个平台&#xff0c;里面系统的介绍了有关ChatGpt的应用和相关&…

记一次springboot项目漏洞挖掘

前言 前段时间的比赛将该cms作为了题目考察&#xff0c;这个cms的洞也被大佬们吃的差不多了&#xff0c;自己也就借此机会来浅浅测试下这个cms残余漏洞&#xff0c;并记录下这一整个流程&#xff0c;谨以此记给小白师傅们分享下思路&#xff0c;有错误的地方还望大佬们请以指正…

OpenGL高级-立方体贴图

运行效果 源代码 着色器 渲染物体的顶点着色器&#xff1a; #version 330 core // 传入局部坐标下的顶点坐标 layout( location 0 ) in vec3 position; layout (location 1) in vec2 texCoords;// 传入变换矩阵 uniform mat4 model; uniform mat4 view; uniform mat4 proje…

二十七、搜索与图论——Floyd 算法(多元路最短路径问题)

Floyd算法主要内容 一、基本思路1、算法原理2、基本思路3、注意 二、Java、C语言模板实现三、例题题解 一、基本思路 1、算法原理 遍历每条边&#xff0c;通过比较进行路径更新——暴力 解决多源最短路问题&#xff0c;求解 i 点到 j 点的最短距离 f [ i, j, k] 表示从 i 走…

Linux | 将SpringBoot+Vue项目部署到服务器上

知识目录 一、写在前面二、后端部署2.1 项目打包2.2 项目运行 三、通过Shell脚本自动部署项目3.1 安装Git和Maven3.2 编写Shell脚本3.2 执行脚本 四、前端部署4.1 安装NGINX4.2 node.js安装4.3 npm打包项目4.4 运行项目 四、总结撒花 一、写在前面 大家好&#xff0c;我是初心…

AlmaLinux 9.2 正式版发布 - RHEL 兼容免费发行版

AlmaLinux 9.2 正式版发布 - RHEL 兼容免费发行版 由社区提供的免费 Linux 操作系统&#xff0c;RHEL 兼容发行版。 请访问原文链接&#xff1a;https://sysin.org/blog/almalinux-9/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sys…

K8s(Kubernetes)学习(一):k8s概念及组件

Kubernetes中文文档&#xff1a;https://kubernetes.io/zh-cn/docs/home/ Kubernetes源码地址&#xff1a;https://github.com/kubernetes/kubernetes 一:Kubernetes是什么 首先要了解应用程序部署经历了以下几个时代&#xff1a; 传统部署时代&#xff1a;在物理服务器上运…

ChatGPT学习研究总结

目录 ChatGPT研究总结 一、程序接入用途不大 二、思考&#xff1a;如何构建一个类似ChatGPT的自定义模型 一些ChatGPT研究学习资料&#xff08;来源网络&#xff09; &#xff08;1&#xff09;一文读懂ChatGPT模型原理 &#xff08;2&#xff09;MATLAB科研图像处理——…

DHCP+链路聚合+NAT+ACL小型实验

实验要求: 1.按照拓扑图上标识规划网络。 2.使用0SPF协议进程100实现ISP互通。 3.私网内PC属于VLAN1O, FTP Server属于VLAN2O,网关分 别为所连接的接入交换机&#xff0c;其中PC要求通过DHCP动态获取 4:私网内部所有交换机都为三层交换机&#xff0c;请合理规划VLAN&#…

带你深入学习k8s--(四) 控制器(k8s核心)

目录 一、概念 1、什么是控制器 2、控制器执行流程 3、控制器类型 二、控制器的使用 1、ReplicaSet 2、Deployment 1、版本迭代 2、回滚 3、修改滚动更新策略 4、暂停与恢复 3、daemonset 4、job 5、cronjob 前言&#xff1a; 上一章我们说到&#xff0c;pod有…

VScode添加右键运行、并设置每次运行前都清屏即去除之前的输出

一、添加右键运行 下载安装运行插件即可 二、运行前清屏 在运行插件中设置 找到Code-runner: Clear Previous Output&#xff0c;把√打上即可

【Linux Network】传输层协议——TCP

目录 TCP协议 TCP协议段格式 确认应答(ACK)机制 超时重传机制 连接管理机制 理解TIME_WAIT状态 解决TIME_WAIT状态引起的bind失败的方法 理解 CLOSE_WAIT 状态 滑动窗口 流量控制 拥塞控制 延迟应答 捎带应答 面向字节流 粘包问题 TCP异常情况 TCP小结 基于TCP应用层协议 TCP/U…

Pytroch nn.Unfold() 与 nn.Fold()图码详解

文章目录 Unfold()与Fold()的用途nn.Unfold()Unfold()与Fold() 变化模式图解 nn.Fold()单通道 滑动窗口无重叠模拟图片数据&#xff08;b,3,9,9&#xff09;&#xff0c;通道数 C 为3&#xff0c;滑动窗口无重叠。单通道 滑动窗口有重叠。 卷积等价于&#xff1a;Unfold Matri…

【滤波专题-第7篇】“类EMD”算法分解后要怎样使用(3)——EMD降噪方法及MATLAB代码实现

使用EMD分解&#xff08;以及其他“类EMD”分解方法&#xff0c;以下为了简便统称EMD&#xff09;做信号降噪&#xff0c;是EMD的一个比较重要的应用方向。EMD可以将复杂的信号分解为一系列的固有模态函数&#xff08;IMFs&#xff09;&#xff0c;每一个IMF都包含了信号的一部…