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

news2024/12/22 18:05:27

前言

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图神经网络:在KarateClub上动手实现图神经网络

文章说明&#xff1a; 1)参考资料&#xff1a;PYG官方文档。超链。 2)博主水平不高&#xff0c;如有错误还望批评指正。 3)我在百度网盘上传了这篇文章的jupyter notebook。超链。提取码8888。 文章目录 文献阅读&#xff1a;代码实操&#xff1a; 文献阅读&#xff1a; 参考文…

JavaWeb05(删除增加修改功能实现连接数据库)

目录 一.实现删除功能 1.1 url如何传参&#xff1f; xx.do?参数参数值&参数名参数值 1.2 servlet如何拿对应值&#xff1f; //根据参数名拿到对应的参数值 String str req.getParameter("参数名") 1.3 如何询问&#xff1f; οnclick"return con…

区位码-GB2312

01-09区为特殊符号 10-15区为用户自定义符号区&#xff08;未编码&#xff09; 16-55区为一级汉字&#xff0c;按拼音排序 56-87区为二级汉字&#xff0c;按部首/笔画排序 88-94区为用户自定义汉字区&#xff08;未编码&#xff09; 特殊符号 区号:01 各类符号 0 1 2 3 4 …

I/O多路转接——epoll服务器代码编写

目录 一、poll​ 二、epoll 1.epoll 2.epoll的函数接口 ①epoll_create ②epoll_ctl ③epoll_wait 3.操作原理 三、epoll服务器编写 1.日志打印 2.TCP服务器 3.Epoll ①雏形 ②InitEpollServer 与 RunServer ③HandlerEvent 四、Epoll的工作模式 1.LT模式与ET…

第二十一章 光源

光源是每个场景必不可少的部分&#xff0c;光源除了能够照亮场景之外&#xff0c;还可以产生阴影效果。 Unity中分为四种光源类型&#xff1a; 1. 方向光&#xff1a;Directional Light 用于模拟太阳光&#xff0c;方向光任何地方都能照射到。 2. 点光源&#xff1a;Point L…

JavaWeb-Servlet【内含思维导图】

目录 Servlet思维导图​编辑 1.什么是Servlet 2.Servelt概述 3.Servlet-Quickstart Your Project 3.1创建一个Web项目&#xff0c;导入Servlet依赖 3.1.1 选择Servlet导入依赖 3.1.2 导入Servlet依赖 3.2 在Web项目&#xff0c;定义类&#xff0c;实现Servlet接口…

Java8新特性-流式操作

在Java8中提供了新特性—流式操作&#xff0c;通过流式操作可以帮助我们对数据更快速的进行一些过滤、排序、去重、最大、最小等等操作并且内置了并行流将流划分成多个线程进行并行执行&#xff0c;提供更高效、快速的执行能力。接下来我们一起看看Java8为我们新增了哪些便捷呢…

Python基础合集 练习19(类与对象3(多态))

多态 class Horse: def init(self, name) -> None: self.name name def fature(self):return 父亲-----马的名字: {0}.format(self.name)def mover(self):print(马儿跑起来很潇洒)class Monkey: def init(self, name) -> None: self.name name def fature(self):ret…

《用于准确连续非侵入性血压监测的心跳内生物标志物》阅读笔记

目录 0 基础知识 1 论文摘要 2 论文十问 3 实验结果 4 论文亮点与不足之处 5 与其他研究的比较 6 实际应用与影响 7 个人思考与启示 参考文献 0 基础知识 非侵入性是指在进行医学检查或治疗时&#xff0c;不需要切开皮肤或穿刺体内组织&#xff0c;而是通过外部手段进…

【VQGAN论文精读】Taming Transformers for High-Resolution Image Synthesis

【VQGAN论文精读】Taming Transformers for High-Resolution Image Synthesis 0、前言Abstract1. Introduction2. Related Work3. Approach3.1. Learning an Effective Codebook of Image Constituents for Use in Transformers学习一个有效的图像成分的Codebook为了在Transfor…

高性能:负载均衡

