当前位置: 首页 > wzjs >正文

一台服务器怎么做多给网站教育培训机构前十名

一台服务器怎么做多给网站,教育培训机构前十名,公司网站建设p开发,景安网站备案查询Java入门Spring AI应用开发 环境 JDK 17 Springboot3.5 spring AI 1.0 (最新版本) qwen模型 or deepseek R1 nodejs 22 这我这里懒得弄用的 18 做了一些小操作 前置了解 此文章是学习黑马spring ai大模型教程的 笔记思路理解 关于推理大模型的一些小知识 : 文中所提到的…

Java入门Spring AI应用开发

环境

  • JDK 17

  • Springboot3.5 +spring AI 1.0 (最新版本)

  • qwen模型 or deepseek R1

  • nodejs 22 这我这里懒得弄用的 18 做了一些小操作

前置了解

此文章是学习黑马spring ai+大模型教程的 笔记+思路理解

关于推理大模型的一些小知识 :

  1. 文中所提到的大模型 指 LLM 也就是大语言模型 (Large Language Models, LLM)目前很火的LLM模型大多基于一种源于NLP(自然语言处理)中的一个神经网络模型 Transformer
  2. 这种模型可以对输入的参数进行推理 , 就是将我们给出的prompt作为开头 推理后续的内容 采用持续生成的方式 在海量的训练数据中推理出一句话 也就是比如 你问gpt 我是一个广东人 你推荐我今天吃什么 他会根据你的词 比如 广东 今天 从吃什么 去推理出 比如广东的数据里有早餐 有概率数据 比如多少人早上选择肠粉 那么他继续推理就可以推荐你今天早上吃肠粉
  3. 其他前置知识 比如什么是 llm 什么是ai应用 可以自行去搜索了解

环境选择

image-20250528164423069

这里推荐两种方式 :

  1. 选择基于 ollama本地部署 deepseek r1:8b 模型用于开发学习
  2. 选择阿里云免费送100wtokens 的首次开通服务

阿里云

现在阿里云注册送很多 免费额度 可以直接查看底下的spring ai 开发简单ai应用了

本地部署

这里 博主的主机是 12g现存的 4070s 所以可以小玩一下 之后的演示 也会基于本地部署的r1:8b模型来展示一些操作

首先 打开 ollama 的官网下载 并且安装 ollama 然后搜索deepseek-r1 选择模型参数

官网地址 : https://ollama.com/

安装完成后 直接可以在cmd中查看到 ollama相关的命令

image-20250528170311674

可以看到和 docker的命令非常的相似

这里我选择 8b 先试试水 因为也是第一次

image-20250528165227867

打开 ollama的控制台 输入命令ollama run deepseek-r1:8b 直接复制即可

image-20250528170114189

image-20250528170404859

下载完成之后 就会启动大模型 我们就可以通过控制台和本地的模型对话了 因为参数低 可能会很慢

小贴士:

什么是大模型应用?

就是通过自己平台调用 推理模型返回结果的平台 比如目前非常常见的各大厂商免费的ai问答网站 都属于大模型应用的一种

RAG应用是什么

其实就是在大模型应用的基础上外挂了一层字典 也可以理解成知识库 可以通过这个知识库快速的检索问题 从而提升回复的精准性和可靠性, 核心思想就是通过实时检索外部知识库作为回复的根基 而不是纯靠大模型

Spring AI

简单的了解

Spring ai 帮我们把接入大模型到使用简化到了 三步:

  • 正确的依赖引入
  • 配置文件
  • 简单的Spring注入

然后只需要按照官方文档提供的调用模式 调用client就可以完成对模型的prompt发送以及获取回复的信息

image-20250528172817945

简单问答助手

创建全新Springboot 项目 ai-web

依赖

    <properties><java.version>17</java.version><spring-ai.version>1.0.0</spring-ai.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-ollama</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></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></dependencies>

编写配置文件 :

设置 模型的类型和ollama为我们提供的 默认在 localhost:11434端口下的 api 服务

