SpringBoot使用SpringAI完成簡單智能助手
一、Spring AI 基礎(chǔ)認知
1.1 主流大模型開發(fā)框架對比
Java 領(lǐng)域?qū)崿F(xiàn)大模型(LLM)開發(fā)的兩大核心框架,核心差異如下:
表格
| 框架 | 最低JDK版本 | 核心優(yōu)勢 |
|---|---|---|
| Spring AI | 17 | 深度適配 SpringBoot 生態(tài),自動裝配,開發(fā)成本低 |
| LangChain4J | 8 | 兼容性強,支持低版本 JDK,生態(tài)插件豐富 |
1.2 Spring AI 核心特性
- 完全適配 SpringBoot 自動裝配,提供各主流大模型的 starter 依賴,快速集成;
- 封裝 ChatClient 統(tǒng)一對話 API,支持同步調(diào)用和流式調(diào)用兩種交互方式;
- 基于 Advisor 切面機制實現(xiàn)功能增強,支持會話記憶、日志記錄、RAG 等能力;
- 自動掃描 @Tool 注解實現(xiàn)工具調(diào)用,無需手動注冊;
- 支持自定義 System 系統(tǒng)提示、對話上下文記憶,適配多輪對話場景。
1.3 快速開始
先帶大家快速搭建一個基本功能項目,后面再依次拆分講解
環(huán)境要求
JDK:17 及以上版本(Spring AI 強制要求);
SpringBoot:3.5.9 及以上(本文示例使用 3.5.9);
構(gòu)建工具:Maven;
大模型 URL&API:可通過硅基流動(https://www.siliconflow.cn/) 獲取(支持 DeepSeek、OpenAI 等多模型,需實名認證并獲取 API-Key)。
①創(chuàng)建SpringBoot項目

②引入依賴
首先,在項目pom.xml中添加spring-ai的版本信息:
<properties>
<java.version>17</java.version>
<spring-ai.version>1.0.0-SNAPSHOT</spring-ai.version> <!-- Spring AI 版本 -->
</properties>然后,添加spring-ai的依賴管理項:
<!-- 管理Spring AI 所有依賴版本,避免版本沖突 -->
<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>最后,引入spring-ai-openai 的依賴:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
<version>${spring-ai.version}</version>
</dependency>為了方便后續(xù)開發(fā),我們再手動引入一個Lombok依賴:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>注意: 千萬不要用start.spring.io提供的lombok,有bug??!
完整依賴(復(fù)制注意修改項目信息)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.9</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ai</groupId>
<artifactId>SpringAi</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringAi</name>
<description>SpringAi</description>
<properties>
<java.version>17</java.version>
<spring-ai.version>1.0.0-SNAPSHOT</spring-ai.version>
</properties>
<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>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
<version>${spring-ai.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>③配置模型信息
首先需要使用Ai的對應(yīng)key
介紹一個網(wǎng)站,叫做硅基流動 https://www.siliconflow.cn/,可以從這獲取,當然后面也會介紹其他的模型獲取網(wǎng)站ps:點擊鏈接會默認填寫推薦碼,謝謝大家

無論什么大模型網(wǎng)站我們都需要獲取兩個內(nèi)容
模型請求地址

API key

接下來,我們在配置文件中配置模型的參數(shù)信息。
以 openai 為例,我們將application.properties修改為application.yaml,然后添加下面的內(nèi)容:
spring:
# Spring AI 核心配置
ai:
openai:
api-key: fghjklfghjklsahdjksadasdsadasd # 硅基流動/OpenAI的API-Key(我瞎寫的改成你自己的)
base-url: https://api.siliconflow.cn # 大模型接口地址(硅基流動/OpenAI官方地址)
chat:
options:
model: deepseek-ai/DeepSeek-V3 # 模型名稱(硅基流動/OpenAI模型名,你選擇模型的名字)
temperature: 0.7 # 隨機性(0-1,值越大回答越靈活)
completions-path: /v1/chat/completions # 對話接口路徑(上面截圖API地址)配置項說明:
- api-key:大模型平臺的訪問密鑰,需從硅基流動 / OpenAI 等平臺獲取;
- base-url:大模型的接口根地址,硅基流動為https://api.siliconflow.cn,OpenAI 官方為-https://api.openai.com/v1;
- model:指定調(diào)用的大模型名稱,需與平臺提供的模型名完全一致;
- temperature:回答的隨機性,0 為完全固定回答,1 為最大隨機性,推薦 0.5-0.7;
- completions-path:對話接口的固定路徑,主流大模型均為/v1/chat/completions。
④創(chuàng)建AiChatConfig工具類
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AiChatConfig {
@Resource
//自動裝配OpenAiChatModel:由spring-ai-starter-model-openai自動配置
OpenAiChatModel openAiChatModel;
/**
* 配置 ChatClient - OpenAI兼容的聊天客戶端
* @return ChatClient 實例
*/
@Bean("open-ai")
public ChatClient openAIChatClient() {
return ChatClient.builder(openAiChatModel)
.build();
}
}
⑤創(chuàng)建AiChatController控制類
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RequiredArgsConstructor
@RestController
@RequestMapping("/ai")
public class AiChatController{
private final ChatClient chatClient;
// 請求方式和路徑不要改動,將來要與前端聯(lián)調(diào)
@RequestMapping("/chat")
public String chat(@RequestParam(defaultValue = "介紹一下你自己") String prompt) {
return chatClient
.prompt(prompt) // 傳入用戶提示詞
.call() // 同步請求,會等待AI全部輸出完才返回結(jié)果
.content(); //返回響應(yīng)內(nèi)容
}
}
⑥測試
請求地址:http://localhost:8080/ai/chat

1.4 Spring AI 核心 API
Spring AI 圍繞ChatClient構(gòu)建統(tǒng)一對話入口,核心相關(guān) API 及作用如下:
| 核心 API | 所屬包 | 核心作用 |
|---|---|---|
| ChatClient | org.springframework.ai.chat.client | 大模型對話統(tǒng)一入口,封裝同步 / 流式調(diào)用 |
| ChatClient.Builder | org.springframework.ai.chat.client | 構(gòu)建 ChatClient 實例,配置系統(tǒng)提示、增強器 |
| OpenAiChatModel | org.springframework.ai.openai | OpenAI 兼容的模型實現(xiàn),由 Spring 自動裝配 |
| ChatMemory | org.springframework.ai.chat.memory | 對話記憶接口,存儲多輪對話上下文 |
| MessageWindowChatMemory | org.springframework.ai.chat.memory | ChatMemory 的實現(xiàn)類,基于消息窗口保留上下文 |
| MessageChatMemoryAdvisor | org.springframework.ai.chat.client.advisor | 會話記憶增強器,實現(xiàn)多輪對話上下文關(guān)聯(lián) |
| SimpleLoggerAdvisor | org.springframework.ai.chat.client.advisor | 日志增強器,打印 AI 交互全流程日志 |
| Flux | reactor.core.publisher | 流式返回結(jié)果類型,實現(xiàn)前端實時接收數(shù)據(jù) |
1.5 流式結(jié)果
同步調(diào)用是指等待大模型完整返回結(jié)果后,再將數(shù)據(jù)返回給前端,適用于短文本問答場景,
核心API 為String ChatClient.prompt().call().content()。
快速開始中就是使用同步調(diào)用
流式調(diào)用是指大模型逐字 / 逐段返回結(jié)果,前端實時接收并展示,解決同步調(diào)用 “等待時間長、用戶體驗差” 的問題,核心基于WebFlux實現(xiàn)
核心 API 為Flux<String> ChatClient.prompt().stream().content()。
編寫流式對話接口
在ChatController中添加流式調(diào)用接口chat2:
/**
* 流式對話接口
* @param prompt 用戶提問的提示詞,默認值為“介紹一下你自己”
* @return Flux<String> 流式結(jié)果,前端實時接收
*/
@RequestMapping(value = "/chat2", produces = "text/html;charset=UTF-8")
public Flux<String> chat2(@RequestParam(defaultValue = "介紹一下你自己") String prompt) {
// 流式調(diào)用核心API鏈
return chatClient
.prompt(prompt) // 傳入用戶提示詞
.stream() // 流式調(diào)用:非阻塞,逐段返回結(jié)果
.content(); // 提取流式的純文本內(nèi)容
}
重啟測試,再次訪問,會一點點生成數(shù)據(jù)展示在頁面上。

1.6 系統(tǒng)(角色)設(shè)置
可以發(fā)現(xiàn),當我們詢問AI你是誰的時候,它回答自己是DeepSeek-R1,這是大模型底層的設(shè)定。如果我們希望AI按照新的設(shè)定工作,就需要給它設(shè)置System背景信息。
在SpringAI中,設(shè)置System信息非常方便,不需要在每次發(fā)送時封裝到Message,而是創(chuàng)建ChatClient時指定即可。
用于定義 AI 的角色、回答風(fēng)格、業(yè)務(wù)規(guī)則,無需在每次調(diào)用時重復(fù)傳遞,由 ChatClient 自動附加到 Prompt 中,不同的項目可能需要設(shè)置不同的System信息,所以一般會定義對應(yīng)的類保存。
創(chuàng)建SystemManage系統(tǒng)設(shè)置管理類
/**
* AI服務(wù)System模板管理
* 職責(zé):統(tǒng)一管理所有AI服務(wù)使用的System模板
*/
public class SystemManage {
//提示詞Demo
public static final String DEMO_SYSTEM= """
你是一個專業(yè)的AI智能助手,你的名字叫小艾同學(xué),請以友好、樂于助人和愉快的方式解答各種問題。
重要:當用戶詢問具體信息時,不要編造不存在的數(shù)據(jù)。
""";
}
修改AiChatConfig類
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AiChatConfig {
@Resource
//自動裝配OpenAiChatModel:由spring-ai-starter-model-openai自動配置
OpenAiChatModel openAiChatModel;
/**
* 配置 ChatClient - OpenAI兼容的聊天客戶端
* @return ChatClient 實例
*/
@Bean("open-ai")
public ChatClient openAIChatClient() {
return ChatClient.builder(openAiChatModel)
// 配置系統(tǒng)提示:定義AI的角色、回答風(fēng)格
.defaultSystem(SystemManage.DEMO_SYSTEM)
.build();
}
}
重啟測試,再次訪問,會按照定義的內(nèi)容生成。

1.7 多輪對話上下文
多輪對話的核心是上下文關(guān)聯(lián),即 AI 能識別上一輪的提問和回答,例如:
用戶:12 個蘋果分給 2 個人,每人分幾個?
AI:6 個;
用戶:分給 3 個人呢?
AI:4 個(需識別 “12 個蘋果” 的上下文)。
核心原理
- MessageChatMemoryAdvisor會在每次調(diào)用大模型時,自動從 ChatMemory 中讀取歷史對話消息,并附加到當前 Prompt 中;
- 大模型基于歷史消息 + 當前提問生成回答,實現(xiàn)上下文關(guān)聯(lián);
- 回答生成后,MessageChatMemoryAdvisor會自動將當前用戶消息和 AI 回答存入 ChatMemory,更新上下文。
Spring AI 通過ChatMemory + MessageChatMemoryAdvisor實現(xiàn)該能力,無需額外編寫業(yè)務(wù)代碼,只需在配置類中完成相關(guān) Bean 配置。
Advisor 核心概念
Advisor 是 Spring AI 基于AOP 切面機制實現(xiàn)的功能增強接口,用于在大模型對話的請求前、響應(yīng)后進行無侵入式處理,核心執(zhí)行流程:
用戶請求 → AdvisedRequest(增強前請求)→ Advisor增強(如添加上下文、記錄日志)→ Prompt(最終請求)→ 大模型 → ChatResponse(模型響應(yīng))→ Advisor增強(如存儲上下文)→ AdvisedResponse(增強后響應(yīng))→ 返回給用戶
Advisor API
| Advisor 類名 | 核心作用 | 配置方式 |
|---|---|---|
| MessageChatMemoryAdvisor | 實現(xiàn)多輪對話上下文關(guān)聯(lián),自動讀寫 ChatMemory | MessageChatMemoryAdvisor.builder(chatMemory).build() |
修改AiChatConfig類
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AiChatConfig {
@Resource
//自動裝配OpenAiChatModel:由spring-ai-starter-model-openai自動配置
OpenAiChatModel openAiChatModel;
/**
* 配置 ChatMemory - 內(nèi)存存儲的會話記憶
*
* @return ChatMemory 內(nèi)存存儲的會話記憶實例
*/
@Bean
public ChatMemory chatMemory() {
return MessageWindowChatMemory.builder()
.maxMessages(30) // 窗口最大消息數(shù)目,保留最近30條消息
.build();
}
/**
* 配置 ChatClient - OpenAI兼容的聊天客戶端
* @return ChatClient 實例
*/
@Bean("open-ai")
public ChatClient openAIChatClient() {
return ChatClient.builder(openAiChatModel)
// 配置系統(tǒng)提示:定義AI的角色、回答風(fēng)格
.defaultSystem(SystemManage.DEMO_SYSTEM)
// 配置增強器:會話記憶(多輪對話)
.defaultAdvisors(
//會話記憶增強器,實現(xiàn)多輪對話上下文關(guān)聯(lián)
MessageChatMemoryAdvisor.builder(chatMemory).build(), // 會話記憶增強器
)
.build();
}
}
測試多輪對話
- 第一次訪問:http://localhost:8080/ai/chat?prompt=12個蘋果分給2個人,每人分幾個?
返回:6 個; - 第二次訪問:http://localhost:8080/ai/chat?prompt=分給3個人呢?
返回:4 個(成功識別上下文 “12 個蘋果”)。

1.8 日志集成
默認情況下,應(yīng)用于AI的交互時不記錄日志的,我們無法得知SpringAI組織的提示詞到底長什么樣,有沒有問題。這樣不方便我們調(diào)試。
SpringAI基于AOP機制實現(xiàn)與大模型對話過程的增強、攔截、修改等功能。所有的增強通知都需要實現(xiàn)Advisor接口。

Advisor API
| Advisor 類名 | 核心作用 | 配置方式 |
|---|---|---|
| SimpleLoggerAdvisor | 記錄 AI 交互全流程日志(Prompt、響應(yīng)、Token 等) | new SimpleLoggerAdvisor() |
修改AiChatConfig類
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.MessageWindowChatMemory;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AiChatConfig {
@Resource
//自動裝配OpenAiChatModel:由spring-ai-starter-model-openai自動配置
OpenAiChatModel openAiChatModel;
/**
* 配置 ChatMemory - 內(nèi)存存儲的會話記憶
*
* @return ChatMemory 內(nèi)存存儲的會話記憶實例
*/
@Bean
public ChatMemory chatMemory() {
return MessageWindowChatMemory.builder()
.maxMessages(30) // 窗口最大消息數(shù)目,保留最近30條消息
.build();
}
/**
* 配置 ChatClient - OpenAI兼容的聊天客戶端
* @return ChatClient 實例
*/
@Bean("open-ai")
public ChatClient openAIChatClient() {
return ChatClient.builder(openAiChatModel)
// 配置系統(tǒng)提示:定義AI的角色、回答風(fēng)格
.defaultSystem(SystemManage.DEMO_SYSTEM)
// 配置增強器:會話記憶(多輪對話)+ 日志記錄(調(diào)試)
.defaultAdvisors(
MessageChatMemoryAdvisor.builder(chatMemory).build(), // 會話記憶增強器
new SimpleLoggerAdvisor() // 日志增強器
)
.build();
}
}
修改日志級別
在application.yaml中添加日志配置,更新日志級別:
位置要頂格寫,不要寫在 spring 標簽的下面
logging:
level:
org.springframework.ai: debug # AI對話的日志級別
com.ruangong.springai: debug # 本項目的日志級別重啟項目,再次聊天就能看到AI對話的日志信息了~

1.9 工具調(diào)用
工具調(diào)用是 Spring AI 核心擴展能力之一,允許大模型根據(jù)用戶提問自動判斷并調(diào)用自定義工具(如天氣查詢、數(shù)據(jù)庫操作、計算器等),而非僅依賴模型自身知識回答問題,核心解決 “大模型知識時效性差、無法執(zhí)行實時 / 計算類操作” 的問題。
工具調(diào)用流程

工具調(diào)用常用注解
| 核心組件 | 所屬包 | 注解位置 | 作用 |
|---|---|---|---|
| @Tool | org.springframework.ai.annotation | 方法 | 標記方法為可被 AI 調(diào)用的工具 |
| @ToolParam | org.springframework.ai.annotation | 參數(shù) | 標記被 AI 調(diào)用的工具方法參數(shù) |
定義可被 AI 調(diào)用的工具類
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Component;
/**
* 這里兩個示例工具方法就直接返回字符串,實際項目中可以注入mapper實現(xiàn)數(shù)據(jù)庫查詢
* 工具1:數(shù)學(xué)計算工具
* 工具2:天氣查詢工具
*/
@Component
public class MyTool {
@Tool(
name = "calculator_tool",
description = "執(zhí)行數(shù)學(xué)計算,參數(shù):expression(數(shù)學(xué)表達式,如 10+20*3)",
returnDirect = true
)
public String calculator_tool(@ToolParam(description = "執(zhí)行數(shù)學(xué)計算,如10+20*3等") String expression) {
System.out.println("------------------------------------------數(shù)學(xué)計算-----------------------------------------");
// 簡單計算(實際可使用安全的表達式解析庫,如 JEP)
return "自己拿計算器算去";
}
@Tool(
name = "weather_tool",
description = "查詢指定城市的實時天氣信息,入?yún)ⅲ篶ity(城市名稱,如北京、上海)",
returnDirect = true
)
public String weather_tool(@ToolParam(description = "搜索關(guān)鍵詞,如'北京'、'上海'等") String city) {
System.out.println("------------------------------------------天氣查詢-----------------------------------------");
String weatherInfo = switch (city) {
case "北京" -> "晴,氣溫 18~28℃,西南風(fēng) 2級";
case "上海" -> "多云,氣溫 22~30℃,東南風(fēng) 3級";
case "廣州" -> "小雨,氣溫 25~32℃,東北風(fēng) 1級";
default -> "暫未查詢到「" + city + "」的天氣信息,請確認城市名稱";
};
return weatherInfo;
}
}
修改AiChatConfig類
import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AiChatConfig {
@Resource
//自動裝配OpenAiChatModel:由spring-ai-starter-model-openai自動配置
OpenAiChatModel openAiChatModel;
@Resource
//注入工具函數(shù)所在工具類
MyTool myTool;
/**
* 配置 ChatMemory - 內(nèi)存存儲的會話記憶
*
* @return ChatMemory 內(nèi)存存儲的會話記憶實例
*/
@Bean
public ChatMemory chatMemory() {
return MessageWindowChatMemory.builder()
.maxMessages(30) // 窗口最大消息數(shù)目,保留最近30條消息
.build();
}
/**
* 配置 ChatClient - OpenAI兼容的聊天客戶端
* @return ChatClient 實例
*/
@Bean("open-ai")
public ChatClient openAIChatClient() {
return ChatClient.builder(openAiChatModel)
// 配置系統(tǒng)提示:定義AI的角色、回答風(fēng)格
.defaultSystem(SystemManage.DEMO_SYSTEM)
// 配置增強器:會話記憶(多輪對話)
.defaultAdvisors(
//會話記憶增強器,實現(xiàn)多輪對話上下文關(guān)聯(lián)
MessageChatMemoryAdvisor.builder(chatMemory).build(), // 會話記憶增強器
)
// 配置自定義調(diào)用工具
.defaultTools(myTool)
.build();
}
}
這樣就可以實現(xiàn)工具調(diào)用了,由大模型自動識別調(diào)用,當然為了提高工具調(diào)用的命中率可以修改系統(tǒng)設(shè)置
//提示詞Demo
public static final String TEST_SYSTEM= """
你是一個專業(yè)的AI智能助手,你的名字叫小艾同學(xué),請以友好、樂于助人和愉快的方式解答各種問題。
## 可用工具函數(shù):
當用戶詢問具體信息時,你應(yīng)該**優(yōu)先使用工具函數(shù)**查詢數(shù)據(jù)庫中的實際數(shù)據(jù),而不是憑空回答:
1. **calculator_tool(expression)** - 執(zhí)行數(shù)學(xué)計算
- 用途:當用戶詢問'幫我算'、'幫我計算',如幫我算10+20*3等
- 示例:calculator_tool("10+20*3")
2. **weather_tool(city)** - 查詢指定城市的實時天氣信息
- 用途:當用戶詢問'今天北京天氣怎么樣'、'廣州天氣'等
- 示例:weather_tool("北京")
**重要**:當用戶詢問具體信息時,必須先調(diào)用相應(yīng)工具查詢,然后基于查詢結(jié)果進行回答。不要編造不存在的數(shù)據(jù)。
""";
1.10 前端集成
在瀏覽器通過地址訪問,非常麻煩,也不夠優(yōu)雅。如果能有一個優(yōu)美的前端頁面就好了。
別著急,我提前給大家準備了一個前端頁面。已經(jīng)進行了資源綁定

前端啟動流程
- 刪除node_modules,pakage-lock.json文件
- 執(zhí)行 npm install --registry=https://registry.npmmirror.com
- 執(zhí)行 npm run dev 就可以啟動了
解決CORS問題
前后端在不同域名,存在跨域問題,因此我們需要在服務(wù)端解決cors問題。在 config 包中添加一個類:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MvcConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.exposedHeaders("Content-Disposition");
}
}
重啟服務(wù),如果你的服務(wù)端接口正確,那么應(yīng)該就可以聊天了。
注意: 前端訪問服務(wù)端的默認路徑是:http://localhost:8080
聊天對話的接口是:POST /ai/chat 如果想實現(xiàn)流式對話將后臺請求路徑修改
請確保你的服務(wù)端接口也是這樣。

