跳转到内容
Spring AI Alibaba 1.0 GA 版本正式发布,开启 Java 智能体开发新时代!点此了解

聊天机器人

本文介绍如何使用 Spring AI Alibaba 开发一个基于通义模型服务的智能体聊天应用

快速体验示例

注意:因为 Spring AI Alibaba 基于 Spring Boot 3.x 开发,因此本地 JDK 版本要求为 17 及以上。

  1. 下载项目

运行以下命令下载源码,进入 helloworld 示例目录:

Terminal window
git clone --depth=1 https://github.com/springaialibaba/spring-ai-alibaba-examples.git
cd spring-ai-alibaba-examples/spring-ai-alibaba-helloworld
  1. 运行项目

首先,需要获取一个合法的 API-KEY 并设置 AI_DASHSCOPE_API_KEY 环境变量,可跳转 阿里云百炼平台 了解如何获取 API-KEY

Terminal window
export AI_DASHSCOPE_API_KEY=${REPLACE-WITH-VALID-API-KEY}

启动示例应用:

Terminal window
./mvnw compile exec:java -Dexec.mainClass="com.alibaba.cloud.ai.example.helloworld.HelloworldApplication"

访问 http://localhost:18080/helloworld/simple/chat?query=给我讲一个笑话吧 ,向通义模型提问并得到回答。

示例开发指南

模型对话能力

以上示例本质上就是一个普通的 Spring Boot 应用,我们来通过源码解析看一下具体的开发流程。

  1. 添加依赖

首先,需要在项目中添加 spring-ai-alibaba-starter 依赖,它将通过 Spring Boot 自动装配机制初始化与阿里云通义大模型通信的 ChatClientChatModel 相关实例。

<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-bom</artifactId>
<version>1.0.0.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
</dependency>
</dependencies>
  1. 注入 ChatClient

接下来,在普通 Controller Bean 中注入 ChatClient 实例,这样你的 Bean 就具备与 AI 大模型智能对话的能力了。

@RestController
@RequestMapping("/helloworld")
public class HelloworldController {
private static final String DEFAULT_PROMPT = "你是一个博学的智能聊天助手,请根据用户提问回答!";
private final ChatClient dashScopeChatClient;
public HelloworldController(ChatClient.Builder chatClientBuilder) {
this.dashScopeChatClient = chatClientBuilder
.defaultSystem(DEFAULT_PROMPT)
// 实现 Logger 的 Advisor
.defaultAdvisors(
new SimpleLoggerAdvisor()
)
// 设置 ChatClient 中 ChatModel 的 Options 参数
.defaultOptions(
DashScopeChatOptions.builder()
.withTopP(0.7)
.build()
)
.build();
}
/**
* ChatClient 简单调用
*/
@GetMapping("/simple/chat")
public String simpleChat(@RequestParam(value = "query", defaultValue = "你好,很高兴认识你,能简单介绍一下自己吗?")String query) {
return dashScopeChatClient.prompt(query).call().content();
}
}

以上示例中,ChatClient 使用默认参数调用大模型,Spring AI Alibaba 还支持通过 DashScopeChatOptions 调整与模型对话时的参数,DashScopeChatOptions 支持两种不同维度的配置方式:

  1. 全局默认值,即 ChatClient 实例初始化参数

application.yaml 文件中指定 spring.ai.dashscope.chat.options.* 或调用构造函数 ChatClient.Builder.defaultOptions(options)DashScopeChatModel(api, options) 完成配置初始化。

  1. 每次 Prompt 调用前动态指定
String result = dashScopeChatClient
.prompt(query)
.options(DashScopeChatOptions.builder().withTopP(0.8).build())
.call()
.content();

关于 DashScopeChatOptions 配置项的详细说明,请查看参考手册。

此外,模型还支持流式调用,这样的数据返回前端会产生“打字机”效果:

/**
* ChatClient 流式调用
*/
@GetMapping("/stream/chat")
public Flux<String> streamChat(@RequestParam(value = "query", defaultValue = "你好,很高兴认识你,能简单介绍一下自己吗?")String query, HttpServletResponse response) {
response.setCharacterEncoding("UTF-8");
return dashScopeChatClient.prompt(query).stream().content();
}

增加聊天记忆能力

以上的代码是不具有记忆的,在每一次调用AI模型,并不会携带上次调用信息。

一种解决办法是在调用大模型的过程中,由开发者编写的代码来维护多轮的对话记忆,这样会大大增加项目的代码量。

Spring AI Alibaba 提供了 jdbcrediselasticsearch 插件可以让聊天机器人拥有“记忆”。下面以 MySQL 为例,演示如何快速编写一个带有记忆的聊天机器人。

  1. 添加依赖
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-memory-jdbc</artifactId>
<version>1.0.0.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>
  1. 配置数据库连接
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/chatMemory?useUnicode=true&characterEncoding=UTF-8
username: root
password: root
  1. 实例化 ChatMemoryRepository 对象和 ChatMemory 对象
// 构造 ChatMemoryRepository 和 ChatMemory
ChatMemoryRepository chatMemoryRepository = MysqlChatMemoryRepository.mysqlBuilder()
.jdbcTemplate(jdbcTemplate)
.build();
ChatMemory chatMemory = MessageWindowChatMemory.builder()
.chatMemoryRepository(chatMemoryRepository)
.build();
  1. 构造 ChatClient 时通过 .defaultAdvisors() 注册 MessageChatMemoryAdvisor
public HelloworldController(JdbcTemplate jdbcTemplate, ChatClient.Builder chatClientBuilder) {
// 构造 ChatMemoryRepository 和 ChatMemory
ChatMemoryRepository chatMemoryRepository = MysqlChatMemoryRepository.mysqlBuilder()
.jdbcTemplate(jdbcTemplate)
.build();
ChatMemory chatMemory = MessageWindowChatMemory.builder()
.chatMemoryRepository(chatMemoryRepository)
.build();
this.dashScopeChatClient = chatClientBuilder
.defaultSystem(DEFAULT_PROMPT)
.defaultAdvisors(new SimpleLoggerAdvisor())
// 注册Advisor
.defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build())
.defaultOptions(
DashScopeChatOptions.builder()
.withTopP(0.7)
.build()
)
.build();
}
  1. 每次调用大模型时通过.advisors()传递当前会话ID
@GetMapping("/simple/chat")
public String simpleChat(@RequestParam(value = "query", defaultValue = "你好,很高兴认识你,能简单介绍一下自己吗?")String query,
@RequestParam(value = "chat-id", defaultValue = "1") String chatId) {
return dashScopeChatClient.prompt(query)
.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, chatId))
.call().content();
}

这样,大模型就会获取会话ID的历史消息记录。

学习更多示例

学习更多 Spring AI Alibaba 框架用法,请参考 Spring AI Alibaba 社区的官方示例源码仓库:

https://github.com/springaialibaba/spring-ai-alibaba-examples