Spring:application:name: ai-webai:ollama:base-url: http://localhost:11434chat:model: deepseek-r1:8b
server:port: 8080
#用于查看会话日志
logging:level:org.springframework.ai.chat.client.advisor: debugcom.hyc.aiweb: debug

Spring ai 其实已经非常的成熟了 我们编写配置之后只需要少量的代码就可以完成 对大模型的调用

配置一下 client

package com.hyc.aiweb.config;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @author 冷环渊* @date 2025/5/28 17:24* @description ModelClientConfiguration*/
@Configuration
public class ModelClientConfiguration {@Beanpublic ChatClient chatClient(OllamaChatModel model) {return ChatClient.builder(model).defaultSystem("现在你是小冷的助手,请以小冷助手来回答问题").build();}
}

简单的对话连接

package com.hyc.aiweb.controller;import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;/*** @author 冷环渊* @date 2025/5/28 17:29* @description ChatController*/
@RestController
@RequestMapping("/ai")
@RequiredArgsConstructor
public class ChatController {private final ChatClient chatClient;//    @RequestMapping("/chat")
//    public String chat(@RequestParam String prompt) {
//        //阻塞式的调用 当全部结果返回的时候才会返回
//        return chatClient.prompt()
//                .user(prompt)
//                .call()
//                .content();
//    }@RequestMapping(value = "/chat", produces = "text/html;charset=utf-8")public Flux<String> chat(@RequestParam String prompt) {//流式调用return chatClient.prompt().user(prompt).stream().content();}
}

测试

image-20250528174722819

到这里我们已经完成最简单的 本地模型 交互

会话日志

Spring AI 给我们提供了基于aop的回话增强 Advisor 用于提供一些辅助 比如交互式ai平台最常见的 对话记录

image-20250528175248574

添加基础日志环绕增强

@Configuration
public class ModelClientConfiguration {@Beanpublic ChatClient chatClient(OllamaChatModel model) {return ChatClient.builder(model).defaultSystem("你是一个可爱的助手, 名字叫小冷").defaultAdvisors(new SimpleLoggerAdvisor()).build();}
}

刷新一下网页 之后查看idea控制台的日志 就可以看到我们的请求信息和回复信息 以 json的格式

image-20250528175839103

接入前端

这里我们使用黑马提供的前端来让交互看起来更加的贴近平台, 可以去黑马程序员公众号自行的搜索获取代码资源

前端项目

这里我们需要去做一些前后端分离必须要做的事情 , 前端项目的依赖和启动

npm i
npm run start

image-20250528182610976

后端项目配置跨域

package com.hyc.aiweb.config;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** @author 冷环渊* @date 2025/5/28 17:24* @description ModelClientConfiguration*/
@Configuration
public class CorsConfiguration implements WebMvcConfigurer {public void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS").allowedHeaders("*");}
}

重启项目 就可以在智能对话中 开始对话了

效果

image-20250528182834869

会话记忆

我们刷新界面会发现 对话的内容什么的 全部都消失了 ,现在我们需要增加 会话记录和会话记忆的小功能

大模型本身并不具备记忆功能 , 这里我们将利用 client中的 一个消息类型 ASSISTANT 来实现对大模型生产的消息进行进行反复的使用 达成一个模拟场景记忆的效果 , 以阿里云的大模型文本调试控制台为例

image-20250528183708467

Spring ai 提供了一个接口 叫做 ChatMemory 用于规范我们使用会话记忆, 这里我们的制作思路是 :

  1. 每一段会话都会有一个id
  2. 存储方式基于ChatMemory 也就是 id+消息集合的方式

定义ChatMemory

spring ai ga1 版本中 与视频有差异 可以采用builder的方式来实现定义

package com.hyc.aiweb.config;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @author 冷环渊* @date 2025/5/28 17:24* @description ModelClientConfiguration*/
@Configuration
public class ModelClientConfiguration {@Beanpublic ChatMemory chatMemory() {return MessageWindowChatMemory.builder().build();}/*** 注入 chatclient 用于 ai对话** @author 冷环渊* date: 2025/5/28 18:41*/@Beanpublic ChatClient chatClient(OllamaChatModel model, ChatMemory chatMemory) {return ChatClient.builder(model).defaultSystem("你是一个可爱的助手, 名字叫小冷,请以小冷的身份和语气回答问题").defaultAdvisors(new SimpleLoggerAdvisor(),MessageChatMemoryAdvisor.builder(chatMemory).build()).build();}
}

