【Spring AI快速上手 (二)】Advisor实现对话上下文管理

发布于:2025-08-05 ⋅ 阅读:(18) ⋅ 点赞:(0)

一、前言

二、Advisor实现对话上下文管理

        pom.xml

        application.properties

        schema-mysql.sql

        application.yml

         自定义记忆实现

        Redis实现记忆功能

        Mysql实现记忆功能

        Advisor 测试代码


一、前言

 Spring AI详解:【Spring AI详解】开启Java生态的智能应用开发新时代(附不同功能的Spring AI实战项目)-CSDN博客

二、Advisor实现对话上下文管理

pom.xml

Spring AI的上下文管理功能需要依赖多个核心组件:

基础依赖:包括Spring Boot Web、测试等基础框架支持

AI模型集成:阿里云百炼、DeepSeek等大模型接入能力

记忆管理核心:提供ChatMemory接口和基础实现

持久化存储:JDBC和Redis两种存储方案实现

<properties>
    <!-- 设置Java版本为17,Spring AI推荐使用Java 17+ -->
    <java.version>17</java.version>
    <!-- 指定Jedis客户端版本 -->
    <jedis.version>5.2.0</jedis.version>
</properties>

<!-- 依赖管理配置(BOM模式) -->
<dependencyManagement>
    <dependencies>
        <!-- 1. Spring AI Alibaba BOM -->
        <!-- 功能:管理阿里云AI生态组件的版本(如Dashscope、百炼平台集成等) -->
        <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>

        <!-- 2. Spring AI BOM -->
        <!-- 功能:管理Spring AI核心模块版本(ChatClient、RAG、工具调用等) -->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>1.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <!-- 3. Spring Boot BOM -->
        <!-- 功能:管理Spring Boot及其starter组件的版本 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.2.5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <!-- 阿里云百炼AI模型集成 -->
    <dependency>
        <groupId>com.alibaba.cloud.ai</groupId>
        <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
    </dependency>

    <!-- Spring AI 聊天记忆自动配置 (核心) -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-autoconfigure-model-chat-memory</artifactId>
        <!--
          基础记忆功能支持:
          - ChatMemory接口自动配置
          - MessageWindowChatMemory实现
          - 记忆管理基础架构
        -->
    </dependency>

    <!-- JDBC记忆存储实现 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-model-chat-memory-repository-jdbc</artifactId>
        <!--
          基于数据库的记忆持久化:
          - 自动创建记忆存储表
          - 支持主流关系型数据库
          - 需要配合spring-boot-starter-jdbc使用
        -->
    </dependency>

    <!-- JDBC核心支持 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>

    <!-- MySQL驱动 -->
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </dependency>

    <!-- 阿里云Redis记忆存储 -->
    <dependency>
        <groupId>com.alibaba.cloud.ai</groupId>
        <artifactId>spring-ai-alibaba-starter-memory-redis</artifactId>
        <!--
          基于Redis的高性能记忆存储:
          - 支持Redis单机/集群模式
          - 自动序列化/反序列化
          - 需要配合Jedis客户端
        -->
    </dependency>

    <!-- Jedis Redis客户端 -->
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>${jedis.version}</version>
    </dependency>

    <!-- Spring Boot Web支持 -->
    <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>
</dependencies>

application.properties

配置文件定义了应用的基础设置和记忆存储参数:

应用基础配置:应用名称、日志级别等

AI服务配置:API密钥、模型选择等

记忆存储配置:JDBC初始化策略、Schema文件位置等

# 应用基础配置
spring.application.name=chat-client

# 阿里云百炼AI配置
spring.ai.dashscope.api-key=${ALI_AI_KEY}
# spring.ai.dashscope.chat.options.model=qwen-plus

# 日志级别配置
# 开启SimpleLoggerAdvisor的DEBUG日志
logging.level.org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor=DEBUG

# JDBC记忆存储初始化配置
# 启动时自动初始化数据库Schema,可选值:
# always - 总是初始化
# never - 不初始化(需手动建表)
# embedded - 仅嵌入式数据库初始化
spring.ai.chat.memory.repository.jdbc.initialize-schema=always

# 指定自定义的Schema初始化SQL文件路径
# 文件内容应包含创建CHAT_MEMORY表的DDL语句
spring.ai.chat.memory.repository.jdbc.schema=classpath:/sql/schema-mysql.sql

schema-mysql.sql

定义了记忆存储的数据库表结构,包含对话ID、内容、类型和时间戳等核心字段

