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

化肥厂的网站摸板如何制作企业网站

化肥厂的网站摸板,如何制作企业网站,东莞网站建设+旅游,google建网站持久化对话 默认情况下,聊天记忆存储在内存中ChatMemory chatMemory new InMemoryChatMemory()。 如果需要持久化存储,可以实现一个自定义的聊天记忆存储类,以便将聊天消息存储在你选择的任何持久化存储介质中。 MongoDB 文档型数据库&…

持久化对话

默认情况下,聊天记忆存储在内存中ChatMemory chatMemory = new InMemoryChatMemory()

如果需要持久化存储,可以实现一个自定义的聊天记忆存储类,以便将聊天消息存储在你选择的任何持久化存储介质中。

MongoDB

文档型数据库,数据以JSON - like的文档形式存储,具有高度的灵活性和可扩展性。它不需要预先定义严格的表结构,适合存储半结构化或非结构化的数据。

当聊天记忆中包含多样化的信息,如文本消息、图片、语音等多媒体数据,或者消息格式可能会频繁变化时,MongoDB 能很好地适应这种灵活性。例如,一些社交应用中用户可能会发送各种格式的消息,使用 MongoDB 可以方便地存储和管理这些不同类型的数据。

整合SpringBoot

引入MongoDB依赖:

<!-- Spring Boot Starter Data MongoDB -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

添加远程连接配置:

#MongoDB连接配置
spring:data:mongodb:uri: mongodb://localhost:27017/chat_memory_dbusername: rootpassword: xxx
实体类

