Spring AI Alibaba - 聊天機器人快速上手

本節對應 Github:https://github.com/JCodeNest/JCodeNest-AI-Alibaba/tree/master/spring-ai-alibaba-helloworld

本文將以阿里巴巴的通義大模型為例,通過 Spring AI Alibaba 組件,手把手帶你完成從零到一的構建過程:首先,創建一個基礎的智能聊天機器人;然后,為其賦予核心的 “記憶” 能力,讓它能夠理解上下文,進行連貫的多輪對話。

阿里云通義大模型: 這是由阿里云推出的一系列功能強大的語言模型。通過阿里云百煉平臺,Java 仔們可以方便地獲取 API-KEY,從而在自己的應用中調用這些模型,實現文本生成、對話、嵌入等多種 AI 功能。

1. 構建聊天機器人

我們的第一步是構建一個可以進行單次問答的聊天機器人。它能接收用戶的問題,并返回通義模型的回答。

1.1 環境準備

在開始之前,請確保你的開發環境滿足以下要求:

  • JDK 17 或更高版本: Spring AI 基于 Spring Boot 3.x,因此需要 Java 17+。
  • Maven 或 Gradle: 用于項目構建和依賴管理。
  • 阿里云 API-KEY: 訪問并登錄阿里云百煉平臺,創建并獲取一個有效的 API-KEY。

image-20250812215118980

1.2 項目初始化和依賴配置

首先,我們需要在 pom.xml 中引入 spring-ai-alibaba-starter-dashscope 依賴。它會通過 Spring Boot 的自動裝配機制,為我們準備好與通義模型通信所需的核心實例,如 ChatClient。

<!-- 管理 Spring AI Alibaba 的所有依賴版本 -->
<dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-bom</artifactId><version>1.0.0.2</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement><!-- 核心依賴:連接通義大模型 -->
<dependencies><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-dashscope</artifactId></dependency>
</dependencies>

1.3 配置 API-KEY

獲取到 API-KEY 后,最安全和推薦的方式是將其配置為環境變量。Spring AI Alibaba 會自動讀取該變量。

export AI_DASHSCOPE_API_KEY=${替換為你的有效API-KEY}

或者你可以在 application.yml 中進行如下配置:

spring:ai:dashscope:api-key: <替換為你的有效API-KEY>

1.4 編寫核心代碼

接下來,我們創建一個 Controller 來處理用戶的聊天請求。

package cn.jcodenest.ai.hello.controller;import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;/*** 用戶聊天 Controller** @author JCodeNest* @version 1.0.0* @since 2025/8/12* <p>* Copyright (c) 2025 JCodeNest-AI-Alibaba* All rights reserved.*/
@RestController
@RequestMapping("/chat")
public class ChatController {private final ChatClient dashScopeChatClient;/*** 通過構造函數注入 ChatClient.Builder*/public ChatController(ChatClient.Builder chatClientBuilder) {this.dashScopeChatClient = chatClientBuilder// 設置默認的系統級提示詞(System Prompt),為 AI 設定角色和行為準則.defaultSystem("你是一個博學的智能聊天助手,請根據用戶提問,結合上下文進行友好、專業地回答!")// 設置默認的模型參數,如 topP、溫度等.defaultOptions(DashScopeChatOptions.builder()// topP 參數,控制生成文本的多樣性.withTopP(0.8).build()).build();}/*** 簡單問答接口** @param query 用戶問題* @return 模型回答*/@GetMapping("/simple")public String simpleChat(@RequestParam(value = "query", defaultValue = "你好,請介紹一下你自己。") String query) {// 使用 prompt() 方法包裝用戶問題,調用 call().content() 獲取模型回答return dashScopeChatClient.prompt(query).call().content();}/*** 流式響應接口,實現打字機效果** @param query 用戶問題* @return 模型回答流*/@GetMapping("/stream")public Flux<String> streamChat(@RequestParam(value = "query", defaultValue = "請給我講一個關于程序員的笑話") String query) {// 調用 stream().content() 返回一個 Flux<String> 對象return dashScopeChatClient.prompt(query).stream().content();}
}

代碼剖析

