【Spring AI】模型記憶持久化 + 自動加載記憶上下文

當我們利用大模型進行開發時,有時會因為項目重啟而丟失模型的記憶,會給開發的過程帶來不方便

接下來我將介紹如何將模型的記憶持久化,并保證在項目重啟后依然能能夠正常加載記憶上下文。

我們在配置ChatClient時,由于想要實現模型的記憶,便需要管理會話信息,而Spring AI給我們提供了Advisors的自動管理機制,其有兩種實現方式,即內存記憶和緩存記憶,但是其根源都是建立在緩存中,主機重啟都會數據丟失。

在模型會話記憶ChatMemory的底層是通過創建不同類型的Message存儲會話,所以我們可以利用這個機制,在每次模型響應后,將模型的響應和用戶的請求信息分別手動創建不同類型的Message進行存儲,而存儲則可以選擇數據庫。

但是首先要給ChatClient配置記憶容器

this.chatClient = chatClient.defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory)).build();

我將分別來講記憶的持久化以及記憶的讀取

模型記憶持久化

以下是ChatClient的捕獲響應方式

public Flux<String> chat(@RequestBody GetRequest request) {//用戶消息String userMessage = request.getMessage();//保存會話idchatHistoryService.save("chat",request.getChatId(),request.getSid());//構建提示詞,用戶提示詞,調用模型,取出響應//流式響應// 創建響應收集器,不斷加載響應內容,用于在中斷時保存已生成內容StringBuilder assistantResponse = new StringBuilder();System.out.println("調用"+modelName+"模型進行響應");Flux<String> response = chatClient.prompt().system(System_Prompt) // 設置系統提示詞.user(userMessage)   // 設置用戶提示詞.advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY,request.getChatId()))  //  設置會話ID.stream()        //流式響應.content()  //獲取響應內容.doOnNext(assistantResponse::append) // 追加到響應收集器中
//                .doOnSubscribe(sub -> activeSubscriptions.put(request.getChatId(), sub)) // 直接存儲Subscription.doFinally(Message->{//將響應信息存儲到數據庫String type = "assistant"; //將用戶信息保存到數據庫saveChatHistory(request.getChatId(),"user", userMessage);//將響應信息存儲到數據庫saveChatHistory(request.getChatId(),type, assistantResponse.toString());});return response;}

可以看到在相應開始前首先創建一個builder容器用于不斷追加模型的響應,在ChatClient的dofinally中調用方法分別存儲用戶和模型信息。

以下是存儲方法

可以看到方法參數為會話ID,類型和內容,其中類型是user或者assistant,這是底層源碼所定義的,我們需要保持一致以便模型能夠正確讀取

//將會話信息存儲到數據庫public void saveChatHistory(String chatId, String type,  String content) {ChatDetail chatDetail = new ChatDetail();chatDetail.setChatId(chatId);chatDetail.setMessageType(type);chatDetail.setContent(content);chatDetailMapper.insert(chatDetail);}

這里注意需要提前定義數據庫表,有類型字段和內容字段

最終存儲的效果:

?加載模型記憶

已經將對話數據持久化,那么在進行項目重啟后為了不丟失原有記憶,我們需要想辦法吧數據庫中存儲的內容加載到模型的記憶中

前面已經說到記憶的存儲在底層時Message類型,而其有不同的實現類,其中UserMessage和AssistantMessage是我們所需要的只要根據從數據庫中消息類型的不同分別創建不同的Message并將其存儲到ChatMemory中即可。

以下是具體流程:

當用戶訪問某個會話時,先將其余會話的記憶清除,再根據會話id從數據庫取得對應記憶,并遍歷存入模型記憶上下文

List<ChatDetail> chatDetails = chatDetailMapper.selectList(new LambdaQueryWrapper<ChatDetail>().eq(ChatDetail::getChatId, chatId));//將當前會話的信息保存到模型記憶上下文//清除其他會話記憶chatHistoryService.getChatIds(type).forEach(chat->chatMemory.clear(chat.getChatId()));activeSubscriptions.clear(); // 同時清理訂閱關系//加入當前會話記憶if (!chatDetails.isEmpty()) {chatDetails.forEach(c -> {if (c.getMessageType().equals("user")) {chatMemory.add(chatId, new UserMessage(c.getContent()));     //用戶信息} else if (c.getMessageType().equals("assistant")) {chatMemory.add(chatId, new AssistantMessage(c.getContent())); //模型回復信息}});System.err.println("當前模型記憶為:"+chatMemory.get(chatId,  Integer.MAX_VALUE));

這樣一來便實現了模型記憶的持久化功能,并在多個會話的情況下保證內存的容量問題。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/81033.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/81033.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/81033.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

(C語言)超市管理系統 (正式版)(指針)(數據結構)(清屏操作)(文件讀寫)

目錄 前言&#xff1a; 源代碼&#xff1a; product.h product.c fileio.h fileio.c main.c 代碼解析&#xff1a; 一、程序結構概述 二、product.c 函數詳解 1. 初始化商品列表 Init_products 2. 添加商品 add_product 3. 顯示商品 display_products 4. 修改商品 mo…

[服務器面板對比] 寶塔、aaPanel、Plesk、cPanel 哪家強?功能、性能與價格橫評 (2025)

對于很多 Linux 服務器用戶來說&#xff0c;直接面對黑乎乎的命令行界面 (CLI) 進行各種操作&#xff0c;雖然強大靈活&#xff0c;但也確實有一定的學習門檻和操作復雜度。特別是當你需要管理多個網站、數據庫、FTP賬戶&#xff0c;或者進行日常的軟件安裝、安全配置、日志查看…

WebGL圖形編程實戰【7】:變換流水線 × 坐標系與矩陣精講

變換流水線 #mermaid-svg-Omabd9LSNCdIvWqB {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Omabd9LSNCdIvWqB .error-icon{fill:#552222;}#mermaid-svg-Omabd9LSNCdIvWqB .error-text{fill:#552222;stroke:#552222;…

電力電容器故障利用沃倫森(WARENSEN)工業設備智能運維系統解決方案

行業工況背景 當配電室報警顯示“電容器故障”時&#xff0c;管理者可能會感到焦慮。沃倫森&#xff08;WARENSEN&#xff09;憑借十多年的電力補償設備服務經驗&#xff0c;提供了科學的故障應對流程&#xff0c;幫助避免大部分二次損失。 一、五大常見故障現象快速識別 溫度…

星海智算云平臺部署GPT-SoVITS模型教程

背景 隨著 GPT-SoVITS 在 AI 語音合成領域的廣泛應用&#xff0c;越來越多的個人和團隊開始關注這項前沿技術。你是否也在思考&#xff0c;如何快速、高效地部署并體驗這款強大的聲音克隆模型&#xff1f;遺憾的是&#xff0c;許多本地部署方案不僅配置復雜&#xff0c;而且對…

高吞吐與低延遲的博弈:Kafka與RabbitMQ數據管道實戰指南

摘要 本文全面對比Apache Kafka與RabbitMQ在數據管道中的設計哲學、核心差異及協同方案。結合性能指標、應用場景和企業級實戰案例,揭示Kafka在高吞吐流式處理中的優勢與RabbitMQ在復雜路由和低延遲傳輸方面的獨特特點;介紹了使用Java生態成熟第三方庫(如Apache Kafka Clie…

Python零基礎入門到高手8.4節: 元組與列表的區別

目錄 8.4.1 不可變數據類型 8.4.2 可變數據類型 8.4.3 元組與列表的區別 8.4.4 今天彩票沒中獎 8.4.1 不可變數據類型 不可變數據類型是指不可以對該數據類型進行原地修改&#xff0c;即只讀的數據類型。迄今為止學過的不可變數據類型有字符串&#xff0c;元組。 在使用[]…

無人機數據處理與特征提取技術分析!

一、運行邏輯 1. 數據采集與預處理 多傳感器融合&#xff1a;集成攝像頭、LiDAR、IMU、GPS等傳感器&#xff0c;通過硬件時間戳或PPS信號實現數據同步&#xff0c;確保時空一致性。 邊緣預處理&#xff1a;在無人機端進行數據壓縮&#xff08;如JPEG、H.265&#xff09;…

LeetCode 熱題 100 105. 從前序與中序遍歷序列構造二叉樹

LeetCode 熱題 100 | 105. 從前序與中序遍歷序列構造二叉樹 大家好&#xff0c;今天我們來解決一道經典的二叉樹問題——從前序與中序遍歷序列構造二叉樹。這道題在 LeetCode 上被標記為中等難度&#xff0c;要求根據給定的前序遍歷和中序遍歷序列&#xff0c;構造并返回二叉樹…

CSS- 1.1 css選擇器

本系列可作為前端學習系列的筆記&#xff0c;代碼的運行環境是在HBuilder中&#xff0c;小編會將代碼復制下來&#xff0c;大家復制下來就可以練習了&#xff0c;方便大家學習。 HTML系列文章 已經收錄在前端專欄&#xff0c;有需要的寶寶們可以點擊前端專欄查看&#xff01; 系…

MongoClient和AsyncIOMotorClient的區別和用法

示例代碼&#xff1a; from motor.motor_asyncio import AsyncIOMotorClient from pymongo import MongoClient&#x1f50d; 這兩個庫分別是&#xff1a; 名字說明舉個例子pymongo.MongoClient同步版 的 MongoDB 客戶端&#xff08;常規阻塞式操作&#xff09;你在主線程里一…

5.15打卡

浙大疏錦行 DAY 26 函數專題1 知識點回顧&#xff1a; 1. 函數的定義 2. 變量作用域&#xff1a;局部變量和全局變量 3. 函數的參數類型&#xff1a;位置參數、默認參數、不定參數 4. 傳遞參數的手段&#xff1a;關鍵詞參數 5. 傳遞參數的順序&#xff1a;同時出現三種參數…

針對面試-mysql篇

1.如何定位慢查詢? 1.1.介紹一下當時產生問題的場景(我們當時的接口測試的時候非常的慢&#xff0c;壓測的結果大概5秒鐘))&#xff0c;可以監測出哪個接口&#xff0c;最終因為是sql的問題 1.2.我們系統中當時采用了運維工具(Skywalking就是2秒&#xff0c;一旦sql執行超過2秒…

window 顯示驅動開發-報告圖形內存(三)

圖形內存報告示例 示例 1&#xff1a;筆記本電腦上的 128 MB 專用板載圖形內存 以下屏幕截圖顯示了使用 Intel Iris 離散圖形適配器運行 Windows 11 的 Surface 筆記本電腦的計算圖形內存數。 適配器的可用內存總數為 16424 MB&#xff0c;用于圖形用途&#xff0c;細分如下&…

極簡主義現代商務風格PPT模版6套一組分享下載

現代商務風格PPT模版下載https://pan.quark.cn/s/12fbc52124d9 第一張PPT模版&#xff0c;簡約風&#xff0c;橄欖綠背景&#xff0c;黑色豎條裝飾&#xff0c;文字有中英文標題和占位符。需要提取關鍵元素&#xff1a;簡約、橄欖綠、對稱布局、占位文本的位置。 風格?&#…

SpringBoot中10種動態修改配置的方法

在SpringBoot應用中&#xff0c;配置信息通常通過application.properties或application.yml文件靜態定義&#xff0c;應用啟動后這些配置就固定下來了。 但我們常常需要在不重啟應用的情況下動態修改配置&#xff0c;以實現灰度發布、A/B測試、動態調整線程池參數、切換功能開…

嵌入式自學第二十二天(5.15)

順序表和鏈表 優缺點 存儲方式&#xff1a; 順序表是一段連續的存儲單元 鏈表是邏輯結構連續物理結構&#xff08;在內存中的表現形式&#xff09;不連續 時間性能&#xff0c; 查找順序表O(1)&#xff1a;下標直接查找 鏈表 O(n)&#xff1a;從頭指針往后遍歷才能找到 插入和…

高并發內存池(三):TLS無鎖訪問以及Central Cache結構設計

目錄 前言&#xff1a; 一&#xff0c;thread cache線程局部存儲的實現 問題引入 概念說明 基本使用 thread cache TLS的實現 二&#xff0c;Central Cache整體的結構框架 大致結構 span結構 span結構的實現 三&#xff0c;Central Cache大致結構的實現 單例模式 thr…

Ubuntu 安裝 Docker(鏡像加速)完整教程

Docker 是一款開源的應用容器引擎&#xff0c;允許開發者打包應用及其依賴包到一個輕量級、可移植的容器中。本文將介紹在 Ubuntu 系統上安裝 Docker 的步驟。 1. 更新軟件源 首先&#xff0c;更新 Ubuntu 系統的軟件源&#xff1a; sudo apt update2. 安裝基本軟件 接下來…

【深度學習】數據集的劃分比例到底是選擇811還是712?

1 引入 在機器學習中&#xff0c;將數據集劃分為訓練集&#xff08;Training Set&#xff09;、驗證集&#xff08;Validation Set&#xff09;和測試集&#xff08;Test Set&#xff09;是非常標準的步驟。這三個集合各有其用途&#xff1a; 訓練集 (Training Set)&#xff…