定义完之后 我们就有了对话记忆 但是我们缺少什么? 我们会发现所有的会话都是混乱的记忆

基于id来管理记忆

黑马提供的前端项目中帮我们生成了 id 我们只需要接受id 并且设置在client 中就完成了 基于id 区分和管理 对话记忆

image-20250528185352069

这里视频中的演示已经过时 最新的官方文档中提示

The main changes that impact end user code are: In VectorStoreChatMemoryAdvisor: The constant CHAT_MEMORY_RETRIEVE_SIZE_KEY has been renamed to TOP_K. The constant DEFAULT_CHAT_MEMORY_RESPONSE_SIZE (value: 100) has been renamed to DEFAULT_TOP_K with a new default value of 20. The constant CHAT_MEMORY_CONVERSATION_ID_KEY has been renamed to CONVERSATION_ID and moved from AbstractChatMemoryAdvisor to the ChatMemory interface. Update your imports to use org.springframework.ai.chat.memory.ChatMemory.CONVERSATION_ID

image-20250528190045288

根据以上规则 去 编写逻辑

    @RequestMapping(value = "/chat", produces = "text/html;charset=utf-8")public Flux<String> chat(@RequestParam String prompt, String chatId) {//流式调用return chatClient.prompt().user(prompt).advisors(a -> a.param(ChatMemory.CONVERSATION_ID,chatId)).stream().content();}

测试

默认会话 :

image-20250528190249547

这是会话1:

image-20250528190330838

实现了上下文的隔离 以及一段对话的记忆 , 查看日志

image-20250528191234587

在下一段对话响应前 会先传入上次对话的结果 类型为 ASSISTANT,再多输入一段内容 就会将上次的两个内容先传入到对话中再去执行内容 这就是对话记忆

image-20250528191422070

会话历史

根据请求的业务类型和id记录历史

image-20250528192336713

这个就是简单的业务了 :

  1. 查询左侧的会话记录并且返回 一个id集合
  2. 查询单次id的会话历史返回消息的集合
  3. 我们就是用map在内存中保存记录

创建接口

package com.hyc.aiweb.repository;import java.util.List;public interface ChatHistoryRepository {/*** 保存会话记录** @author 冷环渊* date: 2025/5/28 19:27*/void save(String type, String chatId);/*** 根据业务类型返回id列表** @author 冷环渊* date: 2025/5/28 19:27*/List<String> getChatIds(String type);
}

实现接口

package com.hyc.aiweb.repository;import org.springframework.stereotype.Component;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** @author 冷环渊* @date 2025/5/28 19:28* @description ChatHistoryRepositoryImpl*/
@Component
public class ChatHistoryRepositoryImpl implements ChatHistoryRepository {//    存储到map中private final Map<String, List<String>> chatHistoryMap = new HashMap<>();@Overridepublic void save(String type, String chatId) {List<String> chatIds = chatHistoryMap.computeIfAbsent(type, k -> new ArrayList<>());if (chatIds.contains(chatId)) {return;}chatIds.add(chatId);}@Overridepublic List<String> getChatIds(String type) {return chatHistoryMap.getOrDefault(type, List.of());}
}

VO对象

package com.hyc.aiweb.controller.vo;import lombok.Data;
import org.springframework.ai.chat.messages.Message;/*** @author 冷环渊* @date 2025/5/28 19:37* @description MessageVO*/
@Data
public class MessageVO {private String role;private String content;public MessageVO(Message message) {switch (message.getMessageType()) {case USER:role = "user";break;case ASSISTANT:role = "assistant";break;}this.content = message.getText();}
}

controller

package com.hyc.aiweb.controller;import com.hyc.aiweb.controller.vo.MessageVO;
import com.hyc.aiweb.repository.ChatHistoryRepositoryImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;import java.util.List;/*** @author 冷环渊* @date 2025/5/28 17:29* @description ChatController*/
@RestController
@RequestMapping("/ai")
@RequiredArgsConstructor
public class ChatController {private final ChatClient chatClient;private final ChatHistoryRepositoryImpl chatHistoryRepository;private final ChatMemory chatMemory;//    @RequestMapping("/chat")
//    public String chat(@RequestParam String prompt) {
//        //阻塞式的调用 当全部结果返回的时候才会返回
//        return chatClient.prompt()
//                .user(prompt)
//                .call()
//                .content();
//    }@RequestMapping(value = "/chat", produces = "text/html;charset=utf-8")public Flux<String> chat(@RequestParam String prompt, String chatId) {chatHistoryRepository.save("chat", chatId);//流式调用return chatClient.prompt().user(prompt).advisors(a -> a.param(ChatMemory.CONVERSATION_ID, chatId)).stream().content();}@GetMapping(value = "/history/{type}")public List<String> historyChat(@PathVariable("type") String type) {return chatHistoryRepository.getChatIds(type);}@GetMapping(value = "/history/{type}/{chatId}")public List<MessageVO> historyChat(@PathVariable("type") String type, @PathVariable("chatId") String chatId) {List<MessageVO> messageList = chatMemory.get(chatId).stream().map(MessageVO::new).toList();if (messageList == null) {return List.of();}System.out.println(messageList);return messageList;}
}

测试

这是第一个会话的记录:

image-20250528200628953

第二个会话的记录:

image-20250528200649756

从测试中我们就可以看到 我们成功的保留了有内容的会话,并且每个会话都有消息历史

总结

通过这么一个短篇小文章 就已经接触到了 基于llm开发ai应用的门槛 我们在这次学习中 学习到了一些关于模型的知识 以及Spring ai的使用 ,这里我们复习一下逻辑

  1. llm是基于推理模型来完成对话的
  2. Spring ai的使用分为 配置client 如果需要上下文对话这需要开启advisors,并且添加到client配置项
  3. 如果需要记录历史 则需要配置chatMemory 并且添加新的MessageChatMemoryAdvisor.builder(chatMemory).build()到client的defaultAdvisors中之后就可以通过 chatMemory来对会话的历史进行操作

小拓展

可以将历史存入 redis中进行三十天有效 或者更长的时间来处理

http://www.dtcms.com/wzjs/47380.html

相关文章:

  • 专业做网站有哪些百度文库官网登录入口
  • 前端做商城网站需要多久线上营销渠道
  • 企业网站里面的qq咨询怎么做上海百度推广公司排名
  • 大连承揽营销型网站公司成都专业seo公司
  • 石家庄手机网站开发磁力最好用的搜索引擎
  • wordpress美女图片站主题营销推广案例
  • 厦门同安网站建设网站排名搜索
  • 做一件代发的网站东莞疫情最新消息
  • 虫虫 wordpress 群发搜索引擎优化工作
  • 四川住房和城乡建设厅网站主页seo的方式包括
  • 荆州哪里有做网站的seo优化便宜
  • 做火情监控网站需要用什么系统地推的60种方法
  • 林业门户网站建设网络广告营销成功案例
  • 自助网站建设哪家好南京seo优化推广
  • 猎头可以做单的网站地推网app推广平台
  • 网站建设公司制作网站关键词工具
  • 浅谈电子商务网站建设与管理的理解镇江百度关键词优化
  • 南京鼓楼做网站公司网站代搭建维护
  • 网站推广网站关键词排名怎么做网站推广费用
  • 建一个类似亨物说网站建设费用网络营销推广主要做什么
  • 哪家网站雅虎全球购做的好深圳网络公司推广
  • web毕业设计代做网站网络营销sem培训
  • 全国建设部官方网站俄罗斯引擎搜索
  • 合肥高端网站建设公司网络营销的成功案例有哪些
  • 做项目的网站好看的html网页
  • 网站与装修公司希爱力双效片
  • 湘潭网络公司网站建设软件外包公司有前途吗
  • 易企秀h5制作教程seo百度贴吧
  • 怎么做网站多少钱网络营销推广的5种方法
  • 网站做图片百度推广是做什么的