CREATE TABLE IF NOT EXISTS SPRING_AI_CHAT_MEMORY (
    `conversation_id` VARCHAR(36) NOT NULL,
    `content` TEXT NOT NULL,
    `type` VARCHAR(10) NOT NULL,
    `timestamp` TIMESTAMP NOT NULL,

    INDEX `SPRING_AI_CHAT_MEMORY_CONVERSATION_ID_TIMESTAMP_IDX` (`conversation_id`, `timestamp`)
    );

application.yml

配置数据源和Redis连接信息

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/springai?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&
    driver-class-name: com.mysql.cj.jdbc.Driver
  ai:
    memory:
      redis:
        host: localhost
        port: 6379
        timeout:  5000
        password:

 自定义记忆实现

演示了最简单的上下文管理实现方式 - 手动拼接对话历史

后续交互将历史对话拼接后作为上下文

使用Spring AI提供的标准记忆实现,创建MessageWindowChatMemory

import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.ChatMemoryRepository;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;

@SpringBootTest
public class TestMemory {

    /**
     * 测试基础记忆功能 - 手动拼接对话历史
     * 演示如何通过字符串拼接实现简单记忆
     *
     * @param chatModel 自动注入的DashScope聊天模型
     */
    @Test
    public void testMemory(@Autowired DashScopeChatModel chatModel) {
        // 1. 创建基础ChatClient
        ChatClient chatClient = ChatClient.builder(chatModel).build();

        // 2. 第一次交互
        String chatHis = "我叫小小";
        String content = chatClient.prompt()
                .user(chatHis)
                .call()
                .content();
        System.out.println(content);
        System.out.println("----------------------------------");

        // 3. 第二次交互(手动拼接历史)
        chatHis += content;
        chatHis += "我叫什么?";
        content = chatClient.prompt()
                .user(chatHis) // 包含完整对话历史
                .call()
                .content();
        System.out.println(content);
    }

    /**
     * 测试ChatMemory实现 - 使用MessageWindowChatMemory
     * 演示Spring AI提供的标准记忆实现
     *
     * @param chatModel 自动注入的DashScope聊天模型
     */
    @Test
    public void testMemory2(@Autowired DashScopeChatModel chatModel) {
        // 1. 创建记忆组件(窗口大小默认为10)
        ChatMemory chatMemory = MessageWindowChatMemory.builder().build();
        String conversationId = "xx001"; // 对话唯一标识

        // 2. 第一次交互
        UserMessage userMessage1 = new UserMessage("我叫小小");
        chatMemory.add(conversationId, userMessage1); // 添加用户消息到记忆
        ChatResponse response1 = chatModel.call(new Prompt(chatMemory.get(conversationId)));
        chatMemory.add(conversationId, response1.getResult().getOutput()); // 添加AI响应到记忆

        // 3. 第二次交互
        UserMessage userMessage2 = new UserMessage("我叫什么?");
        chatMemory.add(conversationId, userMessage2);
        ChatResponse response2 = chatModel.call(new Prompt(chatMemory.get(conversationId)));
        chatMemory.add(conversationId, response2.getResult().getOutput());
        System.out.println(response2.getResult().getOutput().getText()); // 打印AI响应
    }

    // 共享的ChatClient实例
    ChatClient chatClient;

    /**
     * 初始化方法 - 配置带记忆顾问的ChatClient
     */
    @BeforeEach
    public void init(@Autowired ChatClient.Builder builder,
                     @Autowired ChatMemory chatMemory) {
        // 创建带记忆顾问的ChatClient
        this.chatClient = builder
                .defaultAdvisors(
                        PromptChatMemoryAdvisor.builder(chatMemory).build() // 添加记忆顾问
                )
                .build();
    }

    /**
     * 测试记忆顾问 - PromptChatMemoryAdvisor
     * 演示如何通过顾问自动管理对话历史
     */
    @Test
    public void testMemoryAdvisor(@Autowired ChatMemory chatMemory) {
        // 1. 第一次交互
        String content = chatClient.prompt()
                .user("我叫小小")
                .call()
                .content();
        System.out.println(content);
        System.out.println("----------------------------------");

        // 2. 第二次交互(自动使用记忆)
        content = chatClient.prompt()
                .user("我叫什么?")
                .call()
                .content();
        System.out.println(content);
    }