  1. 我們通過構造函數注入了 ChatClient.Builder,這是一個工廠類,用于以鏈式調用的方式構建和配置 ChatClient 實例。
  2. defaultSystem(): 設置一個系統級的提示詞,這對于定義 AI 的角色和行為至關重要。
  3. defaultOptions(): 配置與模型交互時的默認參數。DashScopeChatOptions 提供了豐富的配置項。這些參數也可以在每次調用時動態指定,靈活性非常高。
  4. simpleChat(): 這是最基礎的調用方式,一次性返回完整的模型響應。
  5. streamChat(): 通過返回 Flux<String>,實現了流式響應。這在前端可以輕松實現 “打字機” 的實時顯示效果,極大地提升了用戶體驗。

上述簡單聊天的完整流程:

用戶Spring應用 (Controller)Spring AI ChatClient阿里云通義大模型GET /chat/simple?query=....prompt(query).call()構造并發送 API 請求返回模型生成的完整回答返回內容字符串HTTP 200 OK (響應體為回答)用戶Spring應用 (Controller)Spring AI ChatClient阿里云通義大模型

基礎調用測試結果如下:

image-20250812211602488

流式調用測試結果如下:

image-20250812211544572

2. 為你的機器人賦予記憶

上面的機器人雖然能回答問題,但它是 “健忘” 的。你問它第二個問題時,它完全不記得第一個問題是什么。為了實現真正的對話,我們必須為它增加記憶能力。

例如,當你再問他前面的信息時,他就忘記了:

image-20250812211726599

2.1 為什么需要記憶?

HTTP 協議本身是無狀態的,LLM 的 API 調用在默認情況下也是如此。每一次請求都是獨立的,模型不會保留之前的對話信息。要讓對話持續下去,我們必須在每次請求時,將之前的聊天記錄一并發送給模型。

雖然可以手動在代碼中維護一個對話歷史列表,但這會迅速增加代碼的復雜性和維護成本。幸運的是,Spring AI 提供了優雅的解決方案——Chat Memory

2.2 Spring AI 的記憶解決方案

Spring AI 通過 ChatMemory 接口和 Advisor(AOP 中的 “通知”)設計模式來解決記憶問題。Advisor 可以在 ChatClient 調用前后執行額外的邏輯,例如:

  • 調用前: 從存儲中加載歷史對話記錄,并將其添加到當前的請求中。
  • 調用后: 將本次新的問答對(用戶問題和模型回答)保存到存儲中。

Spring AI Alibaba 提供了多種開箱即用的記憶存儲方案,如 jdbc, redis, elasticsearch。下面我們以最通用的 JDBC (使用 MySQL) 為例進行演示。

2.3 使用 JDBC 持久化記憶

在 pom.xml 中追加 jdbc-memory 和 mysql 驅動的依賴。

<dependencies><!-- Spring AI JDBC 記憶組件 --><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-memory-jdbc</artifactId></dependency><!-- MySQL 數據庫驅動 --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency>
</dependencies>

在 application.yaml 文件中配置數據庫連接信息。

spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/your_database?useUnicode=true&characterEncoding=UTF-8username: your_usernamepassword: your_password# 建議開啟,讓 Hibernate 自動創建或更新表結構jpa:hibernate:ddl-auto: update

注意: JdbcChatMemoryRepository 在應用啟動時會自動檢測并創建名為 ai_chat_memory 的數據表,用于存儲對話記錄。確保你的數據庫用戶有 DDL 權限,或提前手動建表。

create table ai_chat_memory
(id                         bigint auto_increment  primary key,conversation_id  varchar(256) not null,content                longtext     not null,type                    varchar(100) not null,timestamp          timestamp    not null,constraint chk_message_type  check (`type` in ('USER', 'ASSISTANT', 'SYSTEM', 'TOOL'))
);

現在,我們來改造 ChatController,為其注入記憶能力。

@RestController
@RequestMapping("/chat")
public class ChatController {private final ChatClient dashScopeChatClient;// 注入 JdbcTemplate 用于數據庫操作public ChatController(JdbcTemplate jdbcTemplate, ChatClient.Builder chatClientBuilder) {// 1. 構造基于 JDBC 的 ChatMemoryRepositoryChatMemoryRepository chatMemoryRepository = MysqlChatMemoryRepository.mysqlBuilder().jdbcTemplate(jdbcTemplate).build();// 2. 構造一個窗口化的 ChatMemory,它使用上面的 RepositoryChatMemory chatMemory = MessageWindowChatMemory.builder().chatMemoryRepository(chatMemoryRepository).build();// 3. 將 ChatMemory 包裝成一個 Advisor,并注冊到 ChatClientthis.dashScopeChatClient = chatClientBuilder.defaultSystem("你是一個博學的智能聊天助手,請根據用戶提問,結合上下文進行友好、專業地回答!")// 關鍵:注冊 MessageChatMemoryAdvisor.defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build()).defaultOptions(DashScopeChatOptions.builder().withTopP(0.8).build()).build();}/*** 帶有記憶的聊天接口* @param chatId 用于區分不同對話的會話 ID*/@GetMapping("/memory")public String memoryChat(@RequestParam String query,@RequestParam(defaultValue = "default-chat-001") String chatId) {return dashScopeChatClient.prompt(query)// 關鍵:在每次調用時,通過 Advisor 參數傳遞當前的會話 ID.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, chatId)).call().content();}
}

代碼剖析

