AI 对话完善【人工智能】
AI 对话【人工智能】
- 前言
- 版权
- 开源
- 推荐
- AI 对话
- v0版本:基础
- v1版本:对话
- 数据表
- tag.js
- TagController
- v2版本:回复中
- textarea.js
- ChatController
- v3版本:流式输出
- chatLast.js
- ChatController
- v4版本:多轮对话
- QianfanUtil
- ChatController
- v5:其他修改
- 前端样式:跳转到最后一个消息
- 前端样式:Message保留空白符
- 前端样式:最新回复保留空白符
- 最后
前言
2024-4-7 15:04:07
以下内容源自《【人工智能】》
仅供学习交流使用
版权
禁止其他平台发布时删除以下此话
本文首次发布于CSDN平台
作者是CSDN@日星月云
博客主页是https://jsss-1.blog.csdn.net
禁止其他平台发布时删除以上此话
开源
日星月云 / AI对话完善版
jsss-1/aichat
推荐
百度智能云+SpringBoot=AI对话【人工智能】
对话Chat-千帆大模型平台
AI 对话
以下版本除了最简单的AI对话,还完善了一下功能。
以下是部分代码,完整代码请移步GIT。
v0版本:基础
聊天
v1版本:对话
新建新对话
可以置顶(取消置顶)、删除、修改对应的对话
数据表
create table tag
(id int auto_incrementprimary key,user_id int not null,tag_name varchar(16) not null,top int default 0 null
);create table conversation
(id int auto_incrementprimary key,tag_id int null,user_message text null,bot_message text null,create_time varchar(32) null,username varchar(16) null
);
tag.js
$(document).ready(function () {tagList();$("#editBlock").hide();$(".add-button").on("click", function() {addTag();});});function tagSearch(data) {var data=$("#search-input").val();if(!data){//没有数据搜索全部tagList();return false;}$.ajax({type: "GET",url: SERVER_PATH + "/tag/search",data: {data: data},xhrFields: {withCredentials: true},success: function (result) {if (result.status) {alertBox(result.data.message);return false;}set_tags(result.data);}});
}function addTag() {$.ajax({type: "POST",url: SERVER_PATH + "/tag/addTag",xhrFields: {withCredentials: true},success: function (result) {if (result.status) {alertBox(result.data.message);return false;}tagList();}});
}function tagList() {$.ajax({type: "GET",url: SERVER_PATH + "/tag/tagList",xhrFields: {withCredentials: true},success: function (result) {if (result.status) {alertBox(result.data.message);return false;}set_tags(result.data);}});
}function set_tags(tags) {if (!tags) {return false;}$(".tag-list").empty();$.each(tags, function (i, tag) {var btnClass = tag.top === 0 ? "top-btn" : "notop-btn";var topClass = tag.top === 0 ? "ptTag" : "topTag";var tagDiv = `<div class="tag"><img class="tag-btn ${topClass}"></img><span class="show-btn" data-id="${tag.id}">${tag.tagName}</span><div class="button-group"><img class="icon-btn ${btnClass}" data-id="${tag.id}"></img><img class="icon-btn modify-btn" data-id="${tag.id}" data-name="${tag.tagName}"></img><img class="icon-btn delete-btn" data-id="${tag.id}"></img></div></div>`;$(".tag-list").append(tagDiv);});$(".show-btn").on("click", function() {var tagId = $(this).data('id');window.location.href="aichat.html?tagId="+tagId;});$(".notop-btn").on("click", function() {var tagId = $(this).data('id');var newTop=0;topTag(tagId,newTop);});$(".top-btn").on("click", function() {var tagId = $(this).data('id');var newTop=top=1;topTag(tagId,newTop);});$(".modify-btn").on("click", function() {var tagId = $(this).data('id');var tagName = $(this).data('name'); // 获取标签名称// 将标签名称填充到输入框中$("#newName").val(tagName);// 显示编辑界面块$("#editBlock").show();// 保存按钮点击事件$("#saveBtn").off("click").on("click", function() {var newName = $("#newName").val();if(!newName){alertBox("请输入新名字");return false;}modify(tagId,newName);// 关闭编辑界面块$("#editBlock").hide();});$("#cancelBtn").on("click", function() {$("#editBlock").hide();});});$(".delete-btn").on("click", function() {var tagId = $(this).data('id');// 弹出确认删除的提示框var confirmDelete = confirm("确定要删除这个标签吗?");// 如果用户点击确定删除,则执行删除操作if (confirmDelete) {deleteTag(tagId);} });}function topTag(tagId,newTop){$.ajax({type: "POST",url: SERVER_PATH + "/tag/top",data: {tagId: tagId,top: newTop},xhrFields: {withCredentials: true},success: function (result) {if (result.status) {alertBox(result.data.message);return false;}tagList();}});
}function modify(tagId,newName){$.ajax({type: "POST",url: SERVER_PATH + "/tag/modify",data: {tagId: tagId,tagName: newName},xhrFields: {withCredentials: true},success: function (result) {if (result.status) {alertBox(result.data.message);return false;}tagList();}});
}function deleteTag(tagId){$.ajax({type: "GET",url: SERVER_PATH + "/tag/delete",data: {tagId: tagId},xhrFields: {withCredentials: true},success: function (result) {if (result.status) {alertBox(result.data.message);return false;}tagList();}});
}
TagController
package com.jsss.qianfan.controller;import com.jsss.common.BusinessException;
import com.jsss.common.ErrorCode;
import com.jsss.common.ResponseModel;
import com.jsss.entity.User;
import com.jsss.qianfan.entity.Tag;
import com.jsss.qianfan.service.TagService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@RequestMapping("tag")
@CrossOrigin(origins = "${jsss.web.path}", allowedHeaders = "*", allowCredentials = "true")
public class TagController implements ErrorCode {@AutowiredRedisTemplate redisTemplate;@AutowiredTagService tagService;@GetMapping("/tagList")public ResponseModel getTags(String token) {User user = null;if (StringUtils.isNotEmpty(token)) {user = (User) redisTemplate.opsForValue().get(token);}if (user == null) {throw new BusinessException(USER_NOT_LOGIN, "用户未登录");}List<Tag> tags = tagService.searchByUserId(user.getUserId());return new ResponseModel(tags);}@PostMapping("/addTag")public ResponseModel addTag(String token) {User user = null;if (StringUtils.isNotEmpty(token)) {user = (User) redisTemplate.opsForValue().get(token);}if (user == null) {throw new BusinessException(USER_NOT_LOGIN, "用户未登录");}String tagName = "新对话";Tag tag = new Tag(null, user.getUserId(), tagName, 0);tagService.addTag(tag);return new ResponseModel("添加成功");}@PostMapping("/modify")public ResponseModel modifyTag(Integer tagId, String tagName) {if (StringUtils.isEmpty(tagName)){throw new BusinessException(PARAMETER_ERROR, "缺失新的tag名");}tagService.updateTagName(tagId, tagName);return new ResponseModel("修改成功");}@PostMapping("/top")public ResponseModel topTag(Integer tagId, Integer top) {tagService.updateTagTop(tagId, top);String res = top == 1 ? "置顶成功" : "取消置顶成功";return new ResponseModel(res);}@GetMapping("/delete")public ResponseModel deleteTag(Integer tagId) {tagService.deleteTag(tagId);return new ResponseModel("删除成功");}@GetMapping("/search")public ResponseModel searchTag(String token, String data) {User user = null;if (StringUtils.isNotEmpty(token)) {user = (User) redisTemplate.opsForValue().get(token);}if (user == null) {throw new BusinessException(USER_NOT_LOGIN, "用户未登录");}List<Tag> tags = tagService.searchTag(user.getUserId(),data);return new ResponseModel(tags);}}
v2版本:回复中
用户发送问题之后,显示回复中,得到回复后显示。
前端发送请求之后,先会得到“回复中”;
之后,去轮询获取最新回复。
后端接受请求之后,先存入到数据库中一个未回复请求。
然后异步得到回复之后,再去更新数据库。
textarea.js
var textarea = document.getElementById("messageInput");var isSendingMessage = false; // 添加一个变量用于标识是否正在发送消息textarea.addEventListener("keydown", function(event) {if (event.key === "Enter" && !event.shiftKey) {event.preventDefault();if (isSendingMessage) {// 如果正在发送消息,则在文本框中添加换行符textarea.value += "\n";} else{var message = textarea.value.trim();textarea.value = "";if(!message){alertBox("输入内容不能为空!");return false;}var tagId=$.getUrlParam("tagId");;if(!tagId){alertBox("没有对应的参数");return false;}isSendingMessage = true; // 设置为true表示正在发送消息$.ajax({type: "POST",url: SERVER_PATH+"/chat/chat",data:{"tagId": tagId,"content":message},xhrFields: {withCredentials: true},success:function(result){isSendingMessage = false; // 发送完成后设置为falseif (result.status) {alertBox(result.data.message);return false;}//请求成功之后list(tagId);getChat(result.data.id);}});}}
});textarea.addEventListener("keydown", function(event) {if (event.key === "Enter" && event.shiftKey) {// 在 Shift+Enter 情况下允许换行textarea.value += "\n";event.preventDefault();}
});function getChat(chatId){var tagId=$.getUrlParam("tagId");;$.ajax({type: "GET",url: SERVER_PATH+"/chat/getChat",data:{"id": chatId,},xhrFields: {withCredentials: true},success:function(result){isSendingMessage = false; // 发送完成后设置为falseif (result.status) {alertBox(result.data.message);return false;}if (result.data.botMessage == "回复中...") {// 继续轮询,100ms 一次setTimeout(function() {getChat(chatId);}, 100);} else {// 获取到最终回复// 处理回复逻辑list(tagId);}}});
}
ChatController
@PostMapping("/chat")public ResponseModel chat(Integer tagId,String content){if (tagId==null){throw new BusinessException(PARAMETER_ERROR,"没有指定响应的tag");}if (StringUtils.isEmpty(content)){throw new BusinessException(PARAMETER_ERROR,"输入内容不能为空");}Tag tag = tagService.searchById(tagId);if (tag==null){throw new BusinessException(NOT_FIND,"没有找到对应的对话");}String username=userService.selectUserById(tag.getUserId()).getUsername();Conversation conversation = new Conversation(null, tagId,username, content, "回复中...", format(new Date()));chatService.addChat(conversation);// 异步处理AI回复CompletableFuture.runAsync(() -> {Integer id=conversation.getId();String res = null;try {res = qianfanUtil.addMessage(content);} catch (Exception e) {res = "回复失败";}Conversation aiConversation = new Conversation();aiConversation.setId(id);aiConversation.setBotMessage(res);chatService.updateChat(aiConversation);});return new ResponseModel(conversation);}
v3版本:流式输出
流式输出,终止生成。
前端实现,让消息一个字符一个字符显示
chatLast.js
var lastId;
var interval;$(document).ready(function () {$("#stopButton").on("click", function() {var latestReply = $(".latest-reply");var latestReplyText = latestReply.text();clearInterval(interval); // 停止字符流输出$("#stopButton").hide();updateStop(lastId,latestReplyText);});});function listLastReply(tagId) {$.ajax({type: "GET",url: SERVER_PATH + "/chat/list",data: {tagId: tagId},xhrFields: {withCredentials: true},success: function (result) {if (result.status) {alertBox(result.data.message);return false;}set_conversations_last(result.data);}});
}function set_conversations_last(conversations) {if (!conversations) {return false;}$(".conversation-list").empty();var len=conversations.length;$.each(conversations, function (i, conversation) {var questionDiv = '<div class="question-container">' +'<table class="question">' +'<td>' +'<span>' + conversation.createTime + '</span>' +'<div class="user-message">' + conversation.userMessage + '</div>' +'</td>' +'<td type="text">' + conversation.username + '</td>' +'</table>' +'</div>';var answerDiv = '<div class="answer-container">' +'<table class="answer">' +'<td type="text">AI</td>' +'<td>' +'<span>' + conversation.createTime + '</span>' +'<div class="bot-message">' + conversation.botMessage + '</div>' +'</td>' +'</table>' +'</div>';if(i!=len-1){$(".conversation-list").append(questionDiv);$(".conversation-list").append(answerDiv);}});// 获取最新对话的回复var lastConversation = conversations[len - 1];lastId=lastConversation.id;var questionDiv = '<div class="question-container">' +'<table class="question">' +'<td>' +'<span>' + lastConversation.createTime + '</span>' +'<div class="user-message">' + lastConversation.userMessage + '</div>' +'</td>' +'<td type="text">' + lastConversation.username + '</td>' +'</table>' +'</div>';$(".conversation-list").append(questionDiv);var answerDiv = '<div class="answer-container">' +'<table class="answer">' +'<td type="text">AI</td>' +'<td>' +'<span>' + lastConversation.createTime + '</span>' +'<div class="bot-message latest-reply">' + lastConversation.botMessage + '</div>' +'</td>' +'</table>' +'</div>';$(".conversation-list").append(answerDiv);// 逐字显示最新回复var latestReply = $(".latest-reply");var latestReplyText = latestReply.text();latestReply.empty();var index = 0;interval = setInterval(function() {if (index < latestReplyText.length) {$("#stopButton").show();latestReply.append(latestReplyText.charAt(index));index++;} else {clearInterval(interval);$("#stopButton").hide();}}, 10); // 逐字显示的速度,您可以根据需要调整}function updateStop(tagId,message){$.ajax({type: "POST",url: SERVER_PATH + "/chat/updateStop",data: {id: tagId,botMessage: message},xhrFields: {withCredentials: true},success: function (result) {if (result.status) {alertBox(result.data.message);return false;}}});
}
ChatController
@PostMapping("/updateStop")public ResponseModel updateStop(Integer id,String botMessage){Conversation conversation=new Conversation();conversation.setId(id);conversation.setBotMessage(botMessage);chatService.updateChat(conversation);return new ResponseModel();}
v4版本:多轮对话
实现上下文有关的对话
多次调用qianfan.addMessage().addMessage()
QianfanUtil
public String addMessagePlus(List<Message> messages, String content) {ChatResponse response = qianfan.chatCompletion().messages(messages).addMessage("user", content).temperature(0.7).execute();return response.getResult();}
ChatController
@PostMapping("/chat")public ResponseModel chat(Integer tagId, String content) {if (tagId == null) {throw new BusinessException(PARAMETER_ERROR, "没有指定响应的tag");}if (StringUtils.isEmpty(content)) {throw new BusinessException(PARAMETER_ERROR, "输入内容不能为空");}Tag tag = tagService.searchById(tagId);if (tag == null) {throw new BusinessException(NOT_FIND, "没有找到对应的对话");}String username = userService.selectUserById(tag.getUserId()).getUsername();Conversation conversation = new Conversation(null, tagId, username, content, "回复中...", format(new Date()));chatService.addChat(conversation);// 异步处理AI回复CompletableFuture.runAsync(() -> {Integer id = conversation.getId();String res = null;try {
// res = qianfanUtil.addMessage(content);res = qianfanUtil.addMessagePlus(getMessages(tagId), content);} catch (Exception e) {res = "回复失败";}Conversation aiConversation = new Conversation();aiConversation.setId(id);aiConversation.setBotMessage(res);chatService.updateChat(aiConversation);});return new ResponseModel(conversation);}public List<Message> getMessages(Integer tagId) {List<Message> messages = new ArrayList<>();List<Conversation> conversations = chatService.searchByTagId(tagId);int size = conversations.size() - 1;//最新的不需要for (int i = 0; i < size; i++) {Conversation conversation = conversations.get(i);Message userMessage = new Message();userMessage.setRole("user");userMessage.setContent(conversation.getUserMessage());messages.add(userMessage);Message botMessage = new Message();botMessage.setRole("assistant");botMessage.setContent(conversation.getBotMessage());messages.add(botMessage);}return messages;}
v5:其他修改
前端样式:跳转到最后一个消息
在aichat.html中
<script>function scrollToLastMessage() {// 找到消息容器var messageContainer = document.querySelector(".message-container");// 找到消息容器中最后一个子元素var lastMessage = messageContainer.lastElementChild;// 将最后一个消息元素滚动到可见区域lastMessage.scrollIntoView({ behavior: 'auto', block: 'end' });}function onLoad() {setTimeout(scrollToLastMessage, 100); // 添加100毫秒的延迟}window.addEventListener('load', onLoad);</script>
前端样式:Message保留空白符
savePre(conversation.userMessage)
savePre(conversation.botMessage)
function savePre(content){return content.replace(/\n/g, "<br>").replace(/ /g, "<span> </span>");
}
前端样式:最新回复保留空白符
var botMessageWithBrAndSpace = lastConversation.botMessage.replace(/\n/g, "\\n");var answerDiv = '<div class="answer-container">' +'<table class="answer">' +'<td type="text">AI</td>' +'<td>' +'<span>' + lastConversation.createTime + '</span>' +'<div class="bot-message latest-reply">' + botMessageWithBrAndSpace + '</div>' +'</td>' +'</table>' +'</div>';$(".conversation-list").append(answerDiv);// 逐字显示最新回复var latestReply = $(".latest-reply");var latestReplyText = botMessageWithBrAndSpace;latestReply.empty();var index = 0;interval = setInterval(function() {if (index < latestReplyText.length) {$("#stopButton").show();if (latestReplyText.charAt(index) === "\\") {if (latestReplyText.charAt(index + 1) === "n") {latestReply.append("<br>");index++; // 跳过"n"} else {latestReply.append(latestReplyText.charAt(index));}} else if(latestReplyText.charAt(index)===' '){latestReply.append(" ");}else {latestReply.append(latestReplyText.charAt(index));}index++;} else {clearInterval(interval);$("#stopButton").hide();}}, 25); // 逐字显示的速度,您可以根据需要调整}
最后
2024-4-10 17:02:49
迎着日光月光星光,直面风霜雨霜雪霜。
相关文章:

AI 对话完善【人工智能】
AI 对话【人工智能】 前言版权开源推荐AI 对话v0版本:基础v1版本:对话数据表tag.jsTagController v2版本:回复中textarea.jsChatController v3版本:流式输出chatLast.jsChatController v4版本:多轮对话QianfanUtilChat…...
利用数组储存表格数据
原理以及普通数组储存表格信息 在介绍数组的时候说过,数组能够用来储存任何同类型的数据,这里的意思就表明只要是同一个类型的数组据就可以储存到一个数组中。那么在表格中同一行的数据是否可以储存到同一个数组中呢?答案自然是可以ÿ…...

[数据概念|数据技术]智能合约如何助力数据资产变现
“ 区块链上数据具有高可信度,智能合约将区块链变得更加智能化,以支持企业场景。” 之前鼹鼠哥已经发表了一篇文章,简单介绍了区块链,那么,智能合约又是什么呢?它又是如何助力数据资产变现的呢?…...
JS中的常见二进制数据格式
格式描述用途示例ArrayBuffer固定长度的二进制数据缓冲区,不直接操作具体的数据,而是通过类型数组或DataView对象来读写用于存储和处理大量的二进制数据,如文件、图像等let buffer new ArrayBuffer(16);TypedArray基于ArrayBuffer对象的视图…...

uniapp开发h5端使用video播放mp4格式视频黑屏,但有音频播放解决方案
mp4格式视频有一些谷歌播放视频黑屏,搜狗浏览器可以正常播放 可能和视频的编码格式有关,谷歌只支持h.264编码格式的视频播放 将mp4编码格式修改为h.264即可 转换方法: 如果是自己手动上传文件可以手动转换 如果是后端接口调取的地址就需…...

Hive的分区与排序
一、Hive分区 1.引入: 在大数据中,最常见的一种思想就是分治,我们可以把大的文件切割划分成一个个的小的文件,这样每次操作一个个小的文件就会很容易了,同样的道理,在hive当中也是支持这种思想的ÿ…...
Objective-C学习笔记(内存管理、property参数)4.9
1.引用计数器retainCount:每个对象都有这个属性,默认值为1,记录当前对象有多少人用。 为对象发送一条retain/release消息,对象的引用计数器加/减1,为对象发一条retainCount,得到对象的引用计数器值,当计数器…...

C语言进阶课程学习记录-第29课 - 指针和数组分析(下)
C语言进阶课程学习记录-第29课 - 指针和数组分析(下) 数组名与指针实验-数组形式转换实验-数组名与指针的差异实验-转化后数组名加一的比较实验-数组名作为函数形参小结 本文学习自狄泰软件学院 唐佐林老师的 C语言进阶课程,图片全部来源于课…...

一起学习python——基础篇(13)
前言,python编程语言对于我个人来说学习的目的是为了测试。我主要做的是移动端的开发工作,常见的测试主要分为两块,一块为移动端独立的页面功能,另外一块就是和其他人对接工作。 对接内容主要有硬件通信协议、软件接口文档。而涉…...

SOCKS代理概述
在网络技术的广阔领域中🌐,SOCKS代理是一个核心组件,它在提升在线隐私保护🛡️、实现匿名通信🎭以及突破网络访问限制🚫方面发挥着至关重要的作用。本文旨在深入探讨SOCKS代理的基础,包括其定义…...

AI助力M-OFDFT实现兼具精度与效率的电子结构方法
编者按:为了使电子结构方法突破当前广泛应用的密度泛函理论(KSDFT)所能求解的分子体系规模,微软研究院科学智能中心的研究员们基于人工智能技术和无轨道密度泛函理论(OFDFT)开发了一种新的电子结构计算框架…...

【数据结构】单链表(一)
上一篇【数据结构】顺序表-CSDN博客 我们了解了顺序表,但是呢顺序表涉及到了一些问题,比如,中间/头部的插入/删除,时间复杂度为O(N);增容申请空间、拷贝、释放旧空间会有不小的消耗;增容所浪费的空间... 我们如何去解…...

SCI一区 | Matlab实现INFO-TCN-BiGRU-Attention向量加权算法优化时间卷积双向门控循环单元注意力机制多变量时间序列预测
SCI一区 | Matlab实现INFO-TCN-BiGRU-Attention向量加权算法优化时间卷积双向门控循环单元注意力机制多变量时间序列预测 目录 SCI一区 | Matlab实现INFO-TCN-BiGRU-Attention向量加权算法优化时间卷积双向门控循环单元注意力机制多变量时间序列预测预测效果基本介绍模型描述程…...

Coursera吴恩达《深度学习》课程总结(全)
这里有Coursera吴恩达《深度学习》课程的完整学习笔记,一共5门课:《神经网络和深度学习》、《改善深层神经网络》、《结构化机器学习项目》、《卷积神经网络》和《序列模型》, 第一门课:神经网络和深度学习基础,介绍一…...

C# 操作PDF表单 - 创建、填写、删除PDF表单域
通常情况下,PDF文件是不可编辑的,但PDF表单提供了一些可编辑区域,允许用户填写和提交信息。PDF表单通常用于收集信息、反馈或进行在线申请,是许多行业中数据收集和交换的重要工具。 PDF表单可以包含各种类型的输入控件࿰…...

Astropy:探索宇宙奥秘的Python工具箱
Astropy:探索宇宙奥秘的Python工具箱 什么是Astropy库? Astropy 是一个面向天文学领域的 Python 库,旨在提供常用的天文学数据结构、单位转换、物理常数以及天文学计算方法等功能。它为天文学家和研究人员提供了丰富的工具,用于处理和分析天文…...

java数据结构与算法刷题-----LeetCode684. 冗余连接
java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846 文章目录 并查集 并查集 解题思路:时间复杂度O( n ∗ l o g 2…...

循环神经网络简介
卷积神经网络相当于人类的视觉,但是它并没有记忆能力,所以它只能处理一种特定的视觉任务,没办法根据以前的记忆来处理新的任务。比如,在一场电影中推断下一个时间点的场景,这个时候仅依赖于现在的场景还不够࿰…...
计算机网络 子网掩码与划分子网
一、实验要求与内容 1、需拓扑图和两个主机的IP配置截图。 2、设置网络A内的主机IP地址为“192.168.班内学号.2”,子网掩码为“255.255.255.128”,网关为“192.168.班内学号.1”;设置网络B内的主机IP地址为“192.168.班内学号100.2”&#…...

HUD抬头显示器中如何设计LCD的阳光倒灌实验
关键词:阳光倒灌实验、HUD光照温升测试、LCD光照温升测试、太阳光模拟器 HUD(Head-Up Display,即抬头显示器)是一种将信息直接投影到驾驶员视线中的技术,通常用于飞机、汽车等驾驶舱内。HUD系统中的LCD(Liq…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...