    /**
     * 测试配置类 - 自定义记忆实现
     */
    @TestConfiguration
    static class Config {
        /**
         * 配置消息窗口记忆
         * @param chatMemoryRepository 记忆存储库
         * @return 配置好的ChatMemory实例
         */
        @Bean
        ChatMemory chatMemory(ChatMemoryRepository chatMemoryRepository) {
            return MessageWindowChatMemory
                    .builder()
                    .maxMessages(1) // 只保留最近1条消息
                    .chatMemoryRepository(chatMemoryRepository)
                    .build();
        }
    }

    /**
     * 测试对话ID选项 - 多会话记忆隔离
     * 演示如何通过不同对话ID隔离记忆
     */
    @Test
    public void testChatOptions() {
        // 会话1 - 第一次交互
        String content = chatClient.prompt()
                .user("我叫小小")
                .advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, "1"))
                .call()
                .content();
        System.out.println(content);
        System.out.println("----------------------------------");

        // 会话1 - 第二次交互(有记忆)
        content = chatClient.prompt()
                .user("我叫什么?")
                .advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, "1"))
                .call()
                .content();
        System.out.println(content);

        System.out.println("----------------------------------");

        // 会话2 - 新会话(无记忆)
        content = chatClient.prompt()
                .user("我叫什么?")
                .advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, "2"))
                .call()
                .content();
        System.out.println(content);
    }
}

Redis实现记忆功能

Redis基于内存的高性能记忆存储方案

 核心依赖配置

 需要添加spring-ai-alibaba-starter-memory-redis依赖和Jedis客户端依赖

 配置Redis连接参数:主机、端口、超时时间和密码等 

import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import com.alibaba.cloud.ai.memory.redis.RedisChatMemoryRepository;
import com.xushu.springai.cc.ReReadingAdvisor;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@SpringBootTest
public class TestRedisMemory {

    // 共享的ChatClient实例
    ChatClient chatClient;

    /**
     * 初始化方法 - 配置带Redis记忆的ChatClient
     * @param chatModel 自动注入的DashScope聊天模型
     * @param chatMemory 自动注入的ChatMemory实例
     */
    @BeforeEach
    public void init(@Autowired DashScopeChatModel chatModel,
                     @Autowired ChatMemory chatMemory) {
        // 创建带记忆顾问的ChatClient
        this.chatClient = ChatClient
                .builder(chatModel)
                .defaultAdvisors(
                        PromptChatMemoryAdvisor.builder(chatMemory).build() // 使用Redis记忆
                )
                .build();
    }

    /**
     * 测试Redis记忆功能 - 多轮对话
     * 演示如何通过Redis持久化对话记忆
     */
    @Test
    public void testChatOptions() {
        // 第一轮对话 - 设置用户信息
        String content = chatClient.prompt()
                .user("你好,我叫小小!") // 用户输入
                .advisors(new ReReadingAdvisor()) // 添加重读顾问
                .advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, "1")) // 设置对话ID
                .call()
                .content();
        System.out.println(content);
        System.out.println("----------------------------------");

        // 注释说明后续处理流程
        // MQ 异步处理 ----> 存储向量数据库 ---> 相似性检索

        // 第二轮对话 - 查询用户信息
        content = chatClient.prompt()
                .user("我叫什么?") // 基于记忆的查询
                .advisors(new ReReadingAdvisor()) // 再次添加重读顾问
                .advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, "1")) // 相同对话ID
                .call()
                .content();
        System.out.println(content);
    }

    /**
     * Redis记忆配置类
     */
    @TestConfiguration
    static class Config {
        // Redis连接配置
        @Value("${spring.ai.memory.redis.host}")
        private String redisHost;
        @Value("${spring.ai.memory.redis.port}")
        private int redisPort;
        @Value("${spring.ai.memory.redis.password}")
        private String redisPassword;
        @Value("${spring.ai.memory.redis.timeout}")
        private int redisTimeout;

        /**
         * 配置Redis记忆存储库
         * @return RedisChatMemoryRepository实例
         */
        @Bean
        public RedisChatMemoryRepository redisChatMemoryRepository() {
            return RedisChatMemoryRepository.builder()
                    .host(redisHost) // Redis主机
                    .port(redisPort) // Redis端口
                    // 若没有设置密码则注释该项
                    // .password(redisPassword) // Redis密码
                    .timeout(redisTimeout) // 连接超时
                    .build();
        }

        /**
         * 配置基于Redis的聊天记忆
         * @param chatMemoryRepository Redis记忆存储库
         * @return 配置好的ChatMemory实例
         */
        @Bean
        ChatMemory chatMemory(RedisChatMemoryRepository chatMemoryRepository) {
            return MessageWindowChatMemory
                    .builder()
                    .maxMessages(10) // 保留最近10条消息
                    .chatMemoryRepository(chatMemoryRepository) // 使用Redis存储
                    .build();
        }
    }
}