  1. 我們首先構造了一個 MysqlChatMemoryRepository,它是 ChatMemoryRepository 針對 MySQL 的具體實現。
  2. 然后,我們創建了一個 MessageWindowChatMemory 實例,它是一種常見的對話記憶策略(例如,只保留最近 N 輪對話)。
  3. 最核心的一步,是將 chatMemory 包裝進 MessageChatMemoryAdvisor,并通過 .defaultAdvisors() 方法將其注冊到 ChatClient 中。從此,這個 ChatClient 的所有調用都會經過記憶處理。
  4. memoryChat 方法中,我們增加了一個 chatId 參數。這個 ID 是區分不同用戶或不同對話的關鍵。我們通過 .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, chatId)) 將其傳遞給記憶顧問,以便它能為正確的會話加載和保存歷史記錄。

增加記憶功能后,系統的內部工作流程如下:

用戶Spring應用 (Controller)Spring AI ChatClientMessageChatMemoryAdvisorJDBC RepositoryMySQL數據庫阿里云通義大模型GET /chat/memory?query=...&chatId=123.prompt(query).advisors(chatId).call()調用前,觸發 Advisor執行 Before-call 邏輯加載 chatId='1234' 的歷史記錄SELECT * FROM ai_chat_memory WHERE ...返回歷史消息獲得歷史記錄將歷史記錄預置到 Prompt 中發送包含完整上下文的 API 請求返回基于上下文的回答調用后,再次觸發 Advisor執行 After-call 邏輯保存本次新的問答對 (for chatId='1234')INSERT INTO chat_memory ...返回最終內容HTTP 200 OK (響應體為回答)用戶Spring應用 (Controller)Spring AI ChatClientMessageChatMemoryAdvisorJDBC RepositoryMySQL數據庫阿里云通義大模型

現在,你可以連續調用 /chat/memory 接口,使用相同的 chatId,機器人將能夠記住你們之前的對話內容,實現連貫的交流。

第一個問題:請記住,當我問你 “我是誰” 的時候,你只需要答復我,你是 JCode。

image-20250812214044636

此時,可以觀察到我們的對話對信息(USER + ASSISTANT)已經持久化到數據庫了:

image-20250812214122960

第二個問題:我是誰?

image-20250812214223768

可見,LLM 確實實現了 “記住” 的效果,再觀察 ai_chat_memory,新的對話對同樣被添加進來了:

image-20250812214316061

3. 總結

可以看到,我們使用 Spring AI Alibaba 構建一個簡單的智能聊天機器人就是這么簡單。我們從一個簡單的問答服務開始,然后通過 Spring AI 強大且易于擴展的 AdvisorChatMemory 機制,為其無縫集成了持久化的對話記憶能力。

這僅僅是 Spring AI 世界的冰山一角。基于這套框架,你還可以進一步探索更高級的功能,例如:

  • RAG (Retrieval-Augmented Generation): 結合向量數據庫,讓機器人能根據你自己的私有知識庫回答問題。
  • Function Calling: 允許 AI 模型調用你定義的 Java 方法,實現與外部工具和服務的交互。
  • 多模態能力: 處理和生成圖像等非文本內容。

通過 Spring AI 的抽象設計理念,Java 仔們可以聚焦于業務邏輯創新,而不必深陷于與不同 AI 模型底層 API 對接的泥潭。

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

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

相關文章

串口通信學習

