Spring AI中使用ChatMemory實現會話記憶功能

文章目錄

  • 1、需求
  • 2、ChatMemory中消息的存儲位置
  • 3、實現步驟
    • 1、引入依賴
    • 2、配置Spring AI
    • 3、配置chatmemory
    • 4、java層傳遞conversaionId
  • 4、驗證
  • 5、完整代碼
  • 6、參考文檔

1、需求

我們知道大型語言模型 (LLM) 是無狀態的,這就意味著他們不會保存之前的交互信息。當我們希望在一次會話中,模型支持多次交互,那么我們該如何實現呢? 在 Spring AI中提供了ChatMemory功能,它允許我們在與LLM的多次交互中存儲與檢索信息。此處我們借助Spring AI的ChatMemory功能實現一個簡單的多輪對話。

    1. 集成ollama部署的本地模型
    1. 使用jdbc存儲聊天歷史信息(保存到mysql中)

2、ChatMemory中消息的存儲位置

ChatMemory中消息的存儲位置
默認情況下是存儲在內存中,但是它也提供了JDBCCassandraNeo4j的實現。

如果我們想自定義實現存儲該如何實現呢? 需要實現ChatMemoryRepository接口。此處我們不自己實現,使用Spring AI 提供的 JDBC存儲實現。

注意:使用Spring AI 提供的JDBC實現需要引入 spring-ai-starter-model-chat-memory-repository-jdbc 包
ChatMemoryRepository

3、實現步驟

1、引入依賴

<properties><spring-ai.version>1.0.0</spring-ai.version><java.version>17</java.version><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target>        <maven.compiler.compilerVersion>17</maven.compiler.compilerVersion>
</properties>
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 集成ollama --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-ollama</artifactId></dependency><!-- 使用jdbc存儲模型的聊天記錄 --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-chat-memory-repository-jdbc</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></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>

2、配置Spring AI

spring:application:name: spring-ai-advisor-chat-memoryai:ollama:base-url: http://localhost:11434 # 配置ollama的地址chat:model: deepseek-r1:14b  # 配置模型的名稱options:temperature: 0.7 # 配置模型溫度chat:memory:repository:jdbc:initialize-schema: always# 配置初始化腳本的位置schema: classpath:org/springframework/ai/chat/memory/repository/jdbc/schema-mariadb.sqlplatform: mariadbdatasource:url: jdbc:mysql://127.0.0.1:3306/temp_work?useUnicode=true&characterEncoding=utf8&autoReconnectForPools=true&useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driverlogging:level:# 用于支持llm模型輸入前和輸入后的日志打印org.springframework.ai.chat.client.advisor: debug

指定腳本的位置