Mysql实现记忆功能

MySQL作为关系型数据库,是稳定可靠的持久化存储方案,适合需要长期保存对话历史的场景

核心依赖配置

添加spring-ai-starter-model-chat-memory-repository-jdbc

依赖配置MySQL数据源连接信息

package com.xushu.springai.cc.memory;

import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import com.xushu.springai.cc.ReReadingAdvisor;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.memory.repository.jdbc.JdbcChatMemoryRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;

@SpringBootTest
public class TestJDBCMemory {

    // 共享的ChatClient实例
    ChatClient chatClient;

    /**
     * 初始化方法 - 配置带JDBC记忆的ChatClient
     * @param chatModel 自动注入的DashScope聊天模型
     * @param chatMemory 自动注入的ChatMemory实例
     */
    @BeforeEach
    public void init(@Autowired DashScopeChatModel chatModel,
                     @Autowired ChatMemory chatMemory) {
        // 创建带记忆顾问的ChatClient
        this.chatClient = ChatClient
                .builder(chatModel)
                .defaultAdvisors(
                        PromptChatMemoryAdvisor.builder(chatMemory).build() // 使用JDBC记忆
                )
                .build();
    }

    /**
     * 测试JDBC记忆功能 - 多轮对话
     * 演示如何通过JDBC持久化对话记忆
     */
    @Test
    public void testChatOptions() {
        // 第一轮对话 - 设置用户信息
        String content = chatClient.prompt()
                .user("你好,我叫小小!") // 用户输入
                .advisors(new ReReadingAdvisor()) // 添加重读顾问
                .advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, "1")) // 设置对话ID
                .call()
                .content();
        System.out.println(content);
        System.out.println("----------------------------------");

        // 第二轮对话 - 查询用户信息
        content = chatClient.prompt()
                .user("我叫什么?") // 基于记忆的查询
                .advisors(new ReReadingAdvisor()) // 再次添加重读顾问
                .advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, "1")) // 相同对话ID
                .call()
                .content();
        System.out.println(content);
    }

    /**
     * JDBC记忆配置类
     */
    @TestConfiguration
    static class Config {
        /**
         * 配置基于JDBC的聊天记忆
         * @param chatMemoryRepository JDBC记忆存储库
         * @return 配置好的ChatMemory实例
         */
        @Bean
        ChatMemory chatMemory(JdbcChatMemoryRepository chatMemoryRepository) {
            return MessageWindowChatMemory
                    .builder()
                    .maxMessages(1) // 保留最近1条消息
                    .chatMemoryRepository(chatMemoryRepository) // 使用JDBC存储
                    .build();
        }
    }
}
自定义重读用户输入 Advisor
重读(Re2)技术可以提升大模型的推理能力,以下是实现要点:

 核心思想:

 在用户输入后附加"Read the question again: {原问题}"的提示

 通过重复输入引导模型更深入思考

import org.springframework.ai.chat.client.ChatClientRequest;
import org.springframework.ai.chat.client.ChatClientResponse;
import org.springframework.ai.chat.client.advisor.api.*;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import java.util.Map;

/**
 * 重读顾问实现 - 在用户提问前自动添加重读提示
 * 实现BaseAdvisor接口,提供请求前/后的处理能力
 */
public class ReReadingAdvisor implements BaseAdvisor {

    // 默认的重读提示模板
    // 使用{re2_input_query}作为占位符,将被实际用户问题替换
    private static final String DEFAULT_USER_TEXT_ADVISE = """
      {re2_input_query}
      Read the question again: {re2_input_query}
      """;

    /**
     * 请求前处理方法 - 修改用户提问
     * @param chatClientRequest 原始聊天请求
     * @param advisorChain 顾问链
     * @return 修改后的聊天请求
     */
    @Override
    public ChatClientRequest before(ChatClientRequest chatClientRequest, AdvisorChain advisorChain) {
        // 获取原始用户提示内容
        String contents = chatClientRequest.prompt().getContents();

        // 使用PromptTemplate渲染模板,将用户问题插入到重读提示中
        String re2InputQuery = PromptTemplate.builder()
                .template(DEFAULT_USER_TEXT_ADVISE)
                .build()
                .render(Map.of("re2_input_query", contents));

        // 构建新的请求,替换原始提示内容
        ChatClientRequest clientRequest = chatClientRequest.mutate()
                .prompt(Prompt.builder().content(re2InputQuery).build())
                .build();

        return clientRequest;
    }

