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

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

前言

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

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: ChatGPT