springboot+chatgpt+chatUI Pro開發(fā)智能聊天工具的實(shí)踐
一、技術(shù)介紹
1.chatgpt-java是一個(gè)OpenAI的Java版SDK,支持開箱即用。目前以支持官網(wǎng)全部Api。支持最新版本GPT-3.5-Turbo模型以及whisper-1模型。
2.Spring Boot是由Pivotal團(tuán)隊(duì)提供的全新框架,其設(shè)計(jì)目的是用來簡化新Spring應(yīng)用的初始搭建以及開發(fā)過程。該框架使用了特定的方式來進(jìn)行配置,從而使開發(fā)人員不再需要定義樣板化的配置。通過這種方式,Spring Boot致力于在蓬勃發(fā)展的快速應(yīng)用開發(fā)領(lǐng)域(rapid application development)成為領(lǐng)導(dǎo)者。
3.ChatUI Pro 是在ChatUI 基礎(chǔ)組件的基礎(chǔ)上,結(jié)合阿里小蜜的最佳實(shí)踐,沉淀和總結(jié)出來的一個(gè)開箱即用的,可快速搭建智能對話機(jī)器人的框架。它簡單易上手,通過簡單的配置就能搭建出對話機(jī)器人;同時(shí)它強(qiáng)大易擴(kuò)展,通過豐富的接口和自定義卡片滿足各種定制化需求。
二、項(xiàng)目介紹
本項(xiàng)目采用了GPT-3.5-Turb模型作為基礎(chǔ),通過springboot結(jié)合redis、chat-java以及chatUI Pro實(shí)現(xiàn)簡單的人工智能機(jī)器人。因?yàn)樵L問openAI的API返回結(jié)果比較慢,項(xiàng)目中當(dāng)前端將問題請求發(fā)送到后端后,后端會將生成一個(gè)UUID,返回前端,同時(shí)后端也會重新開啟一個(gè)線程去訪問openAI,當(dāng)openAI返回結(jié)果后,后端將UUID做為key,openAI返回的結(jié)果做為value存儲到redis中。前端會根據(jù)后端第一次請求的結(jié)果中UUID做為參數(shù)每個(gè)5s請求一次后端的answer接口,answer接口會根據(jù)UUID查詢r(jià)edis是否有值,直到后端answer接口返回結(jié)果后前端將結(jié)果輸出給用戶
三、項(xiàng)目搭建
1.創(chuàng)建springboot項(xiàng)目,項(xiàng)目命名mychatgpt。
2.導(dǎo)入項(xiàng)目pom的依賴
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.12</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.xyh</groupId> <artifactId>mychatgpt</artifactId> <version>0.0.1-SNAPSHOT</version> <name>mychatgpt</name> <description>Demo project for Spring Boot</description> <properties> <java.version>8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <exclusions> <exclusion> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> </exclusion> <exclusion> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-to-slf4j</artifactId> </exclusion> </exclusions> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> </dependency> <dependency> <groupId>com.theokanning.openai-gpt3-java</groupId> <artifactId>api</artifactId> <version>0.10.0</version> </dependency> <dependency> <groupId>com.theokanning.openai-gpt3-java</groupId> <artifactId>service</artifactId> <version>0.10.0</version> </dependency> <dependency> <groupId>com.theokanning.openai-gpt3-java</groupId> <artifactId>client</artifactId> <version>0.10.0</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.12</version> </dependency> <dependency> <groupId>com.unfbx</groupId> <artifactId>chatgpt-java</artifactId> <version>1.0.5</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.17</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.8</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.2</version> <exclusions> <exclusion> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.github.yulichang</groupId> <artifactId>mybatis-plus-join</artifactId> <version>1.4.2</version> </dependency> <!--集成隨機(jī)生成數(shù)據(jù)包 --> <dependency> <groupId>com.apifan.common</groupId> <artifactId>common-random</artifactId> <version>1.0.19</version> </dependency> <!--集成隨機(jī)生成數(shù)據(jù)包 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
3.編寫chatGPT實(shí)現(xiàn)工具類
package com.xyh.mychatgpt.utils; import com.unfbx.chatgpt.OpenAiClient; import com.unfbx.chatgpt.entity.chat.ChatChoice; import com.unfbx.chatgpt.entity.chat.ChatCompletion; import com.unfbx.chatgpt.entity.chat.Message; import com.unfbx.chatgpt.entity.common.Choice; import com.unfbx.chatgpt.entity.completions.Completion; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.util.Arrays; import java.util.List; /** * @author xiangyuanhong * @description: TODO * @date 2023/3/21上午9:28 */ @Component public class ChatGPTUtils { @Value("${xyh.openai.key}") private String token; @Autowired private RedisUtils redisUtils; public void ask(String model,String question,String uuid){ StringBuffer result=new StringBuffer(); try { OpenAiClient openAiClient = new OpenAiClient(token, 3000, 300, 300, null); if("GPT-3.5-Turb".equals(model)){ // GPT-3.5-Turb模型 Message message=Message.builder().role(Message.Role.USER).content(question).build(); ChatCompletion chatCompletion = ChatCompletion.builder().messages(Arrays.asList(message)).build(); List<ChatChoice> resultList = openAiClient.chatCompletion(chatCompletion).getChoices(); for (int i = 0; i < resultList.size(); i++) { result.append(resultList.get(i).getMessage().getContent()); } }else{ //text-davinci-003/text-ada-003 Completion completion = Completion.builder() .prompt(question) .model(model) .maxTokens(2000) .temperature(0) .echo(false) .build(); Choice[] resultList = openAiClient.completions(completion).getChoices(); for (Choice choice : resultList) { result.append(choice.getText()); } } }catch (Exception e) { System.out.println(e.getMessage()); result.append("小愛還不太懂,回去一定努力學(xué)習(xí)補(bǔ)充知識"); } redisUtils.set(uuid,result.toString()); } }
4.開發(fā)項(xiàng)目Controller類,用來與前端進(jìn)行交互
package com.xyh.mychatgpt.controller; import cn.hutool.core.thread.ThreadUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import com.xyh.mychatgpt.utils.ChatGPTUtils; import com.xyh.mychatgpt.utils.R; import com.xyh.mychatgpt.utils.RedisUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; /** * @author xiangyuanhong * @description: TODO * @date 2023/2/28下午4:57 */ @RestController public class IndexController { @Autowired private RedisUtils redisUtils; @Autowired private ChatGPTUtils chatGPTUtils; @GetMapping("/ask") public R ask(String question,HttpServletRequest request) { String uuid=IdUtil.simpleUUID(); if (StrUtil.isBlank(question)) { question = "今天天氣怎么樣?"; } String finalQuestion = question; ThreadUtil.execAsync(()->{ chatGPTUtils.ask("GPT-3.5-Turb", finalQuestion,uuid); }); return R.ok().put("data",uuid); } @GetMapping("/answer") public R answer(String uuid){ String result=redisUtils.get(uuid); return R.ok().put("data",result); } }
5.前端頁面開發(fā),在項(xiàng)目templates目錄創(chuàng)建index.html頁面,并引入chatUI pro相關(guān)文件
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta name="renderer" content="webkit" /> <meta name="force-rendering" content="webkit" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0, viewport-fit=cover" /> <title>滴答小愛</title> <link rel="stylesheet" rel="external nofollow" > </head> <body> <div id="root"></div> <script src="http://g.alicdn.com/chatui/sdk-v2/0.2.4/sdk.js"></script> <script src="http://g.alicdn.com/chatui/extensions/0.0.7/isv-parser.js"></script> <script src="js/setup.js"></script> <script src="js/jquery-3.6.3.min.js"></script> <script src="http://g.alicdn.com/chatui/icons/0.3.0/index.js" async></script> </body> </html>
6.創(chuàng)建setup.js實(shí)現(xiàn)chatUI Pro與后端通信交換。
var bot = new ChatSDK({ config: { // navbar: { // title: '滴答小愛' // }, robot: { avatar: 'images/chat.png' }, // 用戶頭像 user: { avatar: 'images/user.png', }, // 首屏消息 messages: [ { type: 'text', content: { text: '您好,小愛為您服務(wù),請問有什么可以幫您的?' } } ], // 快捷短語 // quickReplies: [ // { name: '健康碼顏色',isHighlight:true }, // { name: '入浙通行申報(bào)' }, // { name: '健康碼是否可截圖使用' }, // { name: '健康通行碼適用范圍' }, // ], // 輸入框占位符 placeholder: '輸入任何您想詢問的問題', }, requests: { send: function (msg) { if (msg.type === 'text') { return { url: '/ask', data: { question: msg.content.text } }; } } }, handlers: { /** * * 解析請求返回的數(shù)據(jù) * @param {object} res - 請求返回的數(shù)據(jù) * @param {object} requestType - 請求類型 * @return {array} */ parseResponse: function (res, requestType) { // 根據(jù) requestType 處理數(shù)據(jù) if (requestType === 'send' && res.code==0) { // 用 isv 消息解析器處理數(shù)據(jù) $.ajaxSettings.async=false; var answer=""; var isOK=false; while(!isOK){ $.get("/answer",{uuid:res.data},function(result){ console.log(result.data) if(null != result.data){ isOK=true; answer=result.data; } },"json"); if(!isOK){ sleep(5000); } } $.ajaxSettings.async=true; return [{"_id":res.data,type:"text",content:{text:answer},position:"left"}]; } }, }, }); function sleep(n) { //n表示的毫秒數(shù) var start = new Date().getTime(); while (true) { if (new Date().getTime() - start > n) { break; } } } bot.run();
7.項(xiàng)目搭建完成后啟動(dòng)springboot項(xiàng)目然后訪問http://ip:端口就可以。項(xiàng)目最終效果:http://hyrun.vip/
四、項(xiàng)目展示
到此這篇關(guān)于springboot+chatgpt+chatUI Pro開發(fā)智能聊天工具的實(shí)踐的文章就介紹到這了,更多相關(guān)springboot chatgpt智能聊天內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java內(nèi)部類_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
內(nèi)部類是指在一個(gè)外部類的內(nèi)部再定義一個(gè)類。下面通過本文給大家java內(nèi)部類的使用小結(jié),需要的朋友參考下吧2017-04-04SpringBoot動(dòng)態(tài)定時(shí)任務(wù)、動(dòng)態(tài)Bean、動(dòng)態(tài)路由詳解
這篇文章主要介紹了SpringBoot動(dòng)態(tài)定時(shí)任務(wù)、動(dòng)態(tài)Bean、動(dòng)態(tài)路由詳解,之前用過Spring中的定時(shí)任務(wù),通過@Scheduled注解就能快速的注冊一個(gè)定時(shí)任務(wù),但有的時(shí)候,我們業(yè)務(wù)上需要?jiǎng)討B(tài)創(chuàng)建,或者根據(jù)配置文件、數(shù)據(jù)庫里的配置去創(chuàng)建定時(shí)任務(wù),需要的朋友可以參考下2023-10-10Struts2實(shí)現(xiàn)文件上傳功能實(shí)例解析
這篇文章主要介紹了Struts2實(shí)現(xiàn)文件上傳功能實(shí)例解析,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-01-01