    /**
     * 请求后处理方法 - 本实现不做处理直接返回响应
     * @param chatClientResponse 聊天响应
     * @param advisorChain 顾问链
     * @return 原始响应
     */
    @Override
    public ChatClientResponse after(ChatClientResponse chatClientResponse, AdvisorChain advisorChain) {
        return chatClientResponse;
    }

    /**
     * 获取顾问执行顺序
     * @return 执行顺序(数值越小优先级越高)
     */
    @Override
    public int getOrder() {
        return 0; // 最高优先级
    }
}

Advisor 测试代码

SimpleLoggerAdvisor 日志顾问

SafeGuardAdvisor 安全防护顾问

ReReadingAdvisor 重读顾问

import org.junit.jupiter.api.Test;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.SafeGuardAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.ChatMemoryRepository;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;

import java.util.List;

@SpringBootTest
public class TestAdvisor {

    /**
     * 测试日志顾问 - SimpleLoggerAdvisor
     * 演示如何添加简单的请求/响应日志记录
     *
     * 日志级别设置:
     * 在application.properties中添加:
     * logging.level.org.springframework.ai.chat.client.advisor=DEBUG
     *
     * @param chatClientBuilder 自动注入的ChatClient构建器
     */
    @Test
    public void testLoggerAdvisor(@Autowired ChatClient.Builder chatClientBuilder) {
        // 1. 创建ChatClient并添加日志顾问
        ChatClient chatClient = chatClientBuilder
                .defaultAdvisors(new SimpleLoggerAdvisor()) // 添加日志顾问
                .build();

        // 2. 构建并执行聊天请求
        String content = chatClient.prompt()
                .user("你好") // 用户消息
                .call()     // 同步调用
                .content(); // 获取响应

        System.out.println(content);
    }

    /**
     * 测试安全防护顾问 - SafeGuardAdvisor
     * 演示如何拦截包含敏感词的请求
     *
     * @param chatClientBuilder 自动注入的ChatClient构建器
     * @param chatMemory 自动注入的聊天记忆组件
     */
    @Test
    public void testAdvisor(@Autowired ChatClient.Builder chatClientBuilder,
                            @Autowired ChatMemory chatMemory) {
        // 1. 创建ChatClient并添加多个顾问
        ChatClient chatClient = chatClientBuilder
                .defaultAdvisors(
                        new SimpleLoggerAdvisor(),    // 日志顾问
                        new SafeGuardAdvisor(List.of("小小")) // 安全顾问,设置敏感词"小小"
                )
                .build();

        // 2. 构建并执行包含敏感词的请求
        String content = chatClient.prompt()
                .user("小小是谁") // 包含敏感词的查询
                .call()
                .content();

        System.out.println(content);
    }

    /**
     * 测试重读顾问 - ReReadingAdvisor
     * 演示自定义顾问如何修改用户提问
     *
     * @param chatClientBuilder 自动注入的ChatClient构建器
     */
    @Test
    public void testReReadingAdvisor(@Autowired ChatClient.Builder chatClientBuilder) {
        // 1. 创建ChatClient并添加自定义重读顾问
        ChatClient chatClient = chatClientBuilder
                .defaultAdvisors(
                        new SimpleLoggerAdvisor(), // 日志顾问
                        new ReReadingAdvisor()     // 自定义重读顾问
                )
                .build();

        // 2. 构建并执行请求
        String content = chatClient.prompt()
                .user("小小是谁") // 原始问题
                .call()
                .content();

        System.out.println(content);

        // 预期效果:AI会收到"小小是谁\nRead the question again: 小小是谁"
    }
}

上一篇:【Spring AI快速上手 (一)】ChatModel与ChatCilent构建对话-CSDN博客

下一篇:【Spring AI快速上手 (三)】Tool实现业务系统对接-CSDN博客

 实战示例:【Spring AI实战】实现仿DeepSeek页面对话机器人_spring ai flux<string>返回-CSDN博客【Spring AI实战】实现仿DeepSeek页面对话机器人(支持多模态上传)_多模态大模型怎么传图片springai-CSDN博客

有任何问题或建议欢迎评论区留言讨论!


网站公告

今日签到

点亮在社区的每一天
去签到