Spring Ai 1.0.1中存在的問題:使用MessageChatMemoryAdvisor導致System未被正確的放在首位

使用MessageChatMemoryAdvisor導致System未被正確的放在首位

如下是使用Spring Ai實現多輪對話的官方例子(文檔地址:https://docs.spring.io/spring-ai/reference/api/chat-memory.html):

 @AutowiredChatMemoryRepository chatMemoryRepository;  //注入對話記憶@GetMapping("/chatMemory")@Operation(summary = "帶記憶的同步調用")String chatMemory(String userInput) {// 1. 構建對話記憶存儲配置// 使用MessageWindowChatMemory實現窗口記憶策略ChatMemory chatMemory = MessageWindowChatMemory.builder().chatMemoryRepository(chatMemoryRepository) // 底層記憶存儲倉庫(測試使用內存實現).maxMessages(20)    // 設置歷史消息最大保留輪次(滑動窗口大小).build();// 2. 生成唯一會話ID(實際項目中由)String conversationId = "123456789"; // 示例固定值,生產環境需動態生成// 3. 構建對話請求并配置各組件return this.chatClient.prompt()// 3.1 設置對話角色.system(system)  // 系統角色設定(AI人設/指令)// 3.2 設置基礎參數.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, conversationId) // 綁定當前對話ID到請求上下文)// 3.3 添加增強功能(Advisors).advisors(new SimpleLoggerAdvisor(),  // 啟用請求日志記錄(用于調試)MessageChatMemoryAdvisor.builder(chatMemory).build(),   // 啟用記憶管理功能)// 3.4 設置當前用戶輸入.user(userInput)// 3.5 執行調用.call() // 發送同步請求到對話服務// 3.6 處理響應.content(); // 提取響應中的文本內容}

如上示例是根據官方文檔寫的,實際測下來是有問題的,例如:有的模型在二輪對話的時候返回順序問題報錯,有的模型在二輪對話的時候丟失人設。(這個和模型的兼容性有關系)

經過排查可以發現二輪對話的Message中內容順序會有問題(System人設被放到了倒數第二句):

[{"role": "user","content": "您好"},{"role": "assistant","content": "\n\n您好!很高興為您提供服務。請問有什么可以幫助您的嗎?"},{"role": "system","content": "你是智能助理小明"},{"role": "user","content": "你叫什么名字啊"}
]

已上述的格式請求大模型會出現各種問題,因為正常規定的順序就是S- U- A-U。
在GitHub中有大佬給出臨時解決辦法,創建一個SystemFirstSortingAdvisor來確保System人設始終保持第一位:(GitHub原問題地址:https://github.com/spring-projects/spring-ai/issues/4170)

/*** 保證SYSTEM在最前面的增強*/
public class SystemFirstSortingAdvisor implements BaseAdvisor {@Overridepublic ChatClientRequest before(ChatClientRequest chatClientRequest, AdvisorChain advisorChain) {List<Message> processedMessages = chatClientRequest.prompt().getInstructions();processedMessages.sort(Comparator.comparing(m -> m.getMessageType() == MessageType.SYSTEM ? 0 : 1));return chatClientRequest.mutate().prompt(chatClientRequest.prompt().mutate().messages(processedMessages).build()).build();}@Overridepublic ChatClientResponse after(ChatClientResponse chatClientResponse, AdvisorChain advisorChain) {return chatClientResponse; // no-op}@Overridepublic int getOrder() {return 0; // larger than MessageChatMemoryAdvisor so it runs afterwards}
}

最后正確調用(在advisors中加入SystemFirstSortingAdvisor):

 @AutowiredChatMemoryRepository chatMemoryRepository;  //注入對話記憶@GetMapping("/chatMemory")@Operation(summary = "帶記憶的同步調用")String chatMemory(String userInput) {// 1. 構建對話記憶存儲配置// 使用MessageWindowChatMemory實現窗口記憶策略ChatMemory chatMemory = MessageWindowChatMemory.builder().chatMemoryRepository(chatMemoryRepository) // 底層記憶存儲倉庫(測試使用內存實現).maxMessages(20)    // 設置歷史消息最大保留輪次(滑動窗口大小).build();// 2. 生成唯一會話ID(實際項目中由)String conversationId = "123456789"; // 示例固定值,生產環境需動態生成// 3. 構建對話請求并配置各組件return this.chatClient.prompt()// 3.1 設置對話角色.system(system)  // 系統角色設定(AI人設/指令)// 3.2 設置基礎參數.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, conversationId) // 綁定當前對話ID到請求上下文)// 3.3 添加增強功能(Advisors).advisors(new SimpleLoggerAdvisor(),  // 啟用請求日志記錄(用于調試)MessageChatMemoryAdvisor.builder(chatMemory).build(),   // 啟用記憶管理功能new SystemFirstSortingAdvisor() // 確保系統消息優先排序)// 3.4 設置當前用戶輸入.user(userInput)// 3.5 執行調用.call() // 發送同步請求到對話服務// 3.6 處理響應.content(); // 提取響應中的文本內容}

綜上所述,下個版本可能會優化掉這個BUG,目前就先使用SystemFirstSortingAdvisor來保證正常調用。

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

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

相關文章

全景式綜述|多模態目標跟蹤全面解析:方法、數據、挑戰與未來

【導讀】 目標跟蹤&#xff08;Visual Object Tracking, VOT&#xff09;一直是計算機視覺領域的核心問題之一&#xff0c;廣泛應用于自動駕駛、無人機監控、人機交互等場景。隨著單模態方法在復雜環境下逐漸遇到瓶頸&#xff0c;多模態視覺目標跟蹤&#xff08;Multi-Modal V…

怎么用pytorch訓練一個模型,并跑起來

MNIST 手寫數字識別 任務描述 MNIST 手寫數字識別是機器學習和計算機視覺領域的經典任務&#xff0c;其本質是解決 “從手寫數字圖像中自動識別出對應的數字&#xff08;0-9&#xff09;” 的問題&#xff0c;屬于單標簽圖像分類任務&#xff08;每張圖像僅對應一個類別&#x…

Qt應用程序發布方式

解決的問題&#xff1a;在自己電腦上用QT Creator編譯的exe文件放到其他電腦上不能正常打開的問題。1、拷貝已經編譯好的exe應用程序到桌面文件夾。桌面新建文件夾WindowsTest&#xff0c;并且將編譯好的軟件WindowTest.exe放入此文件夾中。2、在此文件夾空白處按住Shift再點擊…

Linux 軟件編程(九)網絡編程:IP、端口與 UDP 套接字

1. 學習目的實現 不同主機之間的進程間通信。在 Linux 下&#xff0c;進程間通信&#xff08;IPC&#xff09;不僅可以發生在同一臺主機上&#xff0c;也可以通過網絡實現不同主機之間的通信。要做到這一點&#xff0c;必須同時滿足以下兩個條件&#xff1a;物理層面&#xff1…

5.Kotlin作用于函數let、run、with、apply、also

選擇建議 需要返回值&#xff1a;使用 let、run 或 with配置對象&#xff1a;使用 apply附加操作&#xff1a;使用 also非空檢查&#xff1a;使用 let鏈式調用&#xff1a;使用 let 或 run Kotlin作用域函數詳解 概述 Kotlin提供了5個作用域函數&#xff1a;let、run、with、ap…

嵌入式學習日記(32)Linux下的網絡編程

1. 目的不同主機&#xff0c;進程間通信。2. 解決的問題1&#xff09;. 主機與主機之間物理層面必須互聯互通。2.&#xff09; 進程與進程在軟件層面必須互聯互通。IP地址&#xff1a;計算機的軟件地址&#xff0c;用來標識計算機設備 MAC地址&#xff1a;計算機的硬件地址&…

C#_接口設計:角色與契約的分離

2.3 接口設計&#xff1a;角色與契約的分離 在軟件架構中&#xff0c;接口&#xff08;Interface&#xff09;遠不止是一種語言結構。它是一份契約&#xff08;Contract&#xff09;&#xff0c;明確規定了實現者必須提供的能力&#xff0c;以及使用者可以依賴的服務。優秀的接…

vsCode或Cursor 使用remote-ssh插件鏈接遠程終端

一、Remote-SSH介紹Remote-SSH 是 VS Code 官方提供的一個擴展插件&#xff0c;允許開發者通過 SSH 協議連接到遠程服務器&#xff0c;并在本地編輯器中直接操作遠程文件&#xff0c;實現遠程開發。它將本地編輯器的功能&#xff08;如語法高亮、智能提示、調試等&#xff09;與…

C語言實戰:從零開始編寫一個通用配置文件解析器

資料合集下載鏈接: ?https://pan.quark.cn/s/472bbdfcd014? 在軟件開發中,我們經常需要將一些可變的參數(如數據庫地址、端口號、游戲角色屬性等)與代碼本身分離,方便日后修改而無需重新編譯整個程序。這種存儲配置信息的文件,我們稱之為配置文件。 一、 什么是配置…

車機兩分屏運行Unity制作的效果

目錄 效果概述 實現原理 完整實現代碼 實際車機集成注意事項 1. 顯示系統集成 多屏顯示API調用 代碼示例&#xff08;AAOS副駕屏顯示&#xff09; 2. 性能優化 GPU Instancing 其他優化技術 3. 輸入處理 觸控處理 物理按鍵處理 4. 安全規范 駕駛員側限制 乘客側…

vivo“空間計算-機器人”生態落下關鍵一子

出品 | 何璽排版 | 葉媛不出所料&#xff0c;vivo Vision熱度很高。從21號下午發布到今天&#xff08;22號&#xff09;&#xff0c;大眾圍繞vivo Vision探索版展開了多方面的討論&#xff0c;十分熱烈。從討論來看&#xff0c;大家現在的共識是&#xff0c;MR行業目前還處于起…

Azure TTS Importer:一鍵導入,將微軟TTS語音接入你的閱讀軟件!

Azure TTS Importer&#xff1a;一鍵導入&#xff0c;將微軟TTS語音接入你的閱讀軟件&#xff01; 文章來源&#xff1a;Poixe AI 厭倦了機械、生硬的文本朗讀&#xff1f;想讓你的閱讀軟件擁有自然流暢的AI語音&#xff1f;今天&#xff0c;我們將為您介紹一款強大且安全的開…

用過redis哪些數據類型?Redis String 類型的底層實現是什么?

Redis 數據類型有哪些&#xff1f; 詳細可以查看&#xff1a;數據類型及其應用場景 基本數據類型&#xff1a; String&#xff1a;最常用的一種數據類型&#xff0c;String類型的值可以是字符串、數字或者二進制&#xff0c;但值最大不能超過512MB。一般用于 緩存和計數器 Ha…

大視協作碼垛機:顛覆傳統制造,開啟智能工廠新紀元

在東三省某食品廠的深夜生產線上&#xff0c;碼垛作業正有序進行&#xff0c;卻不見人影——這不是魔法&#xff0c;而是大視協作碼垛機器人帶來的現實變革。在工業4.0浪潮席卷全球的今天&#xff0c;智能制造已成為企業生存與發展的必由之路。智能碼垛環節作為產線的關鍵步驟&…

c# 保姆級分析繼承詳見問題 父類有一個列表對象,子類繼承這個列表對象并對其進行修改后,將子類對象賦值給父類對象,父類對象是否能包含子類新增的內容?

文章目錄 深入解析:父類與子類列表繼承關系的終極指南 一、問題背景:從實際開發困惑說起 二、基礎知識回顧:必備概念理解 2.1 繼承的本質 2.2 引用類型 vs 值類型 2.3 多態的實現方式 三、核心問題分析:列表繼承場景 3.1 基礎代碼示例 3.2 關鍵問題分解 3.3 結論驗證 四、深…

tensorflow-gpu 2.7下的tensorboard與profiler插件版本問題

可行版本&#xff1a; python3.9.23cuda12.0tensorflow-gpu2.7.0tensorboard2.20.0 tensorboard-plugin-profile 2.4.0 問題描述&#xff1a; 1. 安裝tensorboard后運行tensorboard --logdirlogs在網頁中打開&#xff0c;發現profile模塊無法顯示&#xff0c;報錯如下&#x…

數據結構青銅到王者第一話---數據結構基本常識(1)

目錄 一、集合框架 1、什么是集合框架 2、集合框架的重要性 2.1開發中的使用 2.2筆試及面試題 3、背后涉及的數據結構以及算法 3.1什么是數據結構 3.2容器背后對應的數據結構 3.3相關java知識 3.4什么是算法 3.5如何學好數據結構以及算法 二、時間和空間復雜度 1、…

【Verilog】延時和時序檢查

Verilog中延時和時序檢查1. 延時模型1.1 分布延遲1.2 集總延遲1.3 路徑延遲2. specify 語法2.1 指定路徑延時基本路徑延時邊沿敏感路徑延時狀態依賴路徑延時2.2 時序檢查$setup, $hold, $setuphold$recovery, $removal, $recrem$width, $periodnotifier1. 延時模型 真實的邏輯元…

DigitalOcean Gradient AI平臺現已支持OpenAI gpt-oss

OpenAI 的首批開源 GPT 模型&#xff08;200 億和 1200 億參數&#xff09;現已登陸 Gradient AI 平臺。此次發布讓開發者在構建 AI 應用時擁有更高的靈活度和更多選擇&#xff0c;無論是快速原型還是大規模生產級智能體&#xff0c;都能輕松上手。新特性開源 GPT 模型&#xf…

藏在 K8s 幕后的記憶中樞(etcd)

目錄1&#xff09;etcd 基本架構2&#xff09;etcd 的讀寫流程總覽a&#xff09;一個讀流程b&#xff09;一個寫流程3&#xff09;k8s存儲數據過程源碼解讀4&#xff09;watch 機制Informer 機制etcd watch機制etcd的watchableStore源碼解讀5&#xff09; k8s大規模集群時會存在…