百度智能云+SpringBoot=AI对话【人工智能】
百度智能云+SpringBoot=AI对话【人工智能】
- 前言
- 版权
- 推荐
- 百度智能云+SpringBoot=AI对话【人工智能】
- 效果演示
- 登录
- AI对话
- 项目结构
- 后端开发
- pom和properties
- sql_table和entity
- dao和mapper
- service和impl
- config和util
- LoginController和ChatController
- 前端开发
- css和js
- login.html和chat.html
- 后言
- 最后
前言
2024-3-20 19:41:47
(图片来源网络,侵删)使用百度千帆平台的大模型,完成一个简单的AI对话聊天
以下内容源自《【人工智能】》
仅供学习交流使用
版权
禁止其他平台发布时删除以下此话
本文首次发布于CSDN平台
作者是CSDN@日星月云
(图片来源网络,侵删)博客主页是https://jsss-1.blog.csdn.net
禁止其他平台发布时删除以上此话
推荐
Gitee项目地址: 日星月云 / AI对话
GitHub项目地址:jsss-1/qianfan
百度千帆模型初次体验【人工智能】
百度智能云+SpringBoot=AI对话【人工智能】
通过上篇,我们成功地完成了初次对大模型的使用
(图片来源网络,侵删)本篇,我将带大家开发一个AI对话聊天框
效果演示
登录
输入用户名,点击登录
返回“登录成功”
查询状态
AI对话
页面
输入内容,点击回车即可提问
项目结构
后端开发
pom和properties
pom.xml
SpringBoot2.4.2+JDK8
4.0.0 org.springframework.boot spring-boot-starter-parent 2.4.2 com.example qianfan 0.0.1-SNAPSHOT qianfan qianfan 8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-devtools runtime true org.springframework.boot spring-boot-starter-test test com.baidubce qianfan 0.0.1 org.springframework.boot spring-boot-starter-thymeleaf org.projectlombok lombok true mysql mysql-connector-java runtime org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.4 org.springframework.boot spring-boot-maven-plugin
application.properties
spring.application.name=qianfan # Qianfan QIANFAN_ACCESS_KEY=你的AK QIANFAN_SECRET_KEY=你的SK # ServerProperties server.port=8080 server.servlet.context-path= # ThymeleafProperties spring.thymeleaf.cache=false # mysql spring.datasource.url=jdbc:mysql://localhost:3306/ai?characterEncoding=utf-8&useSSL=false&serverTimezone=Hongkong spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # MyBatis mybatis.mapper-locations=classpath:mapper/*.xml mybatis.type-aliases-package=com.jsss.entity # 生成主键 mybatis.configuration.useGeneratedKeys=true # 驼峰命名 mybatis.configuration.mapUnderscoreToCamelCase=true
sql_table和entity
ai.sql
create table conversation ( id int auto_increment primary key, username varchar(16) null, user_message text null, bot_message text null, create_time varchar(32) null );
**enntity.Conversation **
package com.jsss.qianfan.entity; import lombok.AllArgsConstructor; import lombok.Data; @Data @AllArgsConstructor public class Conversation { private Integer id; private String username; private String userMessage; private String botMessage; private String createTime; }
dao和mapper
**dao.ChatMapper **
package com.jsss.qianfan.dao; import com.jsss.qianfan.entity.Conversation; import org.apache.ibatis.annotations.Mapper; import java.util.List; @Mapper public interface ChatMapper { List getByUsername(String username); void insert(Conversation conversation); }
**mapper/ChatMapper.xml **
SELECT * FROM conversation WHERE username = #{username} INSERT INTO conversation ( username, user_message, bot_message, create_time ) VALUES ( #{username}, #{userMessage}, #{botMessage}, #{createTime} )
service和impl
service.ChatService
package com.jsss.qianfan.service; import com.jsss.qianfan.entity.Conversation; import java.util.List; public interface ChatService { void addChat(Conversation conversation); List searchByUsername(String username); }
impl.ChatServiceImpl
package com.jsss.qianfan.service.impl; import com.jsss.qianfan.dao.ChatMapper; import com.jsss.qianfan.entity.Conversation; import com.jsss.qianfan.service.ChatService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class ChatServiceImpl implements ChatService { @Autowired ChatMapper chatMapper; @Override public void addChat(Conversation conversation) { chatMapper.insert(conversation); } @Override public List searchByUsername(String username) { return chatMapper.getByUsername(username); } }
config和util
configuration.QianfanConfig
package com.jsss.qianfan.configuration; import com.baidubce.qianfan.Qianfan; import com.baidubce.qianfan.core.auth.Auth; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class QianfanConfig { @Value("${QIANFAN_ACCESS_KEY}") String ak; @Value("${QIANFAN_SECRET_KEY}") String sk; @Bean public Qianfan qianFan() { return new Qianfan(Auth.TYPE_OAUTH, ak, sk); } }
util.QianfanUtil
package com.jsss.qianfan.util; import com.baidubce.qianfan.Qianfan; import com.baidubce.qianfan.model.chat.ChatResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class QianfanUtil { @Autowired Qianfan qianfan; public String addMessage(String content) { ChatResponse response = qianfan.chatCompletion() //.model("ERNIE-Bot-4") //使用model指定预置模型 默认模型是ERNIE-Bot-turbo .addMessage("user", content) // 添加用户消息 (此方法可以调用多次,以实现多轮对话的消息传递) .temperature(0.7) // 自定义超参数 .execute(); // 发起请求 return response.getResult(); } public void executeStream(String content) { qianfan.chatCompletion() .addMessage("user", content) .executeStream() // 发起流式请求 .forEachRemaining(chunk -> System.out.print(chunk.getResult())); // 流式迭代,并打印消息 } }
LoginController和ChatController
controller.LoginController
package com.jsss.qianfan.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; @Controller public class LoginController { @GetMapping("/login") public String login(){ return "login"; } @PostMapping("/login") @ResponseBody public String login(HttpServletRequest request,String username){ HttpSession session = request.getSession(); session.setAttribute("username",username); return "登录成功"; } @GetMapping("/logout") @ResponseBody public String logout(HttpServletRequest request,String username){ HttpSession session = request.getSession(); session.removeAttribute("username"); return "登出成功"; } @GetMapping("/status") @ResponseBody public String status(HttpServletRequest request){ HttpSession session = request.getSession(); String username =(String)session.getAttribute("username"); if (username!=null&&!username.isEmpty()){ return username; }else { return "没有登录"; } } }
controller.ChatController
package com.jsss.qianfan.controller; import com.jsss.qianfan.entity.Conversation; import com.jsss.qianfan.service.ChatService; import com.jsss.qianfan.util.QianfanUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Map; @Controller @RequestMapping("chat") public class ChatController { // List conversations=new ArrayList(); // // static int id=1; // // { // conversations.add(new Conversation(id++,"1","你好","抱歉,网络出现异常,请你重试或联系客服!TooManyRequests", format(new Date()))); // conversations.add(new Conversation(id++,"1","你好","抱歉,网络出现异常,请你重试或联系客服!TooManyRequests", format(new Date()))); // } @Autowired QianfanUtil qianfanUtil; @Autowired ChatService chatService; private String format(Date date){ return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date); } @GetMapping("/list") public String getChat(HttpServletRequest request,Model model){ String username= (String) request.getSession().getAttribute("username"); List conversations=chatService.searchByUsername(username); model.addAttribute("conversations",conversations); return "chat"; } @PostMapping("/chat") public String chat(HttpServletRequest httpServletRequest,@RequestBody Map request){ String username= (String) httpServletRequest.getSession().getAttribute("username"); String content = request.get("content"); System.out.println(content); // String res="回复"; // Conversation conversation = new Conversation(id++,username, content, res, format(new Date()); // conversations.add(conversation); String res = qianfanUtil.addMessage(content); Conversation conversation = new Conversation(null, username, content, res, format(new Date())); chatService.addChat(conversation); return "redirect:list"; } }
前端开发
css和js
css/style.css
/* 设置用户发送消息的样式 */ .user-message { background-color: #4CAF50; /* 绿色背景 */ color: white; padding: 10px; margin: 10px; border-radius: 10px; white-space: pre; } /* 设置ChatGPT发送消息的样式 */ .bot-message { background-color: #f2f2f2; /* 灰色背景 */ padding: 10px; margin: 10px; border-radius: 10px; white-space: pre; } .question-container { display: flex; justify-content: flex-end; } .question { display: flex; flex-direction: row; align-items: center; } .question td:first-child { margin-left: auto; } .answer-container { display: flex; justify-content: flex-start; } .answer { display: flex; flex-direction: row; align-items: center; } .answer td:last-child { margin-left: auto; } /* 设置提问和回复消息的表格样式 */ .question, .answer { display: flex; align-items: center; padding: 10px; border-radius: 10px; } /* 设置输入框和发送按钮的样式 */ .form-container { display: flex; justify-content: center; align-items: center; position: fixed; bottom: 0; width: 100%; padding: 10px; background-color: #f9f9f9; border-top: 1px solid #ccc; } .form-row { display: flex; flex: 1; } .form-group { flex: 1; margin-right: 10px; } .form-group input { width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 5px; outline: none; } .message-container { max-height: 700px; /* 设置最大高度,超出部分可滚动 */ overflow-y: auto; /* 竖直方向溢出部分可滚动 */ } .send-message-container { flex: 1; /* 占据剩余空间 */ display: flex; align-items: center; background-color: #f5f5f5; } textarea { width: 1800px; /* 设置输入框的宽度为300像素,您可以根据需要调整这个值 */ height: 100px; /* 设置输入框的高度为200像素,您可以根据需要调整这个值 */ font-size: 16px; /* 设置输入框中文字的字体大小为16像素,您可以根据需要调整这个值 */ resize: none; /* 禁止用户调整输入框的尺寸 */ }
js/onload.js
window.onload = function() { // 找到消息容器 var messageContainer = document.querySelector(".message-container"); // 找到消息容器中最后一个子元素 var lastMessage = messageContainer.lastElementChild; // 将最后一个子元素滚动到可见区域 lastMessage.scrollIntoView(); };
js/textarea.js
var textarea = document.getElementById("messageInput"); textarea.addEventListener("keydown", function(event) { if (event.key === "Enter" && !event.shiftKey) { event.preventDefault(); var message = textarea.value.trim(); textarea.value = ""; // 发送 POST 请求 fetch('/chat/chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ content: message }) }).then(function(response) { // 刷新页面 location.reload(); }); } }); textarea.addEventListener("keydown", function(event) { if (event.key === "Enter" && event.shiftKey) { // 在 Shift+Enter 情况下允许换行 textarea.value += "\n"; event.preventDefault(); } });
login.html和chat.html
html/login.html
AI对话
登录
登录html/chat.html
AI对话
AI 对话
后言
待完善的功能:
-
用户对话之后,需要等待回复,才能弹出对话内容
-
等待期间,还能输入聊天框
-
并且,没有终止生成
-
没有左边框-新建对话
-
没有md格式的复制
最后
2024-3-20 21:06:39
迎着日光月光星光,直面风霜雨霜雪霜。
-
还没有评论,来说两句吧...