Spring AI Alibaba 快速入门:基于通义千问的AI应用开发环境搭建
导读:本文面向有一定 Spring Boot 经验、希望快速落地 AI 能力的 Java 开发者。文章从零开始,带你理解 Spring AI Alibaba 与 Spring AI 的关系,完成环境搭建,并跑通第一个可对话的 ChatClient 示例。预计阅读时间 20 分钟。
一、写在前面:为什么选 Spring AI Alibaba?
过去两年,围绕大模型的 Java 生态经历了一场"野蛮生长"期------各家厂商各自为阵,SDK 风格迥异,换一个模型就要重写一套调用代码。这种碎片化的现状催生了 Spring AI 这个统一抽象层,而 Spring AI Alibaba 则是阿里巴巴基于 Spring AI 规范,针对通义千问(Qwen)系列模型和阿里云百炼平台(DashScope)深度适配的企业级实现。
一句话总结它们的关系:
Spring AI → 定义标准接口(ChatModel、ChatClient、EmbeddingModel...)
Spring AI Alibaba → 实现阿里云 DashScope 侧的具体逻辑,并扩展多模态、Agent、MCP 等能力
选择它的理由很简单:
- 一套代码,多模型切换:今天用 qwen-turbo,明天换 DeepSeek-R1,只改配置文件;
- 云原生友好:与 Spring Boot Actuator、Micrometer、Spring Cloud 无缝集成;
- 活跃维护 :截至 2025 年 3 月,最新版本已到 1.1.2.2,持续跟进上游 Spring AI 1.1.x。
二、技术栈全景与版本说明
在动手之前,先把版本矩阵理清楚,避免依赖冲突这个最常见的坑:
+---------------------------+------------------+
| 组件 | 版本要求 |
+---------------------------+------------------+
| JDK | 17+(必须) |
| Spring Boot | 3.2.x / 3.3.x |
| Spring AI | 1.1.2 |
| Spring AI Alibaba | 1.1.2.x(最新) |
| Maven | 3.8+ |
| 阿里云百炼 DashScope API | 当前稳定版 |
+---------------------------+------------------+
重要提醒 :Spring AI Alibaba 1.1.x 系列对应 Spring AI 1.1.x,不兼容 Spring AI 1.0.x。升级时务必同步升级,否则会出现
ClassNotFoundException或接口不匹配问题。
三、前置准备
3.1 获取阿里云 DashScope API Key
- 访问 阿里云百炼控制台,使用阿里云账号登录;
- 在左侧菜单找到 "模型服务"→"API-KEY 管理",点击"创建 API-KEY";
- 选择适用模型范围(建议选"全部模型"),生成后立即复制保存(只显示一次);
- 确认账号已开通"通义千问"服务权限,免费额度一般够入门使用。
新手常见问题 :创建了 API Key 但调用返回
InvalidApiKey或QuotaExceeded,检查两点:一是 API Key 是否绑定了对应的模型权限;二是余额是否已用尽,可在百炼控制台查看用量。
3.2 JDK 与 Maven 确认
bash
# 确认 JDK 版本
java -version
# 输出示例:openjdk version "17.0.10"
# 确认 Maven 版本
mvn -version
# 输出示例:Apache Maven 3.9.6
若 JDK 版本低于 17,Spring Boot 3.x 启动时会直接报错,没有任何商量余地。
3.3 Maven 仓库配置
Spring AI Alibaba 1.1.x 已发布到 Maven 中央仓库(Central Repository),无需额外配置 snapshot 仓库。若你处于企业内网,只需在公司 Nexus/Artifactory 中同步一下即可。
如果使用阿里云镜像加速,在 ~/.m2/settings.xml 中配置:
xml
<mirrors>
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
四、创建项目:从 Spring Initializr 开始
打开 https://start.spring.io/,按如下配置:
Project: Maven
Language: Java
Spring Boot: 3.3.x(选最新稳定版)
Group: com.example
Artifact: ai-quickstart
Java: 17
依赖项选择:
- Spring Web(提供 HTTP 接口)
- Lombok(简化代码)
点击"Generate"下载并解压项目。
五、核心依赖配置详解
打开 pom.xml,添加以下内容:
5.1 BOM 版本管理(关键步骤)
xml
<properties>
<java.version>17</java.version>
<spring-ai-alibaba.version>1.1.2.2</spring-ai-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring AI Alibaba BOM:统一管理所有子模块版本 -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-bom</artifactId>
<version>${spring-ai-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
5.2 核心依赖
xml
<dependencies>
<!-- Spring Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring AI Alibaba DashScope Starter(1.1版统一入口) -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
<!-- 版本由 BOM 统一管理,这里无需填写 -->
</dependency>
<!-- Lombok:减少样板代码 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
1.1 版 Starter 变化说明 :旧版本(1.0.x)使用
spring-ai-alibaba-starter作为统一入口;1.1 版开始,官方将 DashScope、OpenAI 等模型的 starter 拆分独立,DashScope 对应的入口变更为spring-ai-alibaba-starter-dashscope。如果你在网上看到教程还在用旧依赖名,注意甄别版本。
六、YAML 配置详解
编辑 src/main/resources/application.yml:
yaml
spring:
application:
name: ai-quickstart
ai:
dashscope:
# API Key 配置:生产环境务必通过环境变量注入,不要硬编码
api-key: ${AI_DASHSCOPE_API_KEY:your-api-key-here}
chat:
options:
# 模型选择:qwen-turbo(快速低价)/ qwen-plus(平衡)/ qwen-max(最强)
model: qwen-turbo
# 温度参数(0~2):控制输出随机性,越高越有创意,越低越稳定
# 对话类应用建议 0.7,代码生成建议 0.2
temperature: 0.7
# Top-P(0~1):与 temperature 配合使用,控制词汇多样性
top-p: 0.8
# 最大输出 Token 数
max-tokens: 2048
server:
port: 8080
配置参数一览表
+----------------+----------+--------+-----------------------------------------+
| 参数 | 类型 | 默认值 | 说明 |
+----------------+----------+--------+-----------------------------------------+
| model | String | - | 模型名称,见下文模型清单 |
| temperature | Float | 0.7 | 创意/随机性,0=确定性输出,2=高度随机 |
| top-p | Float | 0.8 | 累积概率截断,通常与 temperature 二选一 |
| max-tokens | Integer | 1500 | 最大输出 Token,影响费用和响应长度 |
| enable-search | Boolean | false | 开启联网搜索(部分模型支持) |
+----------------+----------+--------+-----------------------------------------+
通义千问模型选型建议:
qwen-turbo → 响应最快,适合高并发、简单对话,成本最低
qwen-plus → 中等能力,平衡速度与质量,适合大多数业务场景
qwen-max → 能力最强,适合复杂推理、长文本,成本较高
qwen-long → 超长上下文(百万 Token),适合长文档处理
七、第一个 ChatClient:单轮对话
7.1 Controller 实现
java
package com.example.aiquickstart.controller;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 基础聊天 Controller
* 演示 ChatClient 的基本用法
*/
@Slf4j
@RestController
@RequestMapping("/chat")
public class ChatController {
private final ChatClient chatClient;
/**
* 通过构造器注入 ChatClient.Builder
* Spring AI Alibaba 会自动注册 Builder Bean
*/
public ChatController(ChatClient.Builder builder) {
this.chatClient = builder
// 设置系统角色:定义 AI 的身份和行为边界
.defaultSystem("你是一位资深的 Java 技术专家,熟悉 Spring 生态和云原生技术。" +
"回答时请简洁专业,必要时给出代码示例。")
.build();
}
/**
* 单轮对话接口
* 访问:GET /chat/simple?message=你好
*/
@GetMapping("/simple")
public String simpleChat(@RequestParam(defaultValue = "你好,介绍一下自己") String message) {
log.info("收到用户提问:{}", message);
String response = chatClient
.prompt(message)
.call()
.content();
log.info("模型响应:{}", response);
return response;
}
/**
* 携带自定义参数的对话
* 演示 Call 级别的参数覆盖
*/
@GetMapping("/creative")
public String creativeChat(@RequestParam String message) {
return chatClient
.prompt()
.user(message)
// Call 级别覆盖全局配置,此次调用使用更高创意度
.options(DashScopeChatOptions.builder()
.withTemperature(1.2)
.withModel("qwen-plus")
.build())
.call()
.content();
}
}
7.2 代码解析
上面这段代码里有几个细节值得展开说:
1. ChatClient 是单例,Builder 是原型
ChatClient.Builder 每次注入都是一个新实例(Prototype),但 .build() 出来的 ChatClient 应该作为单例持有。把它声明为类的字段并在构造器中初始化,是线程安全的正确姿势。
2. defaultSystem 的作用范围
defaultSystem 设置的系统提示词会附加在所有请求 的系统消息中,类似于给 AI 定制了一个"人格底色"。如果某次请求需要临时修改,可以在 .prompt() 链上调用 .system() 覆盖。
3. 三级参数覆盖机制
全局配置(application.yml)
↓ 被覆盖
ChatClient 构建时的 defaultOptions
↓ 被覆盖
单次调用的 .options(...)
优先级从低到高,越具体的越优先。
八、流式输出(Streaming):告别等待
普通的 .call() 是等模型生成完整回答后一次性返回,用户体验上会有明显的"等待感"。流式输出通过 SSE(Server-Sent Events)边生成边推送,体验接近 ChatGPT 的打字效果。
8.1 服务端实现
java
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import reactor.core.publisher.Flux;
/**
* 流式对话接口
* 返回 Flux<String>,Spring WebFlux 自动处理 SSE 推送
*/
@GetMapping(value = "/stream", produces = "text/event-stream")
public Flux<String> streamChat(@RequestParam String message) {
return chatClient
.prompt(message)
// stream() 替代 call(),返回响应式流
.stream()
// 提取每个 chunk 的文本内容
.content();
}
注意 :
produces = "text/event-stream"是关键,告诉浏览器/客户端这是 SSE 流,而非普通 JSON 响应。
8.2 用 curl 测试流式效果
bash
# 普通调用
curl "http://localhost:8080/chat/simple?message=用100字介绍Spring Boot"
# 流式调用(实时看到输出逐字出现)
curl -N "http://localhost:8080/chat/stream?message=用100字介绍Spring Boot"
8.3 流式处理流程图
客户端 Spring Controller DashScope API
| | |
|--- GET /chat/stream -----> | |
| |--- POST /stream-chat -----> |
| | |
| | <-- chunk1 (token流) ------ |
| <-- data: "Spring" ------- | |
| | <-- chunk2 (token流) ------ |
| <-- data: " Boot" -------- | |
| | ... |
| | <-- [DONE] --------------- |
| <-- data: [DONE] --------- | |
| | |
九、Lombok 简化代码实践
在 AI 应用中,我们经常需要定义请求/响应的 DTO。Lombok 可以显著减少样板代码:
java
package com.example.aiquickstart.dto;
import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
/**
* 聊天请求 DTO
*/
@Data
@Builder
public class ChatRequest {
/** 用户消息 */
private String message;
/** 会话 ID,用于多轮对话 */
private String sessionId;
/** 是否启用流式输出 */
@Builder.Default
private boolean streaming = false;
}
/**
* 聊天响应 DTO
*/
@Data
@Builder
public class ChatResponse {
/** AI 回答内容 */
private String content;
/** 消耗的 Token 数量 */
private Integer totalTokens;
/** 模型名称 */
private String model;
}
十、启动与验证
10.1 设置环境变量并启动
Windows PowerShell:
powershell
$env:AI_DASHSCOPE_API_KEY = "sk-xxxxxxxxxxxxxxxx"
./mvnw spring-boot:run
Linux / macOS:
bash
export AI_DASHSCOPE_API_KEY="sk-xxxxxxxxxxxxxxxx"
./mvnw spring-boot:run
10.2 验证启动日志
正常启动后,你会看到类似这样的日志:
...
INFO - Tomcat started on port 8080
INFO - Started AiQuickstartApplication in 2.831 seconds
如果看到 DashScopeAutoConfiguration 相关的初始化日志,说明 DashScope 模块加载成功。
10.3 接口测试
bash
# 测试单轮对话
curl "http://localhost:8080/chat/simple?message=Spring Boot 3 有哪些主要新特性"
# 测试流式输出
curl -N "http://localhost:8080/chat/stream?message=请写一首关于Java的五言绝句"
# 测试自定义参数
curl "http://localhost:8080/chat/creative?message=给我编一个有趣的程序员段子"
十一、避坑指南:常见问题处理
坑一:API Key 无效(InvalidApiKey)
错误信息:{"code":"InvalidApiKey","message":"Invalid API-key provided."}
排查步骤:
- 确认环境变量是否正确设置:
echo $AI_DASHSCOPE_API_KEY; - 检查 API Key 是否包含多余的空格或换行符;
- 进入百炼控制台确认 Key 是否启用且未过期;
- 新创建的 Key 有约 1-2 分钟的生效延迟。
坑二:依赖下载失败(网络问题)
在公司内网环境下,访问 Maven 中央仓库可能需要配置代理:
xml
<!-- ~/.m2/settings.xml -->
<proxies>
<proxy>
<id>http-proxy</id>
<active>true</active>
<protocol>http</protocol>
<host>your-proxy-host</host>
<port>8080</port>
<!-- 如有认证 -->
<username>your-username</username>
<password>your-password</password>
<!-- 内网地址不走代理 -->
<nonProxyHosts>localhost|127.0.0.1|*.internal.com</nonProxyHosts>
</proxy>
</proxies>
坑三:NoSuchBeanDefinitionException(找不到 ChatClient.Builder)
通常由以下原因引起:
- Starter 依赖名写错(注意 1.1 版已更名为
spring-ai-alibaba-starter-dashscope); - BOM 版本没有引入,导致依赖版本冲突;
application.yml中spring.ai.dashscope.api-key缺失,自动配置被跳过。
坑四:配置 YAML 缩进错误
YAML 对缩进极度敏感,以下是错误示例与正确示例对比:
yaml
# ❌ 错误:层级混乱
spring:
ai:
dashscope:
api-key: xxx
# ✅ 正确:严格缩进
spring:
ai:
dashscope:
api-key: xxx
坑五:QPS 超限(Throttling)
免费账号有 QPS(每秒请求数)限制,并发测试时容易触发:
错误信息:{"code":"Throttling.RateQuota","message":"Requests rate limit exceeded"}
处理方案:在 RestTemplate 或 WebClient 层加指数退避重试,或升级百炼账号配额。
十二、项目完整结构回顾
ai-quickstart/
├── pom.xml # 依赖配置(含 BOM)
├── src/
│ ├── main/
│ │ ├── java/com/example/
│ │ │ ├── AiQuickstartApplication.java
│ │ │ ├── controller/
│ │ │ │ └── ChatController.java # 核心 Controller
│ │ │ └── dto/
│ │ │ ├── ChatRequest.java
│ │ │ └── ChatResponse.java
│ │ └── resources/
│ │ └── application.yml # 含 API Key 配置
│ └── test/
│ └── java/com/example/
│ └── ChatControllerTest.java
十三、总结与延伸阅读
恭喜你,已经完成了 Spring AI Alibaba 的第一个 Hello World 级应用。回顾一下本文的核心知识点:
- Spring AI vs Spring AI Alibaba:前者定标准,后者做实现,使用时引 Alibaba 的 starter 即可;
- 1.1 版 Starter 已拆分 :
spring-ai-alibaba-starter-dashscope是接入 DashScope 的正确依赖; - BOM 管理版本:引入 BOM 后子模块无需填写版本号,避免版本冲突;
- 三级配置覆盖:YAML 全局 → Builder defaultOptions → Call 级 options;
- 流式输出 :用
.stream().content()配合text/event-stream实现 SSE 推送。
下一篇将深入 Maven 依赖与 YAML 配置的全貌,涵盖多模型并存、Profile 隔离、环境变量注入等企业级配置技巧,敬请期待。
参考资料