Spring AI Alibaba 快速入门:基于通义千问的AI应用开发环境搭建

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

  1. 访问 阿里云百炼控制台,使用阿里云账号登录;
  2. 在左侧菜单找到 "模型服务"→"API-KEY 管理",点击"创建 API-KEY";
  3. 选择适用模型范围(建议选"全部模型"),生成后立即复制保存(只显示一次);
  4. 确认账号已开通"通义千问"服务权限,免费额度一般够入门使用。

新手常见问题 :创建了 API Key 但调用返回 InvalidApiKeyQuotaExceeded,检查两点:一是 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."}

排查步骤:

  1. 确认环境变量是否正确设置:echo $AI_DASHSCOPE_API_KEY
  2. 检查 API Key 是否包含多余的空格或换行符;
  3. 进入百炼控制台确认 Key 是否启用且未过期;
  4. 新创建的 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.ymlspring.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 级应用。回顾一下本文的核心知识点:

  1. Spring AI vs Spring AI Alibaba:前者定标准,后者做实现,使用时引 Alibaba 的 starter 即可;
  2. 1.1 版 Starter 已拆分spring-ai-alibaba-starter-dashscope 是接入 DashScope 的正确依赖;
  3. BOM 管理版本:引入 BOM 后子模块无需填写版本号,避免版本冲突;
  4. 三级配置覆盖:YAML 全局 → Builder defaultOptions → Call 级 options;
  5. 流式输出 :用 .stream().content() 配合 text/event-stream 实现 SSE 推送。

下一篇将深入 Maven 依赖与 YAML 配置的全貌,涵盖多模型并存、Profile 隔离、环境变量注入等企业级配置技巧,敬请期待。


参考资料

相关推荐
伯恩bourne1 小时前
Google Guava:Java 核心工具库的卓越之选
java·开发语言·guava
跨境卫士-小汪1 小时前
高风险订单识别不足如何设置拦截与二次核验
大数据·人工智能·产品运营·跨境电商·营销策略
小王不爱笑1322 小时前
Spring 基础核心
java
心勤则明2 小时前
用 Spring AI Alibaba 打造智能查询增强引擎
java·人工智能·spring
Arva .2 小时前
Spring 的三级缓存,两级够吗
java·spring·缓存
爱喝一杯白开水2 小时前
Java 定时任务完全指南
java
njsgcs2 小时前
图卷积是如何处理不同输入长度的 消息传递
人工智能
毕设源码-郭学长2 小时前
【开题答辩全过程】以 高校自动排课系统的设计与实现为例,包含答辩的问题和答案
java
哥本哈士奇2 小时前
使用OpenClaw的Skills对接本地系统
人工智能