不需要校驗位就選8位&#xff0c;需要校驗位就選9位&#xff01;USRTUSART框圖STM32的外設引腳這是USART的基本結構。數據幀&#xff0c;八位是這個公式還是很重要的&#xff01;如果在編輯器里面使用printf打印漢字的話&#xff0c;會出現亂碼的話&#xff0c;前提是你的編碼格…

面試經典150題[001]:合并兩個有序數組(LeetCode 88)

合并兩個有序數組&#xff08;LeetCode 88&#xff09; https://leetcode.cn/problems/merge-sorted-array/?envTypestudy-plan-v2&envIdtop-interview-150 1. 題目背景 你有兩個已經排好序的數組&#xff1a; nums1&#xff1a;前面是有效數字&#xff0c;后面是空位&…

快速安裝達夢8測試庫

計劃&#xff1a;數據庫名實例名PORT_NUMMAL_INST_DW_PORTMAL_HOSTMAL_PORTMAL_DW_PORTDMDWDBINST_1533615101192.168.207.612510135101*****[2025-08-11 15:14:34]***** Last login: Fri Jul 25 17:36:04 2025 from 192.168.88.48 [rootdm01 ~]# ip a 1: lo: <LOOPBACK,UP,…

Hive中優化問題

一、小文件合并優化Hive中的小文件分為Map端的小文件和Reduce端的小文件。(1)、Map端的小文件優化是通過CombineHiveInputFormat操作。相關的參數是&#xff1a;set hive.input.formatorg.apache.hadoop.hive.ql.io.CombineHiveInputFormat;(2)、Reduce端的小文件合并Map端的小…

tlias智能學習輔助系統--Maven高級-繼承

目錄 一、打包方式與應用場景 二、父子工程繼承關系 1. 父工程配置 2. 子工程配置 三、自定義屬性與引用屬性 1. 定義屬性 2. 在 dependencyManagement 中引用 3. 子工程中引用 四、dependencyManagement 與 dependencies 的區別 五、項目結構示例 六、小結 在實際開…

把 AI 押進“小黑屋”——基于 LLM 的隱私對話沙盒設計與落地

標簽&#xff1a;隱私計算、可信執行環境、LLM、沙盒、內存加密、TEE、SGX、Gramine ---- 1. 背景&#xff1a;甲方爸爸一句話&#xff0c;“數據不能出機房” 我們給某三甲醫院做智能問診助手&#xff0c;模型 70 B、知識庫 300 GB。 甲方只給了兩條鐵律&#xff1a; 1. 患者…

Java 大視界 -- Java 大數據在智能教育學習效果評估指標體系構建與精準評估中的應用(394)

Java 大視界 -- Java 大數據在智能教育學習效果評估指標體系構建與精準評估中的應用&#xff08;394&#xff09;引言&#xff1a;正文&#xff1a;一、傳統學習評估的 “數字陷阱”&#xff1a;看不全、說不清、跟不上1.1 評估維度的 “單行道”1.1.1 分數掩蓋的 “學習真相”…

Dubbo 3.x源碼(33)—Dubbo Consumer接收服務調用響應

基于Dubbo 3.1&#xff0c;詳細介紹了Dubbo Consumer接收服務調用響應 此前我們學習了Dubbo Provider處理服務調用請求的流程&#xff0c;現在我們來學習Dubbo Consumer接收服務調用響應流程。 實際上接收請求和接收響應同屬于接收消息&#xff0c;它們的流程的很多步驟是一樣…

棧和隊列:數據結構中的基礎與應用?

棧和隊列&#xff1a;數據結構中的基礎與應用在計算機科學的領域中&#xff0c;數據結構猶如大廈的基石&#xff0c;支撐著各類復雜軟件系統的構建。而棧和隊列作為兩種基礎且重要的數據結構&#xff0c;以其獨特的特性和廣泛的應用&#xff0c;在程序設計的舞臺上扮演著不可或…

服務端配置 CORS解決跨域問題的原理

服務端配置 CORS&#xff08;跨域資源共享&#xff09;的原理本質是 瀏覽器與服務器之間的安全協商機制。其核心在于服務器通過特定的 HTTP 響應頭聲明允許哪些外部源&#xff08;Origin&#xff09;訪問資源&#xff0c;瀏覽器根據這些響應頭決定是否放行跨域請求。以下是詳細…

Unity筆記(五)知識補充——場景切換、退出游戲、鼠標隱藏鎖定、隨機數、委托

