SpringAI實現AI應用-內置顧問

SpringAI實戰鏈接

1.SpringAl實現AI應用-快速搭建-CSDN博客

2.SpringAI實現AI應用-搭建知識庫-CSDN博客

3.SpringAI實現AI應用-內置顧問-CSDN博客

4.SpringAI實現AI應用-使用redis持久化聊天記憶-CSDN博客

5.SpringAI實現AI應用-自定義顧問(Advisor)-CSDN博客

概述

通過前兩篇帖子,對SpringAI的使用應該有了大致的了解,那么本篇就需要真正去看以下SpringAI里面真正的東西了

首先先看SpringAI官方文檔-Advisors

中文版:顧問 API :: Spring AI 參考 - Spring 框架

官方:Advisors API :: Spring AI Reference

通過文檔可以知道Spring AI 框架提供了幾個內置顧問,以增強?AI 交互。以下是可用顧問的概覽:

聊天記憶顧問

????????這些顧問在聊天記憶存儲中管理對話歷史:

????????MessageChatMemoryAdvisor

????????檢索記憶并將其作為消息集合添加到提示中。這種方法保持了對話歷史的結構。請注意,并非所有 AI 模型都支持這種方法。

????????PromptChatMemoryAdvisor

????????檢索記憶并將其并入提示的系統文本中。

????????VectorStoreChatMemoryAdvisor

????????從 VectorStore 中檢索記憶并將其添加到提示的系統文本中。這個顧問對于高效搜索和檢索大型數據集中的相關信息非常有用。

問題回答顧問

????????QuestionAnswerAdvisor

????????這個顧問使用向量存儲提供問題回答能力,實現了 RAG(檢索增強生成)模式。

內容安全顧問

????????SafeGuardAdvisor

????????一個簡單的顧問,旨在防止模型生成有害或不適當的內容。

聊天記憶實例

接下來繼續使用之前的代碼,逐個驗證這些內置顧問的功能和作用

ChatMemory

想要使用聊天記憶顧問之前,先看一下聊天記憶顧問里的源碼

MessageChatMemoryAdvisor

PromptChatMemoryAdvisor

VectorStoreChatMemoryAdvisor

從源碼中可以看到,兩個內置顧問的構造方法中都有ChatMemory,而VectorStoreChatMemoryAdvisor的構造方法入參的是向量庫,那就先看一下ChatMemory,它是一個內存管理容器,用于存儲和管理多輪對話中的ChatMessage。它不僅允許開發者保存消息,還提供了消息驅逐策略(Eviction Policy)、持久化存儲(Persistence)以及特殊消息處理(如SystemMessage和ToolExecutionMessage)等功能。此外,ChatMemory還與high-level組件(如AI服務)集成,便于開發者更方便地管理對話歷史。

先看一下ChatMemory里的方法

1.add(String conversationId, Message message):將單個消息添加到指定會話的對話中。
2.add(String conversationId, List<Message> messages):將消息列表添加到指定會話的對話中。
3.get(String conversationId, int lastN):從指定會話的對話中檢索最新的N條消息。
4.clear(String conversationId):清除指定會話的對話歷史記錄。

而ChatMemory的實現類是InMemoryChatMemory這個類再之前兩篇帖子的配置類中有實現。

InMemoryChatMemory是Spring AI框架提供的一種ChatMemory實現,它將對話歷史記錄存儲在內存中。這種實現方式具有快速訪問和檢索消息的優點,適用于快速原型開發和測試場景。由于內存是易失性存儲介質,因此InMemoryChatMemory不適用于需要長期保存聊天記錄的應用場景。

而其中的方法也為能持久化聊天記錄提供了幫助,

修改之前接口代碼中的call方法如下(簡單實現)

    /*** 根據消息直接輸出回答* @param map* @return*/@PostMapping("/ai/call")public String call(@RequestBody Map<String,String> map) {String message = map.get("message");Message message1 = new UserMessage(message);String trim = chatClient.prompt().user(message).call().content().trim();Message message2 = new UserMessage(MessageType.SYSTEM, trim, new ArrayList<>(), Map.of());inMemoryChatMemory.add("123456",List.of(message1,message2));return trim;}

然后再獲取聊天記錄進行(簡單實現)

    /*** 查詢聊天記里* @return*/@GetMapping("/ai/chatMemory")public List<Message> chatMemory(){List<Message> messages = inMemoryChatMemory.get("123456", 10);for (Message message : messages) {System.out.println(message.getText());}return messages;}

MessageChatMemoryAdvisor