3、配置chatmemory

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.ChatMemoryRepository;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.memory.repository.jdbc.JdbcChatMemoryRepository;
import org.springframework.ai.chat.memory.repository.jdbc.JdbcChatMemoryRepositoryDialect;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;import javax.sql.DataSource;/*** ai 配置* @author huan.fu* @date 2025/6/8 - 08:44*/
@Configuration
public class AiConfiguration {@Beanpublic JdbcChatMemoryRepository jdbcChatMemoryRepository(JdbcTemplate jdbcTemplate, DataSource dataSource) {JdbcChatMemoryRepositoryDialect dialect = JdbcChatMemoryRepositoryDialect.from(dataSource);return JdbcChatMemoryRepository.builder().jdbcTemplate(jdbcTemplate).dialect(dialect).build();}@Beanpublic ChatMemory chatMemory(ChatMemoryRepository jdbcChatMemoryRepository){return MessageWindowChatMemory.builder().chatMemoryRepository(jdbcChatMemoryRepository)// 每個會話最多記錄20條信息.maxMessages(20).build();}@Beanpublic ChatClient chatClient(OllamaChatModel ollamaChatModel, ChatMemory chatMemory){// 配置模型 (因為我們使用的是 ollama, 所以此處寫的是 OllamaChatModel)return ChatClient.builder(ollamaChatModel)// 默認系統提示詞.defaultSystem("你是一個擁有豐富經驗的編程小助手,擅長編寫各種程序。")// 添加模型輸入前和輸入后日志打印.defaultAdvisors(new SimpleLoggerAdvisor(),// 配置 chat memory advisorMessageChatMemoryAdvisor.builder(chatMemory).build()).build();}
}

注入到advisor中

4、java層傳遞conversaionId

java層傳遞conversaionId
java層傳遞conversaionId

4、驗證

依次訪問如下2個http請求

http://localhost:8080/blockChat?prompt=介紹一下你自己&conversationId=123456789
http://localhost:8080/blockChat?prompt=我剛剛問的問題是什么&conversationId=123456789

驗證結果
會話id需保持一致
從上圖中可以,在第二次詢問模型時,模型知道上次的問題是什么。

5、完整代碼

https://gitee.com/huan1993/spring-cloud-parent/tree/master/spring-ai/spring-ai-advisor-chat-memory

6、參考文檔

1、https://docs.spring.io/spring-ai/reference/api/chat-memory.html

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

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

相關文章

Java 高級泛型實戰:8 個場景化編程技巧

文章目錄 一、通配符高級應用&#xff1a;靈活處理類型關系二、泛型方法與類型推斷三、泛型類的嵌套使用四、受限泛型與邊界條件五、泛型與反射結合六、泛型在函數式接口中的應用七、類型擦除與橋接方法八、自定義泛型注解總結 在Java編程中&#xff0c;泛型不僅是類型安全的保…

[藍橋杯 2024 國 B] 立定跳遠

問題描述 在運動會上&#xff0c;小明從數軸的原點開始向正方向立定跳遠。項目設置了 n 個檢查點 a1,a2,...,an且 ai≥ai?1>0。小明必須先后跳躍到每個檢查點上且只能跳躍到檢查點上。同時&#xff0c;小明可以自行再增加 m 個檢查點讓自己跳得更輕松。在運動會前&#xf…

2025年全國I卷數學壓軸題解答

第19題第3問: b b b 使得存在 t t t, 對于任意的 x x x, 5 cos ? x ? cos ? ( 5 x t ) < b 5\cos x-\cos(5xt)<b 5cosx?cos(5xt)<b, 求 b b b 的最小值. 解: b b b 的最小值 b m i n min ? t max ? x g ( x , t ) b_{min}\min_{t} \max_{x} g(x,t) bmi…

wpf在image控件上快速顯示內存圖像

wpf在image控件上快速顯示內存圖像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在尋找能夠快速在image控件刷新大圖像&#xff08;比如分辨率3000*3000的圖像&#xff09;的辦法&#xff0c;尤其是想把內存中的裸數據&#xff08;只有圖像的數據&#xff0c;不包…

解決網頁導出PDF部分內容被遮擋問題

問題描述 以學習通為例&#xff0c;在使用CtrlP打印頁面或截圖時&#xff0c;固定側邊欄會遮擋部分內容&#xff0c;影響完整內容的獲取。如下圖所示&#xff1a; 解決辦法 通過瀏覽器開發者工具臨時移除固定側邊欄&#xff0c;具體步驟如下&#xff1a; 在目標頁面右鍵點…

機器學習監督學習實戰六:五種算法對新聞組英文文檔進行文本分類(20類),詞頻統計和TF-IDF 轉換特征提取方法理論和對比解析

本文主要介紹了20 Newsgroups數據集及其在文本分類任務中的應用。20 Newsgroups數據集包含約20,000篇新聞組文檔&#xff0c;分為20個不同主題的新聞組&#xff0c;數據集被分為訓練集和測試集。在數據預處理階段&#xff0c;使用了CountVectorizer和TfidfVectorizer兩種方法將…

易學探索助手-個人記錄(十四)

項目背景 在大語言模型&#xff08;LLM&#xff09;完成指令微調&#xff08;SFT&#xff09;之后&#xff0c;雖然可以處理開放式問答任務&#xff0c;但在專業領域&#xff08;如《周易》&#xff09;仍面臨知識更新滯后、事實性薄弱等問題。為此&#xff0c;本文介紹如何通…

從“人找政策”到“政策找人”:智能退稅ERP數字化重構外貿生態

離境退稅新政核心內容與外貿企業影響 &#xff08;一&#xff09;政策核心變化解析 退稅商店網絡擴容 新政明確鼓勵在大型商圈、旅游景區、交通樞紐等境外旅客聚集地增設退稅商店&#xff0c;并放寬備案條件至納稅信用M級企業。以上海為例&#xff0c;靜安區計劃新增1000家退…

Pandas 可視化集成:數據科學家的高效繪圖指南

為什么選擇 Pandas 進行數據可視化&#xff1f; 在數據科學和分析領域&#xff0c;可視化是理解數據、發現模式和傳達見解的關鍵步驟。Python 生態系統提供了多種可視化工具&#xff0c;如 Matplotlib、Seaborn、Plotly 等&#xff0c;但 Pandas 內置的可視化功能因其與數據結…

曼昆《經濟學原理》第九版 第十一章公共物品與公共資源

一、物品分類的基本框架 排他性&#xff1a;能否阻止他人使用該物品的特性競爭性&#xff1a;一個人使用是否減少他人使用的特性 根據這兩個特性可將物品分為四類&#xff1a; 私人物品&#xff1a;既有排他性又有競爭性&#xff08;如冰淇淋、衣服&#xff09;公共物品&…

基于大模型預測原發性急性閉角型青光眼的技術方案研究大綱

目錄 一、引言二、技術方案概述三、術前階段(一)數據采集與處理(二)大模型預測(三)手術方案制定(四)麻醉方案確定(五)術前健康教育四、術中階段(一)實時數據監測與輸入(二)手術策略動態調整(三)并發癥預警與處理(四)術中健康教育五、術后階段(一)恢復監測與…

基于React 的 AntD 庫進行前端開發過程中的問題匯總

背景 最近寫了半個月的 React 前端&#xff0c;三年沒寫過 React 前端了&#xff0c;有些生疏了&#xff0c;匯總一下 基于React 前端的 antD 庫編寫過程中的低級問題吧。 PS 一下&#xff0c;半個月沒有發布博客了&#xff0c;C站產品經理又悄默默地改了樣式&#xff0c;博客…

Spring @Scheduled vs XXL-JOB vs DolphinScheduler vs Airflow:任務調度框架全景對比

引言 從單機定時任務到分布式工作流調度&#xff0c;不同場景需要選擇匹配的調度框架。 本文對比 Spring Scheduled、XXL-JOB、DolphinScheduler &#xff08;海豚調度器&#xff09;和 Apache Airflow 的核心差異&#xff0c;助你避免過度設計或功能不足。 一、核心定位與適用…

springMVC-10驗證及國際化

驗證 概述 ● 概述 1. 對輸入的數據(比如表單數據)&#xff0c;進行必要的驗證&#xff0c;并給出相應的提示信息。 2. 對于驗證表單數據&#xff0c;springMVC提供了很多實用的注解, 這些注解由JSR303 驗證框架提供. ●JSR 303 驗證框架 1. JSR 303 的含義 JSR&#xff0…

OpenCV 滑動條調整圖像對比度和亮度

一、知識點 1、int createTrackbar(const String & trackbarname, const String & winname, int * value, int count, TrackbarCallback onChange 0, void * userdata 0); (1)、創建一個滑動條并將其附在指定窗口上。 (2)、參數說明: trackbarname: 創建的…

ReadWriteLock(讀寫鎖)和 StampedLock

1. ReadWriteLock&#xff08;讀寫鎖&#xff09;&#xff1a;實現高性能緩存 總結&#xff1a; 要點 內容 適用場景 讀多寫少、高并發讀取場景&#xff08;如緩存&#xff09; 鎖類型 ReadWriteLock接口&#xff0c;ReentrantReadWriteLock實現 讀鎖 vs 寫鎖 多線程可…

【決勝公務員考試】求職OMG——見面課測驗1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答題&#xff0c;大家注意呀&#xff01; 博主碼字不易點個關注吧,祝期末順利~~ 1.單選題(2分) 下列說法錯誤的是:&#xff08; B &#xff09; A.選調生屬于公務員系統 B.公務員屬于事業編 C.選調生有基層鍛煉的要求 D…

vue3 el-button 自定義本地圖標

設置不生效的原因可能有&#xff1a;1.style標簽里沒加scoped <style scoped></style>2.本地圖片路徑指向錯誤3.自定義圖片長寬沒設置4.deep深度選擇器使用錯誤&#xff0c;vue3用:deep() <el-tooltip content"重新匹配" placement"top"&g…

如何在最短時間內提升打ctf(web)的水平?

剛剛刷完2遍 bugku 的 web 題&#xff0c;前來答題。 每個人對刷題理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟著writeup做了一遍就等于刷了&#xff0c;還有的人是獨立思考做了一遍就等于刷了。…

6.8 note

paxos算法_初步感知 Paxos算法保證一致性主要通過以下幾個關鍵步驟和機制&#xff1a; 準備階段 - 提議者向所有接受者發送準備請求&#xff0c;請求中包含一個唯一的編號。 - 接受者收到請求后&#xff0c;會檢查編號&#xff0c;如果編號比它之前見過的都大&#xff0c;就會承…