SpringAI特性

一、SpringAI 顧問(Advisors)

Spring AI 使用 Advisors機制來增強 AI 的能力,可以理解為一系列可插拔的攔截器,在調用 AI 前和調用 AI 后可以執行一些額外的操作,比如:

  • 前置增強:調用 AI 前改寫一下 Prompt 提示詞、檢查一下提示詞是否安全
  • 后置增強:調用 AI 后記錄一下日志、處理一下返回的結果

在這里插入圖片描述

解釋上圖的執行流程:

  1. Spring AI 框架從用戶的 Prompt 創建一個 AdvisedRequest,同時創建一個空的 AdvisorContext 對象,用于傳遞信息。
  2. 鏈中的每個 advisor 處理這個請求,可能會對其進行修改。或者,它也可以選擇不調用下一個實體來阻止請求繼續傳遞,這時該 advisor 負責填充響應內容。
  3. 由框架提供的最終 advisor 將請求發送給聊天模型 ChatModel。
  4. 聊天模型的響應隨后通過 advisor 鏈傳回,并被轉換為 AdvisedResponse。后者包含了共享的 AdvisorContext 實例。
  5. 每個 advisor 都可以處理或修改這個響應。
  6. 最終的 AdvisedResponse 通過提取 ChatCompletion 返回給客戶端。

自定義實現攔截器:

  • CallAroundAdvisor:用于處理同步請求和響應(非流式)
  • StreamAroundAdvisor:用于處理流式請求和響應
    由于源碼中實現類很多、所以我們可以自定義攔截器
    在這里插入圖片描述
package com.MrSun.mrsun_agent.advisor;import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.advisor.api.*;
import org.springframework.ai.chat.model.MessageAggregator;
import reactor.core.publisher.Flux;/*** 自定義日志 Advisor* 打印 info 級別日志、只輸出單次用戶提示詞和 AI 回復的文本*/
@Slf4j
public class MyLoggerAdvisor implements CallAroundAdvisor, StreamAroundAdvisor {@Overridepublic String getName() {return this.getClass().getSimpleName();}@Overridepublic int getOrder() {return 0;}/**** @param request* @return*/private AdvisedRequest before(AdvisedRequest request) {//  日志輸出log.info("AI Request: {}", request.userText());return request;}private void observeAfter(AdvisedResponse advisedResponse) {log.info("AI Response: {}", advisedResponse.response().getResult().getOutput().getText());}public AdvisedResponse aroundCall(AdvisedRequest advisedRequest, CallAroundAdvisorChain chain) {// 先執行before 處理請求,然后在進行處理響應advisedRequest = this.before(advisedRequest);AdvisedResponse advisedResponse = chain.nextAroundCall(advisedRequest);this.observeAfter(advisedResponse);return advisedResponse;}public Flux<AdvisedResponse> aroundStream(AdvisedRequest advisedRequest, StreamAroundAdvisorChain chain) {advisedRequest = this.before(advisedRequest);Flux<AdvisedResponse> advisedResponses = chain.nextAroundStream(advisedRequest);// 消息聚合器 等到一起在進行響應return (new MessageAggregator()).aggregateAdvisedResponse(advisedResponses, this::observeAfter);}
}

1、Chat Memory Advisor

前面我們提到了,想要實現對話記憶功能,可以使用 Spring AI 的 ChatMemoryAdvisor,它主要有幾種內置的實現方式:

  • MessageChatMemoryAdvisor:從記憶中檢索歷史對話,并將其作為消息集合添加到提示詞中
  • PromptChatMemoryAdvisor:從記憶中檢索歷史對話,并將其添加到提示詞的系統文本中
  • VectorStoreChatMemoryAdvisor:可以用向量數據庫來存儲檢索歷史對話

1)MessageChatMemoryAdvisor 將對話歷史作為一系列獨立的消息添加到提示中,保留原始對話的完整結構,包括每條消息的角色標識(用戶、助手、系統)。

[{"role": "user", "content": "你好"},{"role": "assistant", "content": "你好!有什么我能幫助你的嗎?"},{"role": "user", "content": "講個笑話"}
]

2)PromptChatMemoryAdvisor 將對話歷史添加到提示詞的系統文本部分,因此可能會失去原始的消息邊界。

以下是之前的對話歷史:
用戶: 你好
助手: 你好!有什么我能幫助你的嗎?
用戶: 講個笑話
現在請繼續回答用戶的問題。

