Azure部署Spring Boot聊天机器人:Redis实现短期记忆求助
解决方案
1. 引入Redis依赖
在项目的pom.xml中添加Spring Data Redis依赖,用于操作Redis:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
2. 配置Azure Redis连接
在application.properties中配置Azure Redis的连接信息:
# Azure Redis连接配置 spring.redis.host=你的Azure Redis主机地址 spring.redis.port=6380 spring.redis.password=你的Redis访问密钥 spring.redis.ssl=true
3. 序列化会话实体
确保ConversationRecord类支持序列化,Spring Data Redis才能将其存入Redis:
import java.io.Serializable; public class ConversationRecord implements Serializable { private String userQuery; private String chatResponse; public ConversationRecord(String userQuery, String chatResponse) { this.userQuery = userQuery; this.chatResponse = chatResponse; } // getter、setter方法 public String getUserQuery() { return userQuery; } public void setUserQuery(String userQuery) { this.userQuery = userQuery; } public String getChatResponse() { return chatResponse; } public void setChatResponse(String chatResponse) { this.chatResponse = chatResponse; } }
4. 改造会话服务
替换原内存ArrayList,用Redis存储会话记录,每个会话用唯一ID(如HttpSession ID)作为key:
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; @Service public class ConversationService { private final RedisTemplate<String, ConversationRecord> redisTemplate; private static final int MAX_RECORD_COUNT = 10; public ConversationService(RedisTemplate<String, ConversationRecord> redisTemplate) { this.redisTemplate = redisTemplate; } // 获取指定会话的历史记录 public List<ConversationRecord> getConversationRecords(String sessionId) { List<ConversationRecord> records = redisTemplate.opsForList().range(sessionId, 0, -1); return records != null ? records : new ArrayList<>(); } // 保存新的会话记录,超过10条时移除最早的一条 public void saveConversationRecord(String sessionId, ConversationRecord record) { List<ConversationRecord> records = getConversationRecords(sessionId); if (records.size() >= MAX_RECORD_COUNT) { redisTemplate.opsForList().leftPop(sessionId); } redisTemplate.opsForList().rightPush(sessionId, record); } }
5. 改造ChatController
通过会话ID从Redis读取历史记录,构造OpenAI请求消息,调用API后保存新记录:
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpSession; import java.util.ArrayList; import java.util.List; @RestController public class ChatController { private final ConversationService conversationService; private final OpenAiClient openAiClient; // 你的OpenAI客户端类 public ChatController(ConversationService conversationService, OpenAiClient openAiClient) { this.conversationService = conversationService; this.openAiClient = openAiClient; } @PostMapping("/chat") public String chat(@RequestParam List<String> messages, HttpSession session) { String sessionId = session.getId(); List<ConversationRecord> historyRecords = conversationService.getConversationRecords(sessionId); List<Message> messageList = new ArrayList<>(); // 拼接历史会话 for (ConversationRecord record : historyRecords) { messageList.add(new Message("user", record.getUserQuery())); messageList.add(new Message("assistant", record.getChatResponse())); } // 添加系统提示词 messageList.add(new Message("system", "You are a helpful assistant!")); // 添加当前用户输入 messages.forEach(msg -> messageList.add(new Message("user", msg))); // 调用OpenAI API获取回复 String response = openAiClient.callChatCompletions(messageList); // 保存新会话记录 String latestUserQuery = messages.get(messages.size() - 1); conversationService.saveConversationRecord(sessionId, new ConversationRecord(latestUserQuery, response)); return response; } }
6. 调整ProductsController
确保调用chat方法时传递会话上下文:
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpSession; import java.util.List; @RestController public class ProductsController { private final ChatController chatController; public ProductsController(ChatController chatController) { this.chatController = chatController; } @PostMapping("/Products") public String handleProductRequest(@RequestBody UserInput input, HttpSession session) { // 生成产品列表的业务逻辑 List<String> productList = generateProductList(input.getUserQuery()); // 调用chat接口并传递会话 String response = chatController.chat(productList, session); System.out.println("Response: \n" + response); return response; } private List<String> generateProductList(String userQuery) { // 替换为你的实际产品生成逻辑 return List.of("产品A", "产品B"); } // 接收用户输入的实体类 static class UserInput { private String userQuery; public String getUserQuery() { return userQuery; } public void setUserQuery(String userQuery) { this.userQuery = userQuery; } } }
关键注意点
- 会话标识:Web场景用
HttpSession.getId()作为会话key,前后端分离场景可让前端传递自定义UUID,确保跨请求会话一致。 - Redis数据结构:用List存储会话记录,
leftPop移除最早记录,rightPush添加新记录,符合上下文的时序要求。 - 序列化配置:若需要Redis存储的内容为可读JSON,可自定义
RedisTemplate配置Jackson序列化器。
内容的提问来源于stack exchange,提问作者githycody
相关产品推荐
相关产品推荐