映射MongoDB中的文档(相当与MySQL的表)

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;@Data
@AllArgsConstructor
@NoArgsConstructor
@Document("chatMessages")
public class ChatMessages {//唯一标识,映射到 MongoDB 文档的 _id 字段@Idprivate ObjectId id;private String conversationId;  //会话IDprivate String messagesJson;  //消息JSON}
消息序列化器

对聊天消息message进行 序列化 和 反序列化 操作

消息序列化(messagesToJson 方法):

将一组 Message 对象(如 UserMessage、AssistantMessage)转换为 JSON 字符串。

用于将内存中的聊天记录保存到存储介质(如数据库、文件)或通过网络传输。

消息反序列化(messagesFromJson 方法):

将 JSON 字符串还原为 Message 对象列表。
用于从持久化存储或网络接收的数据中恢复聊天消息对象。

支持多态反序列化(MessageDeserializer 类)

根据 JSON 中的 messageType 字段判断消息类型(如 “USER” 或 “ASSISTANT”),并创建对应的子类实例。

解决了 Jackson 默认无法识别接口或抽象类具体实现的问题。

格式美化(可选)

启用了 SerializationFeature.INDENT_OUTPUT,使输出的 JSON 更具可读性(适合调试和日志输出)。

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;import java.io.IOException;
import java.util.List;
import java.util.Map;
//聊天消息序列化器
public class MessageSerializer {private static final ObjectMapper objectMapper = new ObjectMapper();static {objectMapper.enable(SerializationFeature.INDENT_OUTPUT);SimpleModule module = new SimpleModule();module.addDeserializer(Message.class, new MessageDeserializer());objectMapper.registerModule(module);}public static String messagesToJson(List<Message> messages) throws JsonProcessingException {return objectMapper.writeValueAsString(messages);}public static List<Message> messagesFromJson(String json) throws JsonProcessingException {return objectMapper.readValue(json, new TypeReference<List<Message>>() {});}private static class MessageDeserializer extends JsonDeserializer<Message> {@Overridepublic Message deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {Map<String, Object> node = p.readValueAs(Map.class);String type = (String) node.get("messageType");switch (type) {case "USER":return new UserMessage((String) node.get("text"));case "ASSISTANT":return new AssistantMessage((String) node.get("text"));default:throw new IOException("未知消息类型: " + type);}}}
}
持久化类
@Component
@RequiredArgsConstructor
public class MongoChatMemory implements ChatMemory {@Resourceprivate MongoTemplate mongoTemplate;@Overridepublic void add(String conversationId, List<Message> messages) {Query query = new Query(Criteria.where("conversationId").is(conversationId));ChatMessages chatMessages = mongoTemplate.findOne(query, ChatMessages.class);List<Message> updatedMessages;if (chatMessages != null) {try {updatedMessages = new java.util.ArrayList<>(chatMessages.getMessagesJson() != null? MessageSerializer.messagesFromJson(chatMessages.getMessagesJson()) : Collections.emptyList());} catch (JsonProcessingException e) {throw new RuntimeException("序列化消息失败", e);}updatedMessages.addAll(messages);} else {updatedMessages = new java.util.ArrayList<>(messages);}try {String json = MessageSerializer.messagesToJson(updatedMessages);if (chatMessages != null) {Update update = new Update().set("messagesJson", json);mongoTemplate.updateFirst(query, update, ChatMessages.class);} else {ChatMessages newChatMessages = new ChatMessages();newChatMessages.setConversationId(conversationId);newChatMessages.setMessagesJson(json);mongoTemplate.insert(newChatMessages);}} catch (JsonProcessingException e) {throw new RuntimeException("序列化消息失败", e);}}@Overridepublic List<Message> get(String conversationId, int lastN) {Query query = new Query(Criteria.where("conversationId").is(conversationId));ChatMessages chatMessages = mongoTemplate.findOne(query, ChatMessages.class);if (chatMessages == null || chatMessages.getMessagesJson() == null) {return Collections.emptyList();}try {List<Message> allMessages = MessageSerializer.messagesFromJson(chatMessages.getMessagesJson());int size = allMessages.size();int fromIndex = Math.max(0, size - lastN);return allMessages.subList(fromIndex, size);} catch (JsonProcessingException e) {throw new RuntimeException("反序列化消息失败", e);}}@Overridepublic void clear(String conversationId) {Query query = new Query(Criteria.where("conversationId").is(conversationId));mongoTemplate.remove(query, ChatMessages.class);}
}
测试

初始化ChatClient时,注入MongoChatMemory

//健康报告对话
@Component
@Slf4j
public class HealthReportApp {private final ChatClient chatClient1;private static final String SYSTEM_PROMPT = "你的名字是“小鹿”,你是一家名为“北京协和医院”的智能客服。你是一个训练有素的医疗顾问和医疗伴诊助手。你态度友好、礼貌且言辞简洁。\n" +"1、请仅在用户发起第一次会话时,和用户打个招呼,并介绍你是谁。\n" ;//初始化ChatClientpublic HealthReportApp(ChatModel dashscopeChatModel,MongoChatMemory mongoChatMemory) throws IOException {chatClient1 = ChatClient.builder(dashscopeChatModel).defaultSystem(SYSTEM_PROMPT)  //系统预设.defaultAdvisors(new MessageChatMemoryAdvisor(mongoChatMemory), //对话记忆//自定义日志  Advisor,可按需开启new MyLoggerAdvisor(),// 自定义违禁词 Advisor,可按需开启new ProhibitedWordAdvisor()//自定义推理增强,可按需开启//new ReReadingAdvisor()).build();}public record HealthReport(String title, List<String> suggestions) { }//生成健康报告对话public HealthReport doChatWithReport(String message, String chatId) {HealthReport healthReport = chatClient1.prompt().system(SYSTEM_PROMPT + "分析用户提供的信息,每次对话后都要生成健康报告,标题为{用户名}的健康报告,内容为建议列表").user(message).advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId).param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10)).call().entity(HealthReport.class);log.info("healthReport: {}", healthReport);return  healthReport;}}       

mongodb记录如下

[ {"messageType" : "USER","metadata" : {"messageType" : "USER"},"media" : [ ],"text" : "你好,我是程序员kk"
}, {"messageType" : "ASSISTANT","metadata" : {"messageType" : "ASSISTANT"},"toolCalls" : [ ],"media" : [ ],"text" : "{\n  \"suggestions\": [\n    \"您好,程序员kk,我是北京协和医院的智能客服小鹿,很高兴为您服务。\",\n    \"长期从事编程工作可能导致久坐,建议您定时起身活动,保持良好姿势。\",\n    \"注意用眼卫生,每工作40-50分钟休息一下眼睛。\",\n    \"合理安排作息时间,保证充足睡眠以维持身体和心理健康。\"\n  ],\n  \"title\": \"程序员kk的健康报告\"\n}"
}, {"messageType" : "USER","metadata" : {"messageType" : "USER"},"media" : [ ],"text" : "你是谁"
}, {"messageType" : "ASSISTANT","metadata" : {"finishReason" : "STOP","id" : "0110f881-f29f-9cef-b142-7a7cf9e3e76c","role" : "ASSISTANT","messageType" : "ASSISTANT","reasoningContent" : ""},"toolCalls" : [ ],"media" : [ ],"text" : "{\n  \"suggestions\": [\n    \"您好,我是北京协和医院的智能客服小鹿,很高兴为您服务。\",\n    \"作为您的医疗顾问和伴诊助手,我将为您提供专业建议。\",\n    \"请告诉我您的需求或问题,我会尽力帮助您。\"\n  ],\n  \"title\": \"程序员kk的健康报告\"\n}"
} ]

接口开发

为了在Controller层实现AI对话历史记录的功能,将添加两个接口:根据chatId查询特定对话历史记录和查询所有对话的摘要列表。

//获取所有conversationId
public List<String> findAllConversationIds(String userId) {if (userId == null || userId.isEmpty()) {return Collections.emptyList(); // 或抛出异常}// 构建正则表达式:以 userId + "_" 开头Pattern pattern = Pattern.compile("^" + Pattern.quote(userId) + "_");// 使用 regex 替代 matchesQuery query = new Query(Criteria.where("conversationId").regex(pattern));return mongoTemplate.findDistinct(query,"conversationId",ChatMessages.class,String.class);
}
/*** 根据 chatId 获取历史聊天记录* 支持参数 lastN 控制获取最近 N 条消息(默认获取全部)*/@GetMapping("/history/{chatId}")public BaseResponse<List<Message>> getChatHistory(@PathVariable String chatId,@RequestParam(defaultValue = "-1") int lastN) {int effectiveLastN = lastN <= 0 ? Integer.MAX_VALUE : lastN;List<Message> history = chatMemory.get(chatId, effectiveLastN);return ResultUtils.success(history);}/*** 获取所有 chatId 列表(用于展示对话历史页面)*/@GetMapping("/conversations")public BaseResponse<List<String>> getAllConversations() {Long currentUserId= BaseContext.getCurrentId();String userId = currentUserId.toString();List<String> conversationIds =  chatMemory.findAllConversationIds(userId);return ResultUtils.success(conversationIds);}/*** 新建对话:生成新的 chatId,并在 MongoDB 中插入一条空记录*/@PostMapping("/conversations/add")public BaseResponse<String> createNewConversation() {Long currentUserId= BaseContext.getCurrentId();String conversationId = currentUserId + "_" + UUID.randomUUID().toString();chatMemory.add(conversationId, Collections.emptyList()); // 插入空消息记录return ResultUtils.success(conversationId);}/*** 删除指定 chatId 的对话记录*/@DeleteMapping("/conversations/{chatId}")public BaseResponse<Boolean> deleteConversation(@PathVariable String chatId) {chatMemory.clear(chatId);return ResultUtils.success(true);}
http://www.dtcms.com/wzjs/121037.html

相关文章:

  • 网站建设维护线下推广团队
  • 佛山市企业网站建设哪家好seo专员工作内容
  • 做公益活动的网站阿里云com域名注册
  • wordpress站群功能快速排名服务平台
  • 怎么用html做网站长沙服务好的网络营销
  • 为什么要做网站百度推广客服电话
  • 韶关做网站公司营销活动怎么做吸引人
  • 如何破解网站后台百度云搜索
  • 成都知名网站建设网站建设公司哪家好?
  • 网站查询系统怎么做关键词排名点击软件首页
  • 非商业组织的网站风格白杨seo教程
  • 企业网站用wordpressseo图片优化的方法
  • 上海论坛网站建设宣传平台有哪些
  • 长春火车站出站要求建网站公司
  • 初中学校网站如何做色盲测试图片
  • 做网站如何避免商标侵权搜索app下载安装
  • 海南seo外包碉堡了seo博客
  • wordpress小程序不能评论seo优化网
  • 网络建站工具旅游网络营销的渠道有哪些
  • 建站市场网络营销课程个人感悟
  • 国外皇色网站深圳媒体网络推广有哪些
  • 服务好的武进网站建设东莞百度seo电话
  • 类似pc蛋蛋的网站建设北京已感染上千万人
  • 国外婚纱网站建设现状企业网页设计报价
  • 网站之间的差异武汉seo公司
  • 深圳返利网站开发百度搜索指数在线查询
  • 建材 团购 网站怎么做seo是什么意思中文
  • 三站合一网站建设方案深圳推广服务
  • 厦门酒店团购网站建设如何开发软件app
  • 深圳网站开发怎么样扬州seo优化