寫在前面&#xff1a;寫本系列(自用)的目的是回顧已經學過的知識、記錄新學習的知識或是記錄心得理解&#xff0c;方便自己以后快速復習&#xff0c;減少遺忘。主要是C#代碼部分。十七、場景切換和退出游戲1、場景切換場景切換使用方法&#xff1a; SceneManager.LoadScene()&a…

用 Spring 思維快速上手 DDD——以 Kratos 為例的分層解讀

用 Spring 思維理解 DDD —— 以 Kratos 為參照 ? 在此前的學習工作中&#xff0c;使用的開發框架一直都是 SpringBoot&#xff0c;對 MVC 架構幾乎是肌肉記憶&#xff1a;Controller 接請求&#xff0c;Service 寫業務邏輯&#xff0c;Mapper 操作數據庫&#xff0c;這套套路…

docspace|Linux|使用docker完全離線化部署onlyoffice之docspace文檔協作系統(全網首發)

一、 前言 書接上回&#xff0c;Linux|實用工具|onlyoffice workspace使用docker快速部署&#xff08;離線和定制化部署&#xff09;-CSDN博客&#xff0c;如果是小公司或者比如某個項目組內部使用&#xff0c;那么&#xff0c;使用docspace這個文檔協同系統是非常合適的&…

【教程】如何高效提取胡蘿卜塊根形態和顏色特征?

胡蘿卜是全球不可或缺的健康食材和重要的經濟作物&#xff0c; 從田間到餐桌&#xff0c;從鮮食到深加工&#xff0c;胡蘿卜在現代人的飲食和健康中扮演著極其重要的角色&#xff0c;通過量化塊根形態和色澤均勻性&#xff0c;可實現對高產優質胡蘿卜品種的快速篩選。工具/材料…

Python初學者筆記第二十四期 -- (面向對象編程)

第33節課 面向對象編程 1. 面向對象編程基礎 1.1 什么是面向對象編程面向過程&#xff1a;執行者 耗時 費力 結果也不一定完美 面向對象&#xff1a;指揮者 省時 省力 結果比較完美面向對象編程(Object-Oriented Programming, OOP)是一種編程范式&#xff0c;它使用"對象&…

Go 語言 里 `var`、`make`、`new`、`:=` 的區別

把 Go 語言 里 var、make、new、: 的區別徹底梳理一下。1?? var 作用&#xff1a;聲明變量&#xff08;可以帶初始值&#xff0c;也可以不帶&#xff09;。語法&#xff1a; var a int // 聲明整型變量&#xff0c;默認值為 0 var b string // 默認值 ""…

計算機網絡---IP(互聯網協議)

一、IP協議概述 互聯網協議&#xff08;Internet Protocol&#xff0c;IP&#xff09;是TCP/IP協議族的核心成員&#xff0c;位于OSI模型的網絡層&#xff08;第三層&#xff09;&#xff0c;負責將數據包從源主機傳輸到目標主機。它是一種無連接、不可靠的協議&#xff0c;提供…

DataFun聯合開源AllData社區和開源Gravitino社區將在8月9日相聚數據治理峰會論壇

&#x1f525;&#x1f525; AllData大數據產品是可定義數據中臺&#xff0c;以數據平臺為底座&#xff0c;以數據中臺為橋梁&#xff0c;以機器學習平臺為中層框架&#xff0c;以大模型應用為上游產品&#xff0c;提供全鏈路數字化解決方案。 ?杭州奧零數據科技官網&#xff…

【工具】通用文檔轉換器 推薦 Markdown 轉為 Word 或者 Pdf格式 可以批量或者通過代碼調用

【工具】通用文檔轉換器 推薦 可以批量或者通過代碼調用 通用文檔轉換器 https://github.com/jgm/pandoc/ Pandoc - index 下載地址 https://github.com/jgm/pandoc/releases 使用方法: 比如 Markdown 轉為 Word 或者 Pdf格式 pandoc -s MANUAL.txt -o example29.docx …

【UEFI系列】Super IO

文章目錄一、什么是Super IO二、Super IO的作用常見廠商三、邏輯設備控制如何訪問SIO邏輯設備的配置寄存器具體配置數值四、硬件監控&#xff08;hardware monitor&#xff09;一、什么是Super IO Super Input/Output超級輸入輸出控制器。 通過LPC&#xff08;low pin count&a…