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



申请成功后将key放在配置文件中

cd spring-ai-alibaba-examples/spring-ai-alibaba-helloworld
./mvnw spring-boot:run

✅模型对话能力
以上示例本质上就是一个普通的 Spring Boot 应用,我们来通过源码解析看一下具体的开发流程。
🔷添加依赖
首先,需要在项目中添加 spring-ai-alibaba-starter 依赖,它将通过 Spring Boot 自动装配机制初始化与阿里云通义大模型通信的 ChatClient、ChatModel 相关实例。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-examples</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>spring-ai-alibaba-helloworld</artifactId>
<version>${revision}</version>
<description>Spring AI Alibaba Helloworld Example</description>
<name>Spring AI Alibaba Helloworld Examples</name>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>${maven-deploy-plugin.version}</version>
</plugin>
</plugins>
</build>
</project>
🔷注入 ChatClient
接下来,在普通 Controller Bean 中注入 ChatClient 实例,这样你的 Bean 就具备与 AI 大模型智能对话的能力了。
package com.alibaba.cloud.ai.example.helloworld;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import jakarta.servlet.http.HttpServletResponse;
import reactor.core.publisher.Flux;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/helloworld")
public class HelloworldController {
private static final String DEFAULT_PROMPT = "你是一个博学的智能聊天助手,请根据用户提问回答!";
private final ChatClient dashScopeChatClient;
// 也可以使用如下的方式注入 ChatClient
public HelloworldController(ChatClient.Builder chatClientBuilder) {
this.dashScopeChatClient = chatClientBuilder
.defaultSystem(DEFAULT_PROMPT)
// TODO
// 实现 Chat Memory 的 Advisor
// 在使用 Chat Memory 时,需要指定对话 ID,以便 Spring AI 处理上下文。
// .defaultAdvisors(
// new MessageChatMemoryAdvisor(new InMemoryChatMemory())
// )
// 实现 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 流式调用
*/
@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();
}
👉DashScopeChatOptions 调整与模型对话时的参数
以上示例中,ChatClient 使用默认参数调用大模型,Spring AI Alibaba 还支持通过 DashScopeChatOptions 调整与模型对话时的参数,DashScopeChatOptions 支持两种不同维度的配置方式:
- 全局默认值,即
ChatClient实例初始化参数
application.yaml 文件中指定 spring.ai.dashscope.chat.options.* 或调用构造函数 ChatClient.Builder.defaultOptions(options)、DashScopeChatModel(api, options) 完成配置初始化。
- 每次 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();
}
接口调用效果

✅增加聊天记忆能力
一种解决办法是在调用大模型的过程中,由开发者编写的代码来维护多轮的对话记忆,这样会大大增加项目的代码量。
Spring AI Alibaba 提供了 jdbc、redis、elasticsearch 插件可以让聊天机器人拥有“记忆”。下面以 MySQL 为例,演示如何快速编写一个带有记忆的聊天机器人。
🔶添加依赖
<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>
🔶配置数据库连接


spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3307/chatMemory?useUnicode=true&characterEncoding=UTF-8
username: root
password: root
🔶实例化 ChatMemoryRepository 对象和 ChatMemory 对象
// 构造 ChatMemoryRepository 和 ChatMemory
ChatMemoryRepository chatMemoryRepository = MysqlChatMemoryRepository.mysqlBuilder()
.jdbcTemplate(jdbcTemplate)
.build();
ChatMemory chatMemory = MessageWindowChatMemory.builder()
.chatMemoryRepository(chatMemoryRepository)
.build();
🔥 构造 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();
}
🔥 每次调用大模型时通过.advisors()传递当前会话ID
/**
* ChatClient 使用自定义的 Advisor 实现功能增强.
* eg:
* http://127.0.0.1:18080/helloworld/advisor/chat/123?query=你好,我叫牧生,之后的会话中都带上我的名字
* 你好,牧生!很高兴认识你。在接下来的对话中,我会记得带上你的名字。有什么想聊的吗?
* http://127.0.0.1:18080/helloworld/advisor/chat/123?query=我叫什么名字?
* 你叫牧生呀。有什么事情想要分享或者讨论吗,牧生?
*/
@GetMapping("/advisor/chat/{id}")
public Flux<String> advisorChat(
HttpServletResponse response,
@PathVariable String id,
@RequestParam String query) {
response.setCharacterEncoding("UTF-8");
return this.dashScopeChatClient.prompt(query)
.advisors(
a -> a.param(ChatMemory.CONVERSATION_ID, id)
).stream().content();
}
🔶测试记忆能力
第一次发送我的名字带上会话id 1

数据库中存储数据

第二次询问我的名字,回答正确

数据库中存储数据

1060

被折叠的 条评论
为什么被折叠?