一般情況下,更建議使用 MessageChatMemoryAdvisor。更符合大多數現代 LLM 的對話模型設計,能更好地保持上下文連貫性。

2、Chat Memory

上述 ChatMemoryAdvisor 都依賴 [Chat Memory]進行構造,Chat Memory 負責歷史對話的存儲,定義了保存消息、查詢消息、清空消息歷史的方法。其實就是基本的增刪改查

在這里插入圖片描述
Spring AI 內置了幾種 Chat Memory,可以將對話保存到不同的數據源中,比如:

  • InMemoryChatMemory:內存存儲
  • CassandraChatMemory:在 Cassandra 中帶有過期時間的持久化存儲
  • Neo4jChatMemory:在 Neo4j 中沒有過期時間限制的持久化存儲
  • JdbcChatMemory:在 JDBC 中沒有過期時間限制的持久化存儲

實現對話記憶

1)首先初始化 ChatClient 對象。使用 Spring 的構造器注入方式來注入阿里大模型 dashscopeChatModel 對象,并使用該對象來初始化 ChatClient。初始化時指定默認的系統 Prompt 和基于內存的對話記憶 Advisor。代碼如下:

@Component
@Slf4j
public class LoveApp {private final ChatClient chatClient;private static final String SYSTEM_PROMPT = "扮演深耕戀愛心理領域的專家。開場向用戶表明身份,告知用戶可傾訴戀愛難題。" +"圍繞單身、戀愛、已婚三種狀態提問:單身狀態詢問社交圈拓展及追求心儀對象的困擾;" +"戀愛狀態詢問溝通、習慣差異引發的矛盾;已婚狀態詢問家庭責任與親屬關系處理的問題。" +"引導用戶詳述事情經過、對方反應及自身想法,以便給出專屬解決方案。";public LoveApp(ChatModel dashscopeChatModel) {// 初始化基于內存的對話記憶ChatMemory chatMemory = new InMemoryChatMemory();chatClient = ChatClient.builder(dashscopeChatModel).defaultSystem(SYSTEM_PROMPT).defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory)).build();}
}

2)編寫對話方法。調用 chatClient 對象,傳入用戶 Prompt,并且給 advisor 指定對話 id 和對話記憶大小。代碼如下:

public String doChat(String message, String chatId) {ChatResponse response = chatClient.prompt().user(message).advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId).param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10)).call().chatResponse();String content = response.getResult().getOutput().getText();log.info("content: {}", content);return content;
}

