版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
SpringAI智能对话系统完整实战项目一、项目整体介绍1.技术栈后端:SpringBoot3.2+SpringAI1.0.x大模型支持:OpenAI/通义千问/文心一言/本地Ollama(Llama3/Qwen)持久层:SpringDataRedis(会话上下文存储)+MyBatis-Plus(对话记录持久化MySQL)功能模块:流式对话、多轮上下文记忆、角色设定、知识库RAG、对话历史管理、接口鉴权前端配套:简易Vue流式聊天页面(附接口文档)2.核心能力单轮/多轮连续对话,自动维护会话上下文SSE流式输出打字机效果自定义AI角色、prompt模板统一管理RAG本地知识库问答(文档向量检索)Redis存储会话,支持多用户隔离对话对话记录入库,支持历史查询、清空会话多模型动态切换(OpenAI/阿里云通义/Ollama本地大模型)二、环境依赖配置1.Mavenpom.xml核心依赖xml<!--SpringBoot--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.5</version><relativePath/></parent><dependencies><!--WebSSE流式响应--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--SpringAI核心--><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId><version>1.0.0</version></dependency><!--本地Ollama支持(可选)--><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-ollama-spring-boot-starter</artifactId><version>1.0.0</version></dependency><!--阿里云通义千问(可选)--><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-alibaba-spring-boot-starter</artifactId><version>1.0.0</version></dependency><!--Redis会话记忆存储--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!--MySQL对话记录持久化--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.5</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><!--RAG向量库:Chroma本地轻量向量库--><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-chroma-store-spring-boot-starter</artifactId><version>1.0.0</version></dependency><!--工具--><dependency><groupId>jectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.32</version></dependency></dependencies>2.application.yml配置yaml#服务端口server:port:8080servlet:context-path:/ai#数据库spring:datasource:driver-class-name:com.mysql.cj.jdbc.Driverurl:jdbc:mysql://:3306/spring_ai_chat?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghaiusername:rootpassword:root#Redis会话存储data:redis:host:port:6379password:database:0#SpringAI配置spring.ai:#OpenAI配置(优先使用)openai:api-key:sk-xxx你的密钥xxxbase-url:/v1chat:options:model:gpt-3.5-turbotemperature:0.7max-tokens:1024#本地Ollama备用ollama:base-url::11434chat:options:model:qwen:7b#向量库vectorstore:chroma:client:host:localhostport:8000collection-name:chat_knowledge#MyBatis-Plusmybatis-plus:mapper-locations:classpath:mapper/**/*.xmltype-aliases-package:com.ai.chat.entityconfiguration:map-underscore-to-camel-case:truelog-impl:org.apache.ibatis.logging.stdout.StdOutImpl三、数据库表设计1.对话记录表chat_recordsqlCREATETABLE`chat_record`(`id`bigintNOTNULLAUTO_INCREMENTCOMMENT'主键',`user_id`varchar(64)NOTNULLCOMMENT'用户唯一标识',`session_id`varchar(64)NOTNULLCOMMENT'会话ID',`role`varchar(16)NOTNULLCOMMENT'角色user/assistant',`content`textNOTNULLCOMMENT'对话内容',`model_name`varchar(32)DEFAULTNULLCOMMENT'使用模型',`create_time`datetimeDEFAULTCURRENT_TIMESTAMP,PRIMARYKEY(`id`),KEYidx_user_session(`user_id`,`session_id`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4COMMENT='对话历史记录';四、核心代码分层实现1.实体类ChatRecordjava运行packagecom.ai.chat.entity;importcom.baomidou.mybatisplus.annotation.IdType;importcom.baomidou.mybatisplus.annotation.TableId;importcom.baomidou.mybatisplus.annotation.TableName;importlombok.Data;importjava.time.LocalDateTime;@Data@TableName("chat_record")publicclassChatRecord{@TableId(type=IdType.AUTO)privateLongid;privateStringuserId;privateStringsessionId;privateStringrole;privateStringcontent;privateStringmodelName;privateLocalDateTimecreateTime;}2.请求DTOChatRequestjava运行packagecom.ai.chat.dto;importlombok.Data;@DatapublicclassChatRequest{//用户IDprivateStringuserId;//会话ID,同一轮对话保持一致privateStringsessionId;//用户提问内容privateStringmessage;//自定义AI角色描述privateStringsystemPrompt;//是否开启RAG知识库privateBooleanuseRag=false;}3.Redis会话记忆工具(多轮对话上下文)SpringAI自带ChatMemory,封装Redis持久化会话,实现多轮记忆不丢失java运行packagecom.ai.chat.memory;importorg.springframework.ai.chat.memory.ChatMemory;importorg.springframework.ai.chat.memory.RedisChatMemory;importorg.springframework.data.redis.core.RedisTemplate;importorg.springframework.stereotype.Component;@ComponentpublicclassChatMemoryManager{privatefinalRedisTemplate<String,Object>redisTemplate;publicChatMemoryManager(RedisTemplate<String,Object>redisTemplate){this.redisTemplate=redisTemplate;}/***获取指定会话的记忆容器*/publicChatMemorygetMemory(StringsessionId){//会话过期30分钟returnnewRedisChatMemory(redisTemplate,"chat:memory:"+sessionId,1800L);}/***清空会话上下文*/publicvoidclearMemory(StringsessionId){getMemory(sessionId).clear(sessionId);}}4.RAG知识库服务(文档问答)java运行packagecom.ai.chat.service;importorg.springframework.ai.chat.client.ChatClient;importorg.springframework.ai.document.Document;importorg.springframework.ai.reader.TextReader;importorg.springframework.ai.transformer.splitter.TokenTextSplitter;importorg.springframework.ai.vectorstore.VectorStore;importorg.springframework.stereotype.Service;importorg.springframework.core.io.FileSystemResource;importjava.util.List;@ServicepublicclassRagService{privatefinalVectorStorevectorStore;privatefinalChatClientchatClient;publicRagService(VectorStorevectorStore,ChatClient.BuilderchatClientBuilder){this.vectorStore=vectorStore;this.chatClient=chatClientBuilder.build();}//加载本地文档到向量库publicvoidloadDoc(StringfilePath){TextReaderreader=newTextReader(newFileSystemResource(filePath));List<Document>docs=reader.get();//文本分割TokenTextSplittersplitter=newTokenTextSplitter();List<Document>splitDocs=splitter.apply(docs);vectorStore.add(splitDocs);}//根据问题检索相关上下文publicStringretrieveContext(Stringquery){List<Document>similarDocs=vectorStore.similaritySearch(query,3);StringBuildercontext=newStringBuilder();for(Documentdoc:similarDocs){context.append(doc.getContent()).append("\n");}returncontext.toString();}}5.核心对话业务服务ChatServicejava运行packagecom.ai.chat.service;importcom.ai.chat.dto.ChatRequest;importcom.ai.chat.entity.ChatRecord;importcom.ai.chat.mapper.ChatRecordMapper;importcom.ai.chat.memory.ChatMemoryManager;importorg.springframework.ai.chat.client.ChatClient;importorg.springframework.ai.chat.memory.ChatMemory;importorg.springframework.stereotype.Service;importreactor.core.publisher.Flux;importjava.time.LocalDateTime;@ServicepublicclassChatService{privatefinalChatClient.BuilderchatClientBuilder;privatefinalChatMemoryManagermemoryManager;privatefinalChatRecordMapperrecordMapper;privatefinalRagServiceragService;publicChatService(ChatClient.BuilderchatClientBuilder,ChatMemoryManagermemoryManager,ChatRecordMapperrecordMapper,RagServiceragService){this.chatClientBuilder=chatClientBuilder;this.memoryManager=memoryManager;this.recordMapper=recordMapper;this.ragService=ragService;}/***SSE流式对话*/publicFlux<String>streamChat(ChatRequestreq){ChatMemorymemory=memoryManager.getMemory(req.getSessionId());ChatClientclient=chatClientBuilder.defaultSystem(req.getSystemPrompt()==null?"你是智能助手,简洁回答用户问题":req.getSystemPrompt()).chatMemory(memory).build();StringuserMsg=req.getMessage();//开启RAG则拼接检索到的知识库上下文if(Boolean.TRUE.equals(req.getUseRag())){Stringcontext=ragService.retrieveContext(userMsg);userMsg="参考资料:"+context+"\n用户问题:"+userMsg;}//保存用户提问入库saveRecord(req,"user",req.getMessage());//流式返回AI输出Flux<String>flux=mpt().user(userMsg).stream().content();//流式拼接完整回答,结束后入库StringBuilderfullResp=newStringBuilder();returnflux.doOnNext(chunk->fullResp.append(chunk)).doOnComplete(()->saveRecord(req,"assistant",fullResp.toString()));}//保存对话记录到MySQLprivatevoidsaveRecord(ChatRequestreq,Stringrole,Stringcontent){ChatRecordrecord=newChatRecord();record.setUserId(req.getUserId());record.setSessionId(req.getSessionId());record.setRole(role);record.setContent(content);record.setModelName("gpt-3.5-turbo");record.setCreateTime(LocalDateTime.now());recordMapper.insert(record);}//清空会话上下文publicvoidclearSession(StringsessionId){memoryManager.clearMemory(sessionId);}}6.Controller流式对话接口(SSE)java运行packagecom.ai.chat.controller;importcom.ai.chat.dto.ChatRequest;importcom.ai.chat.service.ChatService;importorg.springframework.http.MediaType;importorg.springframework.web.bind.annotation.*;importreactor.core.publisher.Flux;@RestController@RequestMapping("/chat")publicclassChatController{privatefinalChatServicechatService;publicChatController(ChatServicechatService){this.chatService=chatService;}/***流式对话接口SSE*/@PostMapping(value="/stream",produces=MediaType.TEXT_EVENT_STREAM_VALUE)publicFlux<String>streamChat(@RequestBodyChatRequestrequest){returnchatService.streamChat(request);}/***清空当前会话记忆*/@DeleteMapping("/session/{sessionId}")publicStringclearSession(@PathVariableStringsessionId){chatService.clearSession(sessionId);return"会话已清空";}}五、前端调用示例(JSSSE)javascript运行//前端发起流式对话asyncfunctionsendChat(){
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年上海市南汇区街道办人员招聘考试模拟试题及答案详解
- 2025年沈阳市大东区辅警协警招聘笔试试题及答案详解
- 2026年鹰潭市月湖区街道办人员招聘考试模拟试题及答案详解
- 2026年保定市南市区中小学教师招聘考试备考试题及答案详解
- 2026年保定市北市区街道办人员招聘笔试参考题库及答案详解
- 2026年社区工作者高频考点知识测试题库及答案
- 2026年游泳教练资格认证考试模拟题集及答案解析
- 智能产品营销与服务(第2版 新形态版)课件 郭洪延 第7-13章:智能产品广告投放-使用新媒体进行营销与服务
- 2026年中学生安全知识竞赛试题附答案
- 2026年社区《网格员》城镇片区专项考前冲刺训练试题(含答案)
- 2026年哈尔滨城市发展投资集团面向社会招聘53人笔试模拟试题及答案详解
- 2026中秋国庆备货趋势洞察-尼尔森iq-202607
- 2026交管12123学法减分题库(含完整答案解析全国)
- 2026年四川省成都市公安招聘辅警考试真题及答案
- 电控配电用电缆桥架(JBT 10216-2025)
- 《计算机绘图AutoCAD》电子教案
- 混凝土职业技能竞赛备赛试题库500题(含答案)
- DL∕T 673-2015 火力发电厂水处理用001×7强酸性阳离子交换树脂报废标准
- 阀门投标文件(技术标)
- (高清版)TDT 1056-2019 县级国土资源调查生产成本定额
- 四年级竖式计算大全100道
评论
0/150
提交评论