目录 什么是负载均衡 负载均衡分类 服务端负载均衡 服务端负载均衡——软硬件分类 服务端负载均衡——OSI模型分类 客户端负载均衡 负载均衡常见算法 七层负载均衡做法 DNS解析 反向代理 什么是负载均衡 将用户请求分摊&#xff08;分流&#xff09; 到不同的服务器上…

小记Java调用C++开发的动态链接库(DLL)

一、背景 五一快乐吖&#xff01;死肥宅正趁着五一这段时间&#xff0c;努力提升自己&#xff01; 最近使用Java拦截Windows系统中一些默认事件时&#xff0c;发现了一些瓶颈。 我用Java操作浏览器、用Java最小化其他应用窗口&#xff0c;但是我发现这个操作&#xff0c;他都…

【Unity-UGUI控件全面解析】| InputField 输入框组件详解

🎬【Unity-UGUI控件全面解析】| InputField 输入框组件详解一、组件介绍二、组件属性面板2.1 Content Type(内容类型)三、代码操作组件四、组件常用方法示例4.1 代码限制输入字符4.2 校验文本输入格式4.3 校验输入文本长度💯总结🎬 博客主页:https://xiaoy.blog.csdn.…

话说【永恒之塔sf】里面最有前途的职业:商人

如果有人问我永恒之塔里面什么职业最有前途&#xff01;那我告诉你就是商人&#xff01; 做一个NB商人比拥有一身牛b装备要更有成就感。 在老区由于进入的比较晚&#xff0c;所以最后随了大流被淹死在千万基纳中。为了证明商人在永恒之塔是钱途无量的&#xff0c;我转到了新区—…

快解析动态域名解析,实现外网访问内网数据库

今天跟大家分享一下如何借助快解析动态域名解析&#xff0c;在两种特定网络环境下&#xff0c;实现外网访问内网mysql数据库。 第1种网络环境&#xff1a;路由器分配的是动态公网IP&#xff0c;且有路由器登录管理权限。如何实现外网访问内网mysql数据库&#xff1f; 针对这种…

IDEA2022版教程上()

0、前景摘要 0.1 概览 0.2 套课程适用人群 初学Java语言&#xff0c;熟悉了记事本、EditPlus、NotePad或Sublime Text3等简易开发工具的Java初学者熟练使用其他Java集成开发环境&#xff08;IDE&#xff09;&#xff0c;需要转向IDEA工具的Java工程师们关注IDEA各方面特性的J…

Hadoop大数据分析技术(伪分布式搭建)

一.安装JDK和配置SSH免密登录 &#xff08;1&#xff09;准备软件 &#xff08;2&#xff09;解压压缩包 tar -zxvf jdk-8u221-linux-x64.tar.gz &#xff08;3&#xff09;在此处我们配置系统环境变量&#xff0c;使用命令&#xff1a; vim /etc/profile &#xff08;4&#x…

Python入门教程(高级版)

Python用了好几年了&#xff0c;但似乎一直没 “系统入门” 过&#xff08;o(╯□╰)o&#xff09;。今年&#xff08;2023年&#xff09;趁着五一假期&#xff0c;我做了一次相对完整的 “入门” ——本文是这次学习历程的详细记录。 目录 1 Python基础1.1 Python1.1.1 认识Py…

Oracle VM VirtualBox安装centos7步骤 for win10

目录 1.安装VirtualBox 2.安装vagrant 3.安装centos7 4.查看网络与百度和物理机连通情况 5.设置IP 1.安装VirtualBox 下载的链接:Downloads – Oracle VM VirtualBox 2.安装vagrant 根据自己的操作系统选择对应的版本。 Install | Vagrant | HashiCorp Developer 我的P…

asp.net+sqlserver旅游网站zjy99A2

1&#xff0e;系统登录&#xff1a;系统登录是用户访问系统的路口&#xff0c;设计了系统登录界面&#xff0c;包括用户名、密码和验证码&#xff0c;然后对登录进来的用户判断身份信息&#xff0c;判断是管理员用户还是普通用户。 2&#xff0e;系统用户管理&#xff1a;不管是…