3)編寫單元測試,測試多輪對話:

    @Testvoid testChat() {//生成一個繪畫IDString chatId= UUID.randomUUID().toString();//第一輪String message="你好,我是南瓜";String answer= loveApp.doChat(message,chatId);//第二輪message="我想讓另一半(松鼠)更喜歡我";answer= loveApp.doChat(message,chatId);Assertions.assertNotNull(answer);//第三輪message="我的另一半是誰了。我忘記了,你幫我回憶一下";answer= loveApp.doChat(message,chatId);Assertions.assertNotNull(answer);}

效果如下:
在這里插入圖片描述
這樣就可以實現多輪對話功能。

3、Re-Reading Advisor

實現一個 Re-Reading(重讀)Advisor,又稱 Re2。該技術通過讓模型重新閱讀問題來提高推理能力,有文獻 來印證它的效果。
注意:雖然該技術可提高大語言模型的推理能力,不過成本會加倍!
Re2 的實現原理很簡單,改寫用戶 Prompt 為下列格式,也就是讓 AI 重復閱讀用戶的輸入:

/*** 自定義 Re2 Advisor* 可提高大型語言模型的推理能力*/
public class ReReadingAdvisor implements CallAroundAdvisor, StreamAroundAdvisor {private AdvisedRequest before(AdvisedRequest advisedRequest) {Map<String, Object> advisedUserParams = new HashMap<>(advisedRequest.userParams());advisedUserParams.put("re2_input_query", advisedRequest.userText());return AdvisedRequest.from(advisedRequest).userText("""{re2_input_query}Read the question again: {re2_input_query}""").userParams(advisedUserParams).build();}@Overridepublic AdvisedResponse aroundCall(AdvisedRequest advisedRequest, CallAroundAdvisorChain chain) {return chain.nextAroundCall(this.before(advisedRequest));}@Overridepublic Flux<AdvisedResponse> aroundStream(AdvisedRequest advisedRequest, StreamAroundAdvisorChain chain) {return chain.nextAroundStream(this.before(advisedRequest));}@Overridepublic int getOrder() {return 0;}@Overridepublic String getName() {return this.getClass().getSimpleName();}
}

以上就是SpringAI的一些特性。

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

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

相關文章

101alpha_第6個

第6個alpha (-1 * correlation(open, volume, 10)) 這個就是看這兩個相似性。10天之內的 如果結果為正且數值較大&#xff0c;投資者可能會認為在開盤價上漲時成交量萎縮&#xff0c;市場上漲動力不足&#xff0c;可能是賣出信號&#xff1b;反之&#xff0c;開盤價下跌時成交…

【滲透測試】Web服務程序解析漏洞原理、利用方式、防范措施

文章目錄 Web服務程序解析漏洞原理、利用方式、防范措施一、原理**1. 定義與觸發條件****2. 攻擊鏈流程圖** 二、利用方式**1. 常見漏洞類型與利用手法**(1) IIS 5.x-6.x解析漏洞(2) Apache解析漏洞(3) Nginx解析漏洞(4) IIS 7.x解析漏洞(5) PHP CGI解析漏洞&#xff08;CVE-20…

SSL證書格式詳解:PEM、CER、DER、JKS、PKCS12等

引言 在網絡安全領域&#xff0c;SSL/TLS證書是保障互聯網通信安全的核心工具。它們通過加密連接&#xff0c;確保服務器與客戶端之間的數據隱私和完整性。然而&#xff0c;對于初學者來說&#xff0c;SSL證書的多種格式——PEM、CER、JKS、PKCS12、PFX等——常常令人困惑。每…

生信服務器如何安裝cellranger|生信服務器安裝軟件|單細胞測序軟件安裝

一.Why cellranger Cell Ranger 是由 10x Genomics 公司開發的一款用于處理其單細胞測序&#xff08;single-cell RNA-seq, scRNA-seq&#xff09;數據的軟件套件。它主要用于將原始測序數據&#xff08;fastq 文件&#xff09;轉換為可以用于下游分析的格式&#xff0c;比如基…

Redis 常見數據類型

Redis 常見數據類型 一、基本全局命令詳解與實操 1. KEYS 命令 功能&#xff1a;按模式匹配返回所有符合條件的鍵&#xff08;生產環境慎用&#xff0c;可能導致阻塞&#xff09;。 語法&#xff1a; KEYS pattern 模式規則&#xff1a; h?llo&#xff1a;匹配 hello, ha…

33號遠征隊 - 游玩鑒賞

風景很好畫質很好 , 圖片太大只能截圖一小部分 地編和特效 值得參考

使用JMETER中的JSON提取器實現接口關聯

一、JSON提取器介紹 JSON提取器是JMETER工具中用于從JSON響應中提取數據的重要組件&#xff0c;常常用于接口關聯場景中&#xff08;參數傳遞&#xff09;。 二、添加JSON提取器 舉例&#xff08;積分支付接口請求數據依賴于創建訂單接口響應的payOrderId&#xff09; 1.在…

QT6(35)4.8定時器QTimer 與QElapsedTimer:理論,例題的界面搭建,與功能的代碼實現。

&#xff08;112&#xff09; &#xff08;113&#xff09;模仿隨書老師給的源代碼搭建的&#xff0c; LCD 顯示的部分不一樣 &#xff1a; &#xff08;114&#xff09;以下開始代碼完善&#xff1a; 關聯定時器的信號與槽函數 &#xff1a; &#xff08;115&#xff09;…

nvidia-smi 和 nvcc -V 作用分別是什么?

命令1&#xff1a;nvidia-smi 可以查看當前顯卡的驅動版本&#xff0c;以及該驅動支持的CUDA版本。 命令2&#xff1a;nvcc -V 可以看到實際安裝的CUDA工具包版本為 12.8 更詳細的介紹&#xff0c;可以參考如下鏈接

Excel 數據 可視化 + 自動化!Excel 對比軟件

各位Excel小能手們&#xff01;你們有沒有過要對比兩個Excel表格數據差異&#xff0c;卻看得眼睛都花了的經歷&#xff1f;其實啊&#xff0c;現在有專門的Excel文件比較軟件能幫咱解決這大難題。這軟件就是用來快速找出兩個或多個Excel表格數據不同之處&#xff0c;還能把修改…

《軟件項目經濟性論證報告模板:全面解析與策略建議》

《軟件項目經濟性論證報告模板:全面解析與策略建議》 一、引言 1.1 項目背景闡述 在數字化浪潮席卷全球的當下,各行業對軟件的依賴程度日益加深。[行業名稱] 行業也不例外,隨著業務規模的不斷擴張、業務復雜度的持續提升以及市場競爭的愈發激烈,對高效、智能、定制化軟件…

高頻工業RFID讀寫器-三格電子

高頻工業RFID讀寫器 型號&#xff1a;SG-HF40-485、SG-HF40-TCP 產品功能 高頻工業讀寫器&#xff08;RFID&#xff09;產品用在自動化生產線,自動化分揀系統,零部件組裝產線等情境下&#xff0c;在自動化節點的工位上部署RFID讀寫設備&#xff0c;通過與制品的交互&#xf…

2025年5月計劃(linux+Gpu精粹催眠+UE獨立游戲)

終于步入正軌了&#xff0c;4月份為了各種面試&#xff0c;一會學這&#xff0c;一會學那。 現在&#xff0c;有大量的業余時間了&#xff0c;也該干點正事了。 按照規劃&#xff0c; 1&#xff0c;ue獨立游戲&#xff08;十分鐘的視頻即可&#xff09; 2&#xff0c;linux-&…

計算機學習路線與編程語言選擇(信息差)

——授人以魚不如授人以漁 計算機學習公式&#xff1a;1/3科班思維 1/3路線選擇 1/3工程能力 好工作隨便找&#xff08;來自B站小毛毛熊&#xff09; 本文主要是路線選擇&#xff01;&#xff01;&#xff01;下面開始吧。 面向崗位學習&#xff01;到招聘網站看看有哪些…

『Python學習筆記』ubuntu解決matplotlit中文亂碼的問題!

ubuntu解決matplotlit中文亂碼的問題&#xff01; 文章目錄 simhei.ttf字體下載鏈接&#xff1a;http://xiazaiziti.com/210356.html將字體放到合適的地方 sudo cp SimHei.ttf /usr/share/fonts/(base) zkfzkf:~$ fc-list | grep -i "SimHei" /usr/local/share/font…

電動汽車充換電設施可調能力聚合評估與預測 - 使用說明文檔

電動汽車充換電設施可調能力聚合評估與預測 - 使用說明文檔 概述 本腳本real_data_model.m基于論文《大規模電動汽車充換電設施可調能力聚合評估與預測》(鮑志遠&#xff0c;胡澤春)實現了電動汽車充電設施的負荷預測和可調能力評估。使用混合模型&#xff08;LSTM神經網絡線…

C#生成二維碼和條形碼

C# 實現二維碼和條形碼生成&#xff1a;從入門到實戰 文章目錄 C# 實現二維碼和條形碼生成&#xff1a;從入門到實戰一、引言二、準備工作2.1 開發環境搭建2.2 引入相關庫 三、生成條形碼3.1 條形碼基本概念3.2 使用[ZXing.Net](https://ZXing.Net)生成條形碼3.2.1 核心代碼實現…

C++結構體介紹

結構體的定義 在C中&#xff0c;結構體&#xff08;struct&#xff09;是一種用戶定義的數據類型&#xff0c;允許將不同類型的數據組合在一起。結構體的定義使用struct關鍵字&#xff0c;后跟結構體名稱和一對花括號{}&#xff0c;花括號內包含成員變量的聲明。 struct Pers…

各類音頻放大器電路原理簡析

A類&#xff08;甲類&#xff09;放大器 晶體管在整個信號周期內始終導通&#xff0c;導通角為360 本質上是一個簡單的共源放大電路&#xff0c;M1 是放大管&#xff0c;M2 為電流源管負載&#xff0c;其最大輸出電流受ID2控制&#xff0c;帶負載能力弱。 B類&#xff08;乙類…

OpenCV的 ccalib 模塊用于自定義標定板的檢測和處理類cv::ccalib::CustomPattern()----函數calibrate

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 cv::ccalib::CustomPattern 是OpenCV的 ccalib 模塊中的一個類&#xff0c;主要用于自定義標定板的檢測和處理。這個模塊提供了比傳統的 calib3d…