恭喜您,你的第一個AI對話機器人就簡單完成了。
1.11 會話隔離
在實際項目中,不同用戶會在不同會話進行提問,在上文的多輪對話上下文中,使用MessageChatMemoryAdvisor僅能實現(xiàn)上下文,無法實現(xiàn)會話隔離。
因為所有的請求都使用默認的記憶,所以要實現(xiàn)會話級別的記憶那么久需要為每一個會話都創(chuàng)建一個專屬于會話的"記憶",例如前臺案例請求攜帶的chatId,就是會話的標識
修改ChatController 對應(yīng)方法
/**
* 流式對話接口
* @param prompt 用戶提問的提示詞,默認值為“介紹一下你自己”
* @return Flux<String> 流式結(jié)果,前端實時接收
*/
@RequestMapping(value = "/chat2", produces = "text/html;charset=UTF-8")
public Flux<String> chat2(@RequestParam(defaultValue = "介紹一下你自己") String prompt,String chatId) {
// 流式調(diào)用核心API鏈
return chatClient
.prompt(prompt) // 傳入用戶提示詞
//為當前請求設(shè)置對話記憶(使用默認的會話id標識與前臺生成的chatId)
.advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, chatId))
.stream() // 流式調(diào)用:非阻塞,逐段返回結(jié)果
.content(); // 提取流式的純文本內(nèi)容
}
1.12 前端界面功能簡單實現(xiàn)
多會話切換歷史查詢
頁面在進行會話切換時,會將會話的Id發(fā)送給后臺,獲取信息,所以后臺需要保存對話信息
創(chuàng)建AiChatMessage類,保存對話信息
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* AI聊天消息實體類
* @author system
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
//AI聊天消息實體類
public class AiChatMessage {
//消息ID
private Long id;
//會話ID
private String sessionId;
//角色:user-用戶,assistant-AI助手
private String role;
//消息內(nèi)容")
private String content;
//創(chuàng)建時間
private LocalDateTime createTime;
}
數(shù)據(jù)實際應(yīng)該存儲到數(shù)據(jù)庫,本文使用自定義數(shù)據(jù)類模擬
創(chuàng)建MessageData類,模擬存儲對話數(shù)據(jù)
import java.util.ArrayList;
//保存對話信息工具類,模擬數(shù)據(jù)庫存儲
public class MessageData {
public static ArrayList<AiChatMessage> messages=new ArrayList<>();
public static void addMessage(AiChatMessage message){
messages.add(message);
}
}
修改ChatController類內(nèi)容
/**
* 流式對話接口
* @param prompt 用戶提問的提示詞,默認值為“介紹一下你自己”
* @return Flux<String> 流式結(jié)果,前端實時接收
*/
@RequestMapping(value = "/chat2", produces = "text/html;charset=UTF-8")
public Flux<String> chat2(@RequestParam(defaultValue = "介紹一下你自己") String prompt,String chatId) {
// 流式調(diào)用核心API鏈 獲取結(jié)果
Flux<String> content = chatClient
.prompt(prompt)
.advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, chatId))
.stream() // 流式調(diào)用
.content();
//將用戶信息存儲
MessageData.addMessage(AiChatMessage.builder()
.role(MessageType.USER.getValue())
.content(prompt)
.sessionId(chatId)
.build());
StringBuilder fullResponse = new StringBuilder();
return content.doOnNext(fullResponse::append)
//返回結(jié)束時執(zhí)行
.doOnComplete(() -> {
//獲取會話結(jié)果存儲
MessageData.addMessage(AiChatMessage.builder()
.role(MessageType.ASSISTANT.getValue())
.content(fullResponse.toString())
.sessionId(chatId)
.build());
});
}
@GetMapping("/history/chat/{chatId}")
public List<AiChatMessage> history(@PathVariable String chatId){
//獲取指定會話的歷史信息并返回
return MessageData.messages.stream().filter(msg->msg.getSessionId().equals(chatId)).toList();
}
獲取當前網(wǎng)頁會話下的多個聊天記錄
因為只是一個案例,所以使用session存儲會話id,實際開發(fā)中創(chuàng)建會話可以存儲到數(shù)據(jù)庫中,然后通過數(shù)據(jù)庫查詢返回
修改ChatController類內(nèi)容
/**
* 流式對話接口
* @param prompt 用戶提問的提示詞,默認值為“介紹一下你自己”
* @return Flux<String> 流式結(jié)果,前端實時接收
*/
@RequestMapping(value = "/chat", produces = "text/html;charset=UTF-8")
public Flux<String> chat2(@RequestParam(defaultValue = "介紹一下你自己") String prompt,String chatId,HttpSession session) {
//獲取當前會話中的chatId列表
HashSet<String> sessionIds= ( HashSet<String>) session.getAttribute("sessionIds");
//因為是set集合所以每次請求直接添加即可
sessionIds.add(chatId);
//將最新的chatId列表存入sessin
session.setAttribute("sessionIds",sessionIds);
// 流式調(diào)用核心API鏈 獲取結(jié)果
Flux<String> content = chatClient
.prompt(prompt)
.advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, chatId))
.stream() // 流式調(diào)用
.content();
//將用戶信息存儲
MessageData.addMessage(AiChatMessage.builder()
.role(MessageType.USER.getValue())
.content(prompt)
.sessionId(chatId)
.build());
StringBuilder fullResponse = new StringBuilder();
return content.doOnNext(fullResponse::append)
//返回結(jié)束時執(zhí)行
.doOnComplete(() -> {
//獲取會話結(jié)果存儲
MessageData.addMessage(AiChatMessage.builder()
.role(MessageType.ASSISTANT.getValue())
.content(fullResponse.toString())
.sessionId(chatId)
.build());
});
}
@GetMapping("/history/chat/{chatId}")
public List<AiChatMessage> history(@PathVariable String chatId){
return MessageData.messages.stream().filter(msg->msg.getSessionId().equals(chatId)).toList();
}
/**
* 獲取歷史會話列表方法
* @param session 當前會話對象 自動注入
* @return HashSet<String> 存儲ChatId的集合
*/
@GetMapping("/history/chat")
public HashSet<String> history1(HttpSession session){
System.out.println("----------------------------------------------");
HashSet<String> sessionIds= (HashSet<String>) session.getAttribute("sessionIds");
if(sessionIds==null){
sessionIds=new HashSet<String>();
//加幾個模擬數(shù)據(jù) 要不需要手動點擊
sessionIds.add("1773648154863");
sessionIds.add("1773648154864");
sessionIds.add("1773648154865");
}
return sessionIds;
}
以上就是SpringBoot使用SpringAI完成簡單智能助手的詳細內(nèi)容,更多關(guān)于SpringBoot SpringAI智能助手的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于springboot創(chuàng)建mybatis的完整步驟
MyBatis是一款優(yōu)秀的數(shù)據(jù)庫持久層框架,相比Hibernate我更喜歡使用MyBatis,看的到SQL還是讓人更安心點,這篇文章主要給大家介紹了關(guān)于基于springboot創(chuàng)建mybatis的完整步驟,需要的朋友可以參考下2024-03-03
idea hibernate jpa 生成實體類的實現(xiàn)
這篇文章主要介紹了idea hibernate jpa 生成實體類的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
java靜態(tài)工具類注入service出現(xiàn)NullPointerException異常處理
如果我們要在我們自己封裝的Utils工具類中或者非controller普通類中使用@Autowired注解注入Service或者Mapper接口,直接注入是報錯的,因Utils用了靜態(tài)方法,我們無法直接用非靜態(tài)接口的,遇到這問題,我們要想法解決,下面小編就簡單介紹解決辦法,需要的朋友可參考下2021-09-09
springboot整合nacos的入門Demo及Nacos安裝部署
Nacos?提供了一組簡單易用的特性集,幫助您快速實現(xiàn)動態(tài)服務(wù)發(fā)現(xiàn)、服務(wù)配置、服務(wù)元數(shù)據(jù)及流量管理,Nacos?致力于幫助您發(fā)現(xiàn)、配置和管理微服務(wù),這篇文章主要介紹了springboot整合nacos的入門Demo,需要的朋友可以參考下2024-01-01
Java技能點之SimpleDateFormat進行日期格式化問題
這篇文章主要介紹了Java技能點之SimpleDateFormat進行日期格式化問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04

