一、前言
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博客
有任何问题或建议欢迎评论区留言讨论!