AI对话-SpringAI破局尝试
目录
SpringAI+DeepSeek大模型应用开发
功能:聊天,会话日志,会话记忆,会话历史
对话机器人效果:
后端代码(jdk17)
pom.xml
启动类
controller包下
CharController
ChatHistoryController
config包下
CommonConfigguration
MvcConfiguration
entity包
MessageVO
repository包
ChatHistoryRepository
InMemoryChatHistoryRepository
配置
部署本地大模型,也可以使用大公司的云大模型,但是需要付费
需要去ollama先下载ollama的安装包,得到如下
前端代码:
可以ai生成一个智能问答的前端vue界面,也可以私信111发送
SpringAI+DeepSeek大模型应用开发
功能:聊天,会话日志,会话记忆,会话历史
对话机器人效果:
后端代码(jdk17)
pom.xml
<?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>3.5.4</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.itheima</groupId><artifactId>heima-ai</artifactId><version>0.0.1-SNAPSHOT</version><name>heima-ai</name><description>heima-ai</description><url/><licenses><license/></licenses><developers><developer/></developers><scm><connection/><developerConnection/><tag/><url/></scm><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><version>1.18.22</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.2.9</version> <!-- 根据你的 Spring 版本调整 --></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>${spring-ai.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
启动类
package com.itheima.ai;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class HeimaAiApplication {public static void main(String[] args) {SpringApplication.run(HeimaAiApplication.class, args);}}
controller包下
CharController
package com.itheima.ai.controller;import com.itheima.ai.repository.ChatHistoryRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;import static org.springframework.ai.chat.memory.ChatMemory.CONVERSATION_ID;@RequiredArgsConstructor
@RestController
@RequestMapping("/ai")
public class CharController {private final ChatClient chatClient;private final ChatHistoryRepository chatHistoryRepository;@RequestMapping(value = "/chat",produces = "text/html;charset=utf-8")public Flux<String> chat(String prompt,String chatId) {
// 保存会话chatHistoryRepository.save("chat", chatId);
// 请求模型return chatClient.prompt().user(prompt).advisors(a -> a.param(CONVERSATION_ID, chatId)).stream().content();}
}
ChatHistoryController
package com.itheima.ai.controller;import com.itheima.ai.entity.vo.MessageVO;
import com.itheima.ai.repository.ChatHistoryRepository;
import lombok.RequiredArgsConstructor;import org.springframework.ai.chat.memory.ChatMemory;
//import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.Message;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;@RequiredArgsConstructor
@RestController
@RequestMapping("/ai/history")
public class ChatHistoryController {private final ChatHistoryRepository chatHistoryRepository;private final ChatMemory chatMemory;@GetMapping("/{type}")public List<String> getChatIds(@PathVariable("type") String type) {return chatHistoryRepository.getChatIds(type);}@GetMapping("/{type}/{chatId}")public List<MessageVO> getChatHistory(@PathVariable("type") String type, @PathVariable("chatId") String chatId) {List<Message> messages = chatMemory.get(chatId);if(messages == null) {return List.of();}return messages.stream().map(MessageVO::new).toList();}
}
config包下
CommonConfigguration
package com.itheima.ai.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.InMemoryChatMemoryRepository;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;@Configuration
public class CommonConfigguration {@Autowiredprivate ChatMemory chatMemory;@Beanpublic ChatClient chatClient(OllamaChatModel model) {
// 构造的是返回值类型的Builder构造器return ChatClient.builder(model).defaultSystem("你是一个热心、可爱的智能助手,你的名字叫团团,请以小团团的身份和语气回答问题。").defaultAdvisors(new SimpleLoggerAdvisor(),MessageChatMemoryAdvisor.builder(chatMemory).build()).build();}
}
MvcConfiguration
package com.itheima.ai.config;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class MvcConfiguration implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS").allowedHeaders("*");}
}
entity包
MessageVO
package com.itheima.ai.entity.vo;import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.ai.chat.messages.Message;@NoArgsConstructor
@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;default:role = "";break;}this.content = message.getText();}
}
repository包
ChatHistoryRepository
package com.itheima.ai.repository;import java.util.List;public interface ChatHistoryRepository {/*** 保存会话记录* @param type 业务类型,如:chat、service、pdf* @param chatId 会话ID*/void save(String type, String chatId);/*** 获取会话ID列表* @param type 业务类型,如:chat、service、pdf* @return 会话ID列表*/List<String> getChatIds(String type);
}
InMemoryChatHistoryRepository
package com.itheima.ai.repository;import org.springframework.stereotype.Component;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;@Component
public class InMemoryChatHistoryRepository implements ChatHistoryRepository {private final Map<String, List<String>> chatHistory = new HashMap<>();@Overridepublic void save(String type, String chatId) {/*if (!chatHistory.containsKey(type)) {chatHistory.put(type, new ArrayList<>());}List<String> chatIds = chatHistory.get(type);*/List<String> chatIds = chatHistory.computeIfAbsent(type, k -> new ArrayList<>());if (chatIds.contains(chatId)) {return;}chatIds.add(chatId);}@Overridepublic List<String> getChatIds(String type) {/*List<String> chatIds = chatHistory.get(type);return chatIds == null ? List.of() : chatIds;*/return chatHistory.getOrDefault(type, List.of());}
}
配置
部署本地大模型,也可以使用大公司的云大模型,但是需要付费
需要去ollama先下载ollama的安装包,得到如下
如果不想默认安装在C盘就不要双击这个安装包