了解完ChatMemory,那就開始看第一個內置顧問MessageChatMemoryAdvisor,這個也在之前的代碼中實現過,當時為了簡單實現多輪對話記憶,而且還是加在了方法上

這篇帖子,我們將代碼加在配置類上,修改配置類如下,配置類中沒有配置會話id和儲存大小,是因為統一進行的配置,這種方式將chatClient注冊到spring容器的時候,還沒有辦法知道用戶的會話id,所以只能默認,儲存大小也使用默認,默認大小為100

    @BeanChatClient chatClient(ChatClient.Builder builder) {return builder// 它定義了聊天機器人在回答問題時應當遵循的風格和角色定位。.defaultSystem("你是一個智能機器人,你的名字叫 Spring AI智能機器人").defaultAdvisors(new MessageChatMemoryAdvisor(inMemoryChatMemory())).build();}

此時所有的接口都實現了記憶對話的功能

測試

由此可見在全局都已經實現了對話記憶

PromptChatMemoryAdvisor

再來看PromptChatMemoryAdvisor,它和MessageChatMemoryAdvisor的類似,也是直接修改配置類,如下

    @BeanChatClient chatClient(ChatClient.Builder builder) {return builder// 它定義了聊天機器人在回答問題時應當遵循的風格和角色定位。.defaultSystem("你是一個智能機器人,你的名字叫 Spring AI智能機器人").defaultAdvisors(
//                        new MessageChatMemoryAdvisor(inMemoryChatMemory())new PromptChatMemoryAdvisor(inMemoryChatMemory())).build();}

VectorStoreChatMemoryAdvisor

VectorStoreChatMemoryAdvisor 是 Spring AI 框架中的一個組件,它結合了向量存儲(VectorStore)技術來增強聊天機器人的記憶能力。這個 Advisor 利用向量數據庫存儲用戶與聊天機器人的交互歷史,包括用戶提出的問題和模型的回答。在生成新的回復時,VectorStoreChatMemoryAdvisor 會檢索與當前問題相關的歷史記錄,并將其作為上下文信息添加到提示中,從而幫助大型語言模型(LLM)生成更連貫和準確的回復。

具體實現需要將聊天記錄持久化到向量庫,下篇帖子再詳細說明聊天記錄持久化的問題

區別

看了SpringAI的官方文檔,網上也搜了一下這三個內置顧問,都說的太官方了,簡單說一下:

MessageChatMemoryAdvisor:將對話歷史以消息集合的形式存儲和傳遞。它維護了一個結構化的對話歷史記錄,通常將用戶消息和模型響應封裝為消息對象。適用于需要保持對話歷史結構的場景,例如需要明確區分用戶消息和系統消息。

PromptChatMemoryAdvisor:將對話歷史以純文本的形式合并到系統提示中。它將歷史消息轉換為一個字符串,并將其附加到系統提示的文本中。適用于需要將歷史信息作為上下文傳遞給模型的場景,尤其是當模型不支持消息集合時。

VectorStoreChatMemoryAdvisor:使用向量存儲技術將對話歷史存儲在向量數據庫中。它將對話記錄封裝為向量形式的文檔,并通過向量檢索來獲取相關的歷史信息。適用于需要高效檢索和處理大規模數據集的場景。

問題回答實例

QuestionAnswerAdvisor

這個顧問訪問的就是上篇帖子實現的向量庫,當用戶提出問題時,QuestionAnswerAdvisor會首先對知識庫進行檢索,并將匹配到的相關引用文本添加到用戶提問的后面,從而為生成的回答提供更為豐富和準確的上下文。此外,該Advisor還設定了一個默認提示詞,旨在確保回答的質量和相關性。如果在知識庫中無法找到匹配的文本,系統將可能拒絕回答用戶的問題。

實現如下:

    @BeanChatClient chatClient(ChatClient.Builder builder,VectorStore vectorStore) {return builder// 它定義了聊天機器人在回答問題時應當遵循的風格和角色定位。.defaultSystem("你是一個智能機器人,你的名字叫 Spring AI智能機器人").defaultAdvisors(
//                        new MessageChatMemoryAdvisor(inMemoryChatMemory())new PromptChatMemoryAdvisor(inMemoryChatMemory()),QuestionAnswerAdvisor.builder(vectorStore).order(1).build()).build();}

測試

經過測試可以看到,只有問向量庫中的內容,才會進行回答

內容安全實例

SafeGuardAdvisor

這個顧問顧名思義就是過濾敏感詞匯的,具體實現如下

    @BeanChatClient chatClient(ChatClient.Builder builder,VectorStore vectorStore) {return builder// 它定義了聊天機器人在回答問題時應當遵循的風格和角色定位。.defaultSystem("你是一個智能機器人,你的名字叫 Spring AI智能機器人").defaultAdvisors(
//                        new MessageChatMemoryAdvisor(inMemoryChatMemory())new PromptChatMemoryAdvisor(inMemoryChatMemory()),QuestionAnswerAdvisor.builder(vectorStore).order(1).build(),SafeGuardAdvisor.builder().sensitiveWords(List.of("色情", "暴力")) // 敏感詞列表.order(2) // 設置優先級.failureResponse("抱歉,我無法回答這個問題。").build() // 敏感詞過濾失敗時的響應).build();}

測試

經過測試,安全顧問已經把敏感詞進行了過濾

完整代碼

AiConfig(配置文件)

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.*;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.List;/*** @Author majinzhong* @Date 2025/4/28 10:34* @Version 1.0*/
@Configuration
public class AiConfig {@BeanChatClient chatClient(ChatClient.Builder builder,VectorStore vectorStore) {return builder// 它定義了聊天機器人在回答問題時應當遵循的風格和角色定位。.defaultSystem("你是一個智能機器人,你的名字叫 Spring AI智能機器人")//這里可以添加多個顧問 order(優先級)越小,越先執行// 注意:顧問添加到鏈中的順序至關重要,因為它決定了其執行的順序。每個顧問都會以某種方式修改提示或上下文,一個顧問所做的更改會傳遞給鏈中的下一個顧問。// 在此配置中,將首先執行MessageChatMemoryAdvisor,將對話歷史記錄添加到提示中。然后,問答顧問將根據用戶的問題和添加的對話歷史進行搜索,從而可能提供更相關的結果。.defaultAdvisors(//內存存儲對話記憶
//                        new MessageChatMemoryAdvisor(inMemoryChatMemory()),new PromptChatMemoryAdvisor(inMemoryChatMemory()),// QuestionAnswerAdvisor 此顧問使用矢量存儲提供問答功能,實現RAG(檢索增強生成)模式QuestionAnswerAdvisor.builder(vectorStore).order(1).build(),// SafeGuardAdvisor是一個安全防護顧問,它確保生成的內容符合道德和法律標準。SafeGuardAdvisor.builder().sensitiveWords(List.of("色情", "暴力")) // 敏感詞列表.order(2) // 設置優先級.failureResponse("抱歉,我無法回答這個問題。").build(), // 敏感詞過濾失敗時的響應// SimpleLoggerAdvisor是一個記錄ChatClient的請求和響應數據的顧問。這對于調試和監控您的AI交互非常有用,建議將其添加到鏈的末尾。new SimpleLoggerAdvisor()).defaultOptions(ChatOptions.builder().topP(0.7) // 取值越大,生成的隨機性越高;取值越低,生成的隨機性越低。默認值為0.8.build()).build();}@BeanChatMemory inMemoryChatMemory() {return new InMemoryChatMemory();}
}

AdvisorController(測試接口)

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.MessageType;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.web.bind.annotation.*;import java.util.ArrayList;
import java.util.List;
import java.util.Map;import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY;/*** @Author majinzhong* @Date 2025/5/6 14:22* @Version 1.0*/
@CrossOrigin
@RestController
public class AdvisorController {// 負責處理OpenAI的bean,所需參數來自properties文件private final ChatClient chatClient;//對話記憶private final InMemoryChatMemory inMemoryChatMemory;public AdvisorController(ChatClient chatClient,InMemoryChatMemory inMemoryChatMemory) {this.chatClient = chatClient;this.inMemoryChatMemory = inMemoryChatMemory;}/*** 普通聊天* @param message* @param sessionId* @return*/@GetMapping("/ai/generateCall")public String generateCall(@RequestParam(value = "message", defaultValue = "講個笑話") String message, @RequestParam String sessionId) {return chatClient.prompt().user(message).advisors(advisorSpec -> advisorSpec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, sessionId).param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10)).call().content().trim();}/*** 根據消息直接輸出回答* @param map* @return*/@PostMapping("/ai/callAdvisor")public String call(@RequestBody Map<String,String> map) {String message = map.get("message");Message message1 = new UserMessage(message);String trim = chatClient.prompt().user(message).call().content().trim();Message message2 = new UserMessage(MessageType.SYSTEM, trim, new ArrayList<>(), Map.of());inMemoryChatMemory.add("123456",List.of(message1,message2));return trim;}/*** 查詢聊天記里* @return*/@GetMapping("/ai/chatMemory")public List<Message> chatMemory(){List<Message> messages = inMemoryChatMemory.get("123456", 10);for (Message message : messages) {System.out.println(message.getText());}return messages;}
}

代碼中的這個方法設置了記憶對話的對話id和存儲的大小

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

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

相關文章

Nginx核心原理以及案例分析(AI)

一、Nginx核心原理分析 1. ?事件驅動與非阻塞模型? ?Epoll異步機制?&#xff1a;基于Linux的epoll模型實現異步非阻塞I/O處理&#xff0c;單線程可高效管理數萬并發連接&#xff0c;避免傳統select模型的輪詢性能瓶頸。?多進程架構?&#xff1a;采用Master-Worker模式&…

【Bug經驗分享】SourceTree用戶設置必須被修復/SSH 主機密鑰未緩存(踩坑)

文章目錄 配置錯誤問題原因配置錯誤問題解決主機密鑰緩存問題原因主機密鑰緩存問題解決 更多相關內容可查看 配置錯誤問題原因 電腦太卡&#xff0c;曾多次強制關機&#xff0c;在關機前沒有關閉SourceTree&#xff0c;導致配置錯誤等問題 配置錯誤問題解決 方式一&#xff…

阿里云服務器-centos部署定時同步數據庫數據-dbswitch

前言&#xff1a; 本文章介紹通過dbswitch工具實現2個mysql數據庫之間實現自動同步數據。 應用場景&#xff1a;公司要求實現正式環境數據庫數據自動冷備 dbswitch依賴環境&#xff1a;git ,maven,jdk 方式一&#xff1a; 不需要在服務器中安裝git和maven&#xff0c;直接用…

windows10 環境下通過huggingface_hub下載huggingface社區模型

項目場景&#xff1a; 有一些模型需要在huggingface下載&#xff0c;因為國內限制&#xff0c;一般無法訪問huggingface網站進行下載。然而&#xff0c;可以通過國內的鏡像下載。網上大部分都是在linux系統下&#xff0c;通過huggingface提供的指令下載。本文針對采用python腳…

C++之異常

目錄 前言 一、什么是異常 二、C中的異常 2.1 C語言中的異常處理 2.2 C中的異常處理 2.3 異常的拋出與捕獲 2.4 棧展開 2.5 查找匹配的處理代碼 2.6 異常重新拋出 2.7 異常安全問題 2.8 異常規范 2.9 標準庫的異常 前言 在之前我們已經學習了C中不少知識了&#xff0c;但是其中…

$在R語言中的作用

在 R 語言中&#xff0c;$ 是一個非常重要的操作符&#xff0c;主要用于訪問對象的成員或組件。它的用途非常廣泛&#xff0c;不僅限于數據框&#xff08;data frame&#xff09;&#xff0c;還可以用于列表&#xff08;list&#xff09;、環境&#xff08;environment&#xf…

設計一個分布式系統:要求全局消息順序,如何使用Kafka實現?

一、高吞吐低延遲 Kafka 集群設計要點 1. 分區策略優化 // 計算合理分區數公式&#xff08;動態調整&#xff09; int numPartitions max(Tp, Tc) / min(Tp, Tc) // Tp生產者吞吐量 Tc消費者吞吐量建議初始按業務鍵&#xff08;如訂單ID&#xff09;哈希分區單分區吞吐建議…

[dify]官方模板DeepResearch工作流學習筆記

一、功能 根據用戶輸入的主題進行多輪搜索并生成綜合報告 1、流程分析 1.1 初始階段 Start節點&#xff1a;接收用戶輸入的"depth"參數&#xff0c;決定搜索的深度/輪數 參數可以不填&#xff0c;不填的時候取默認值3 Create Array節點&#xff1a;根據depth參數…

hadoop中的序列化和反序列化(3)

3. Java的序列化 Java提供了內置的序列化機制&#xff0c;通過java.io.Serializable接口實現。 3.1 如何實現Java序列化 讓類實現Serializable接口。 使用ObjectOutputStream進行序列化。 使用ObjectInputStream進行反序列化。 示例代碼 序列化 java 復制 import jav…

6、CMake基礎:流程控制

流程控制 1. 條件判斷1.1 基本表達式1.2 邏輯判斷1.3 比較基于數值的比較基于字符串的比較 1.4 文件操作1.5 其他 2. 循環2.1 foreach方法1方法2方法3方法4 2.2 while 在 CMake 的 CMakeLists.txt 中也可以進行流程控制&#xff0c;也就是說可以像寫 shell 腳本那樣進行條件判斷…

【網絡編程】二、UDP網絡套接字編程詳解

文章目錄 前言Ⅰ. UDP服務端一、服務器創建流程二、創建套接字 -- socketsocket 屬于什么類型的接口???socket 是被誰調用的???socket 底層做了什么???和其函數返回值有沒有什么關系??? 三、綁定對應端口號、IP地址到套接字 -- bind四、數據的發送和接收 -- sendto…

準確--Notepad++ 實用的插件介紹

Notepad 提供了很多實用的插件&#xff0c;可以極大地提升編程和文本編輯的效率。以下是一些常用且有用的插件介紹&#xff1a; 1. NPP Export 功能&#xff1a;可以將打開的文件導出為 HTML 或 RTF 格式&#xff0c;方便生成漂亮的代碼文檔。用途&#xff1a;適合需要將代碼…

[20250507] AI邊緣計算開發板行業調研報告 ??(2024年最新版)?

[20250507] AI邊緣計算開發板行業調研報告 ??(2024年最新版&#xff09;? 一、行業背景?? 隨著物聯網設備激增與AI模型輕量化&#xff0c;邊緣計算成為AI落地核心場景。AI邊緣計算開發板&#xff08;Edge AI Board&#xff09;作為硬件載體&#xff0c;需滿足??低延遲…

傳輸層協議 1.TCP 2.UDP

傳輸層協議 1.TCP 2.UDP TCP協議 回顧內容 傳輸層功能&#xff1a;定義應用層協議數據報文的端口號&#xff0c;流量控制對原始數據進行分段處理 傳輸層所提供服務 傳輸連接服務數據傳輸服務&#xff1a;流量控制、差錯控制、序列控制 一、傳輸層的TCP協議 1.面向連接的…

LVGL -meter的應用

1 meter介紹 lv_meter 是 LVGL v8 引入的一種圖形控件&#xff0c;用于創建儀表盤樣式的用戶界面元素&#xff0c;它可以模擬像速度表、電壓表、溫度表這類模擬表盤。它通過可視化刻度、指針、顏色弧線等來展示數值信息&#xff0c;是一種非常直觀的數據展示控件。 1.1 核心特…

GoFly企業版框架升級2.6.6版本說明(框架在2025-05-06發布了)

前端框架升級說明&#xff1a; 1.vue版本升級到^3.5.4 把"vue": "^3.2.40",升級到"vue": "^3.5.4"&#xff0c;新版插件需要時useTemplateRef,所以框架就對齊進行升級。 2.ArcoDesign升級到2.57.0&#xff08;目前最新2025-02-10&a…

阿里聯合北大開源數字人項目FantasyTalking,輸出內容更加動態化~

簡介 FantasyTalking 的核心目標是從單一靜態圖像、音頻&#xff08;以及可選的文本提示&#xff09;生成高保真、連貫一致的說話肖像。研究表明&#xff0c;現有方法在生成可動畫化頭像時面臨多重挑戰&#xff0c;包括難以捕捉細微的面部表情、整體身體動作以及動態背景的協調…

基于nnom的多選擇器

核心組件 元件類型目的接口STM32F103CB微控制器主處理單元-MPU60506 軸 IMU移動偵測I2C 接口W25Q64 系列閃存信號和配置存儲SPI 系列按鈕用戶輸入模式選擇和激活GPIO &#xff08;通用輸出&#xff09;搭載了LED用戶反饋系統狀態指示GPIO &#xff08;通用輸出&#xff09;RT6…

Redis中6種緩存更新策略

Redis作為一款高性能的內存數據庫&#xff0c;已經成為緩存層的首選解決方案。然而&#xff0c;使用緩存時最大的挑戰在于保證緩存數據與底層數據源的一致性。緩存更新策略直接影響系統的性能、可靠性和數據一致性&#xff0c;選擇合適的策略至關重要。 本文將介紹Redis中6種緩…

項目優先級頻繁變動,如何應對?

項目優先級頻繁變動是許多公司和團隊在工作中常遇到的挑戰。 這種情況通常由業務需求變化、市場壓力或高層決策調整等因素引起&#xff0c;常常讓團隊成員感到困惑和不安。首先&#xff0c;制定明確的優先級管理框架是應對項目優先級變動的基礎&#xff0c; 通過清晰的優先級排…