最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot使用SpringAI完成簡單智能助手

 更新時間:2026年03月21日 14:50:48   作者:Amour戀空  
本文詳解如何在Spring?Boot?3.5.9+環(huán)境中集成Spring?AI框架,實現(xiàn)基于大模型的智能對話助手,涵蓋環(huán)境配置、依賴引入、模型接入(如OpenAI/SiliconFlow)、ChatClient統(tǒng)一API調(diào)用、流式響應(yīng)、System角色設(shè)定、多輪對話上下文管理等核心技術(shù)點,需要的朋友可以參考下

一、Spring AI 基礎(chǔ)認知

1.1 主流大模型開發(fā)框架對比

Java 領(lǐng)域?qū)崿F(xiàn)大模型(LLM)開發(fā)的兩大核心框架,核心差異如下:

表格

框架最低JDK版本核心優(yōu)勢
Spring AI17深度適配 SpringBoot 生態(tài),自動裝配,開發(fā)成本低
LangChain4J 8兼容性強,支持低版本 JDK,生態(tài)插件豐富

1.2 Spring AI 核心特性

  1. 完全適配 SpringBoot 自動裝配,提供各主流大模型的 starter 依賴,快速集成;
  2. 封裝 ChatClient 統(tǒng)一對話 API,支持同步調(diào)用和流式調(diào)用兩種交互方式;
  3. 基于 Advisor 切面機制實現(xiàn)功能增強,支持會話記憶、日志記錄、RAG 等能力;
  4. 自動掃描 @Tool 注解實現(xiàn)工具調(diào)用,無需手動注冊;
  5. 支持自定義 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所屬包核心作用
ChatClientorg.springframework.ai.chat.client大模型對話統(tǒng)一入口,封裝同步 / 流式調(diào)用
ChatClient.Builderorg.springframework.ai.chat.client構(gòu)建 ChatClient 實例,配置系統(tǒng)提示、增強器
OpenAiChatModelorg.springframework.ai.openaiOpenAI 兼容的模型實現(xiàn),由 Spring 自動裝配
ChatMemoryorg.springframework.ai.chat.memory對話記憶接口,存儲多輪對話上下文
MessageWindowChatMemoryorg.springframework.ai.chat.memoryChatMemory 的實現(xiàn)類,基于消息窗口保留上下文
MessageChatMemoryAdvisororg.springframework.ai.chat.client.advisor會話記憶增強器,實現(xiàn)多輪對話上下文關(guān)聯(lián)
SimpleLoggerAdvisororg.springframework.ai.chat.client.advisor日志增強器,打印 AI 交互全流程日志
Fluxreactor.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 個蘋果” 的上下文)。

核心原理

  1. MessageChatMemoryAdvisor會在每次調(diào)用大模型時,自動從 ChatMemory 中讀取歷史對話消息,并附加到當前 Prompt 中;
  2. 大模型基于歷史消息 + 當前提問生成回答,實現(xiàn)上下文關(guān)聯(lián);
  3. 回答生成后,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),自動讀寫 ChatMemoryMessageChatMemoryAdvisor.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)用常用注解

核心組件所屬包注解位置作用
@Toolorg.springframework.ai.annotation方法標記方法為可被 AI 調(diào)用的工具
@ToolParamorg.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)文章

  • 使用java實現(xiàn)手機短信驗證全過程

    使用java實現(xiàn)手機短信驗證全過程

    這篇文章主要介紹了使用java實現(xiàn)手機短信驗證全過程,文中有非常詳細的代碼示例,對正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • SpringBoot整合模板引擎過程代碼實例

    SpringBoot整合模板引擎過程代碼實例

    這篇文章主要介紹了SpringBoot整合模板引擎過程代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-07-07
  • 基于springboot創(chuàng)建mybatis的完整步驟

    基于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)

    這篇文章主要介紹了idea hibernate jpa 生成實體類的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • maven打包如何指定jdk的版本

    maven打包如何指定jdk的版本

    這篇文章主要介紹了maven打包如何指定jdk的版本問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • mybatis使用xml進行增刪改查代碼解析

    mybatis使用xml進行增刪改查代碼解析

    這篇文章主要介紹了mybatis使用xml進行增刪改查代碼解析,分享了相關(guān)配置和代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-02-02
  • Shiro在springboot中快速實現(xiàn)方法

    Shiro在springboot中快速實現(xiàn)方法

    Apache Shiro是一個Java的安全(權(quán)限)框架,可以容易的開發(fā)出足夠好的應(yīng)用,既可以在JavaEE中使用,也可以在JavaSE中使用,這篇文章主要介紹了Shiro在springboot中快速實現(xiàn),需要的朋友可以參考下
    2023-02-02
  • java靜態(tài)工具類注入service出現(xiàn)NullPointerException異常處理

    java靜態(tài)工具類注入service出現(xiàn)NullPointerException異常處理

    如果我們要在我們自己封裝的Utils工具類中或者非controller普通類中使用@Autowired注解注入Service或者Mapper接口,直接注入是報錯的,因Utils用了靜態(tài)方法,我們無法直接用非靜態(tài)接口的,遇到這問題,我們要想法解決,下面小編就簡單介紹解決辦法,需要的朋友可參考下
    2021-09-09
  • springboot整合nacos的入門Demo及Nacos安裝部署

    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進行日期格式化問題

    這篇文章主要介紹了Java技能點之SimpleDateFormat進行日期格式化問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04

最新評論

西丰县| 青岛市| 郧西县| 平安县| 盐池县| 永平县| 翁牛特旗| 行唐县| 新野县| 万州区| 南京市| 勃利县| 沭阳县| 杨浦区| 萍乡市| 嵊州市| 依兰县| 迁安市| 库伦旗| 渝北区| 德州市| 黄平县| 商水县| 成武县| 平山县| 梓潼县| 江口县| 鹤峰县| 集贤县| 惠东县| 积石山| 雷山县| 金平| 安阳市| 临洮县| 九江县| 曲沃县| 四川省| 东乌| 闽清县| 宜章县|