前几篇我们分别接入了云端 DeepSeek、OpenAI ChatGPT,还用 Ollama 在本地跑了大模型。今天,我们进入国产大模型的主场——阿里云百炼平台,以及它的 Java 最佳拍档:Spring AI Alibaba。
如果你是国内开发者,大概率会遇到这样的场景:公司要求使用国产大模型(合规、数据不出境),而且最好和阿里云已有的基础设施打通。Spring AI Alibaba 正是为这个场景量身打造的框架——它基于 Spring AI 标准构建,深度集成阿里云百炼平台(DashScope),提供对通义千问全系列模型的原生支持。
今天这篇,我们从零开始接入百炼平台,体验 ChatClient 文本对话和多模态图像理解两大核心能力。
一、痛点场景:国产大模型接入的“最后一公里”
先来看看几个真实的开发者困境:
场景一:合规要求
公司项目要求所有数据不出境,必须使用国产大模型。但团队对阿里云百炼的 API 格式不熟悉,担心接入成本高、文档不完善。如果用原始 HTTP 调用,要自己处理签名、Token 管理、重试逻辑,费时费力。
场景二:生态整合
项目已经用了 Spring Cloud Alibaba 全家桶(Nacos、Sentinel、RocketMQ),想在同一个技术栈里接入 AI 能力。如果另起一套 Python 服务,运维成本翻倍。
场景三:多模态需求
产品经理要求做一个“拍照识物”功能——用户上传一张图片,AI 自动识别并描述内容。你可能会想:这得用 Python 的视觉模型吧?Java 能搞吗?
答案都是:能。而且比你想象中简单得多。Spring AI Alibaba 把百炼平台的能力封装成了标准的ChatClient和ChatModel,你用前面几篇学到的任何知识,在这里完全复用。并且通过withMultiModel(true)配置,一行开关即可在纯文本与多模态之间切换。
二、核心概念快览
2.1 Spring AI Alibaba 是什么?
Spring AI Alibaba 是阿里云基于 Spring AI 官方标准深度打造的企业级 AI 应用开发框架。它的核心价值在于:一套标准 API,屏蔽不同大模型的底层差异,让 Java 开发者像写 Spring Boot 业务代码一样开发 AI 应用。它的底层兼容 Spring AI 全量 API,无缝对接 Spring Boot、Spring Cloud 微服务生态,并深度整合阿里云灵积 DashScope 平台,原生支持通义千问全系列模型。
简单记忆:Spring AI 定义了“怎么用”的标准,Spring AI Alibaba 提供了“连什么”的落地实现。
2.2 百炼平台(DashScope)
百炼是阿里云推出的一站式大模型服务平台,底层是通义千问系列模型。通过统一的 API,你可以访问文本生成、图像理解、语音合成、视频生成等多种模型能力。Spring AI Alibaba 通过dashscopestarter 封装了对百炼平台的访问,你只需要一个 API Key 就能调用所有服务。
2.3 多模态图像理解
“多模态”这个词听起来唬人,其实就是让模型能处理多种类型的信息输入——不只是文字,还有图片、视频、音频等。图像理解是多模态的一个子集,指的是模型能“看懂”图片内容并给出描述。比如给它一张猫的照片,它能告诉你“这是一只橘猫,正趴在沙发上睡觉”。Spring AI Alibaba 通过在DashScopeChatOptions中开启withMultiModal(true)并将Media对象附加到UserMessage上来支持多模态输入。
2.4 与 Spring AI 的关系
Spring AI Alibaba 项目和前面几篇用的 Spring AI(开源版)是一脉相承的:
- Spring AI Alibaba 是 Spring AI 的阿里云实现,底层完全遵循 Spring AI 的 API 规范。
- 你前面学到的
ChatClient、Prompt、流式输出、结构化输出等概念和调用方式,在这里全部通用。 - 区别只在于依赖和配置:从
spring-ai-starter-model-openai换成spring-ai-alibaba-starter-dashscope,从base-url换成百炼自动配置。
三、环境准备
3.1 获取百炼 API Key
访问 百炼控制台,用阿里云账号登录。进入“API Key 管理”页面,创建一个新的 API Key。
新用户通常有可观的免费额度,足够学习和测试使用。Key 创建后仅显示一次,务必保存好。
设置环境变量(避免硬编码):
# Mac / LinuxexportDASHSCOPE_API_KEY=sk-你的密钥# Windows PowerShell$env:DASHSCOPE_API_KEY="sk-你的密钥"如果使用 IDEA,记得在 Run Configuration 中添加该环境变量。
3.2 Maven 依赖
创建一个新的 Spring Boot 项目(JDK 17+,Spring Boot 3.5.x)。在pom.xml中添加 Spring AI Alibaba 的 BOM 和 dashscope starter:
<?xml version="1.0" encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.5.14</version><relativePath/></parent><groupId>com.example</groupId><artifactId>spring-ai-alibaba-demo</artifactId><version>0.0.1-SNAPSHOT</version><properties><java.version>17</java.version><!-- 版本说明(2026 年 5 月): Spring AI Alibaba 1.1.2.0 是当前最新稳定版,对应 Spring AI 1.1.2 请关注 https://github.com/alibaba/spring-ai-alibaba/releases 获取最新版本 --><spring-ai-alibaba.version>1.1.2.0</spring-ai-alibaba.version><spring-ai.version>1.1.6</spring-ai.version></properties><dependencies><!-- Spring Boot Web Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring AI Alibaba DashScope Starter:提供百炼平台接入能力 --><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-dashscope</artifactId><version>${spring-ai-alibaba.version}</version></dependency><!-- Spring Boot 测试 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><!-- Spring AI BOM:统一管理 Spring AI 相关依赖版本 --><dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>${spring-ai.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>依赖注意:
spring-ai-alibaba-starter-dashscope内部已经包含了百炼平台的默认 URL 配置,因此在application.yml中通常无需配置base-url,只需要配置api-key即可。如果需要自定义连接参数,可以通过spring.ai.dashscope.connection相关配置项调整。
3.3 application.yml 配置
spring:application:name:spring-ai-alibaba-demoai:dashscope:api-key:${DASHSCOPE_API_KEY}# 从环境变量读取chat:options:model:qwen-plus# 使用通义千问增强版temperature:0.7# 开发阶段建议开启 DEBUG 日志,方便排查请求/响应内容logging:level:com.alibaba.cloud.ai:DEBUG模型选择说明:
百炼平台提供了多个文本模型,按能力和成本排序:
| 模型名称 | 特点 | 适用场景 |
|---|---|---|
| qwen-turbo | 速度快,成本最低 | 简单对话、文本分类 |
| qwen-plus | 效果、速度、成本均衡 | 日常对话、内容生成(推荐) |
| qwen-max | 最强能力,复杂推理 | 高质量创作、复杂分析 |
| qwen-vl-max | 多模态模型 | 图像理解、图文分析 |
日常学习和开发,推荐使用 qwen-plus,性价比最高。如果需要测试多模态功能,需要切换为 qwen-vl-max 等多模态模型。
四、代码实战:文本对话与多模态
4.1 创建 AIChatService
新建 service 包,创建AIChatService.java:
packagecom.example.demo.service;importorg.springframework.ai.chat.client.ChatClient;importorg.springframework.ai.chat.model.ChatModel;importorg.springframework.core.io.ClassPathResource;importorg.springframework.stereotype.Service;importorg.springframework.util.MimeTypeUtils;importreactor.core.publisher.Flux;@ServicepublicclassAIChatService{privatefinalChatClientchatClient;privatefinalChatModelchatModel;// 注入 ChatModel 以支持多模态配置/** * 构造器注入 ChatClient 和 ChatModel * ChatClient 用于纯文本对话 * ChatModel 用于需要自定义配置的高级场景(如多模态) */publicAIChatService(ChatClientchatClient,ChatModelchatModel){this.chatClient=chatClient;this.chatModel=chatModel;}// ========== 纯文本对话 ==========/** * 同步对话 */publicStringchat(Stringmessage){returnchatClient.prompt().user(message).call().content();}/** * 流式对话(打字机效果) */publicFlux<String>streamChat(Stringmessage){returnchatClient.prompt().user(message).stream().content();}// ========== 多模态:图像理解 ==========/** * 图像理解:从 classpath 读取图片并分析 * 使用 ChatModel 而非 ChatClient,因为需要自定义 DashScopeChatOptions * @param imagePath classpath 下的图片路径,如 "/images/cat.jpg" * @param question 关于图片的问题,如 "描述这张图片" */publicStringunderstandImage(StringimagePath,Stringquestion){// 创建自定义 ChatClient(带有多模态配置)returnChatClient.create(chatModel).prompt().user(userSpec->{// 设置文本部分userSpec.text(question);// 附加图片资源userSpec.media(MimeTypeUtils.IMAGE_JPEG,newClassPathResource(imagePath));}).options(com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions.builder().withModel("qwen-vl-max")// 切换为多模态模型.withMultiModel(true)// 开启多模态支持.build()).call().content();}/** * 图像理解(通过 URL) * @param imageUrl 图片的网络地址 * @param question 问题 */publicStringunderstandImageByUrl(StringimageUrl,Stringquestion){returnChatClient.create(chatModel).prompt().user(userSpec->{userSpec.text(question);try{userSpec.media(MimeTypeUtils.IMAGE_PNG,newjava.net.URI(imageUrl).toURL());}catch(Exceptione){thrownewRuntimeException("图片 URL 格式错误",e);}}).options(com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions.builder().withModel("qwen-vl-max").withMultiModel(true).build()).call().content();}}关键点解读:
- 纯文本对话用的就是前面几篇的标准
ChatClient,写法完全一致。 - 多模态(图像理解)需要用
DashScopeChatOptions指定多模态模型并开启withMultiModal(true),然后将图片作为media附加到UserMessage上。 - 用
ChatClient.create(chatModel)手动创建实例来支持自定义 Options,这是相对底层的用法,适用于需要特定模型配置的高级场景。 - 图片可以通过本地文件(
ClassPathResource)或网络 URL 传入。 - 多模态模型支持 image 和 video 格式,但不同模型的具体支持范围不同。如 qwen-vl-max 支持图片和视频,使用时需要通过
message.getMetadata().put(DashScopeApiConstants.MESSAGE_FORMAT, MessageFormat.VIDEO)来指定。
4.2 创建 Controller
新建 controller 包,创建AIController.java:
packagecom.example.demo.controller;importcom.example.demo.service.AIChatService;importorg.springframework.http.MediaType;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestParam;importorg.springframework.web.bind.annotation.RestController;importreactor.core.publisher.Flux;@RestControllerpublicclassAIController{privatefinalAIChatServicechatService;publicAIController(AIChatServicechatService){this.chatService=chatService;}/** * 文本同步对话 * GET /ai/chat?msg=你好 */@GetMapping("/ai/chat")publicStringchat(@RequestParam(defaultValue="请用一句话介绍通义千问")Stringmsg){returnchatService.chat(msg);}/** * 文本流式对话(SSE) * GET /ai/stream?msg=介绍Spring Boot */@GetMapping(value="/ai/stream",produces=MediaType.TEXT_EVENT_STREAM_VALUE)publicFlux<String>streamChat(@RequestParamStringmsg){returnchatService.streamChat(msg);}/** * 图像理解(本地图片) * GET /ai/vision?question=描述这张图片 * 需要在 src/main/resources/images/ 下放置测试图片 */@GetMapping("/ai/vision")publicStringvision(@RequestParam(defaultValue="描述这张图片")Stringquestion){returnchatService.understandImage("/images/test.jpg",question);}/** * 图像理解(通过 URL) * GET /ai/vision-url?imageUrl=图片地址&question=描述这张图片 */@GetMapping("/ai/vision-url")publicStringvisionByUrl(@RequestParamStringimageUrl,@RequestParam(defaultValue="描述这张图片")Stringquestion){returnchatService.understandImageByUrl(imageUrl,question);}}4.3 准备测试图片
在src/main/resources/images/目录下放一张测试图片(如test.jpg),用于验证图像理解功能。你可以随便找一张照片放进去。
五、运行与演示
5.1 启动应用
确保DASHSCOPE_API_KEY环境变量已设置,启动 Spring Boot 应用。
5.2 测试文本对话
浏览器访问:
http://localhost:8080/ai/chat?msg=用一句话介绍阿里云百炼平台返回类似:
阿里云百炼是一站式大模型服务平台,提供通义千问系列模型的 API 调用、模型微调和应用部署能力。5.3 测试流式对话
使用 curl 查看打字机效果:
curl-N"http://localhost:8080/ai/stream?msg=用100字介绍Spring AI Alibaba"你会看到逐字蹦出的文本流。
5.4 测试图像理解
先确保src/main/resources/images/test.jpg文件存在,然后浏览器访问:
http://localhost:8080/ai/vision?question=描述这张图片里的内容如果你测试通过 URL 的图片识别接口:
http://localhost:8080/ai/vision-url?imageUrl=https://example.com/cat.jpg&question=这是什么动物返回结果类似:
这是一只橘色的猫,正趴在灰色的沙发上睡觉,画面光线柔和,整体氛围很温馨。六、常见问题与避坑提示
问题一:API Key 不生效或 401 错误
原因:环境变量未正确设置,或 Key 格式错误。
排查:
- 终端执行
echo $DASHSCOPE_API_KEY(Mac/Linux)或echo $env:DASHSCOPE_API_KEY(PowerShell)确认变量有值。 - IDEA 中需要在 Run Configuration 中手动添加环境变量,它不会自动读取系统终端的环境变量。
- 百炼 API Key 的格式通常以
sk-开头,确认是否完整复制。
问题二:图片上传报错 “url error, please check url”
HTTP 400 - {"code":"InvalidParameter","message":"url error, please check url!"}这是百炼多模态接口的一个常见问题。Spring AI Alibaba 的多模态功能需要额外配置——必须在DashScopeChatOptions中开启withMultiModal(true),否则百炼会把图片地址当成文本参数处理,导致 URL 解析错误。遇到这个错误时,请检查是否已添加.withMultiModal(true)配置。
问题三:模型名称无效
model "xxx" not found原因:配置的模型名称不在百炼支持的列表中。
解决:登录百炼控制台查看可用模型列表。注意文本模型和多模态模型是分开的:
- 文本对话用:
qwen-turbo、qwen-plus、qwen-max - 多模态(图像理解)用:
qwen-vl-max、qwen-vl-plus
问题四:接口超时
java.net.SocketTimeoutException: Read timed out百炼接口在处理长文本或图片时可能需要较长时间。可以在application.yml中增加超时配置:
spring:ai:dashscope:chat:options:timeout:120s# 增加超时时间问题五:多模态模型不支持视频格式
如果你尝试传入视频文件但调用失败,可能是因为当前多模态模型只支持 image 格式。注意 qwen-vl-max 支持图片和视频,但需要通过message.getMetadata().put(DashScopeApiConstants.MESSAGE_FORMAT, MessageFormat.VIDEO)来指定视频格式。对于其他多模态模型,请查阅百炼官方文档确认具体支持范围。
七、小结与下一步预告
本篇回顾
- 理解了 Spring AI Alibaba 的定位:Spring AI 的阿里云落地实现,一套标准 API 打通百炼全系模型。
- 完成了环境搭建:添加
spring-ai-alibaba-starter-dashscope依赖,配置DASHSCOPE_API_KEY。 - 实现了文本对话和流式输出——代码与前面几篇完全一致。
- 掌握了多模态图像理解:通过
DashScopeChatOptions.withMultiModal(true)开启多模态,将图片作为media附加到消息中。
和前面几篇的呼应
还记得第 3 篇我们说的“改配置,不改代码”吗?从 DeepSeek 到 OpenAI 到 Ollama 再到今天的百炼,你的业务代码始终是:
chatClient.prompt().user(message).call().content();这正是 Spring AI 生态最核心的价值——让你专注于业务逻辑,而不是模型接入细节。
下一步预告
现在我们已经掌握了文本对话、流式输出、结构化输出和多模态能力。下一篇,我们将构建一个“记得你的聊天机器人”——引入对话记忆(Chat Memory),让 AI 能记住上下文,实现真正的多轮对话。我们会深入 Spring AI 的ChatMemory抽象、会话持久化,并演示如何在不同 AI 客户端之间灵活切换。
下一篇《记忆与持久化:构建一个记得你的聊天机器人》见。
本系列博客基于 Spring AI 1.1.6 和 Spring AI Alibaba 1.1.2.0 版本编写。Spring AI Alibaba 生态更新频繁,建议在实际开发时查阅 Spring AI Alibaba 官方文档 获取最新版本信息和 API 变更。百炼平台模型列表和计费规则请参考 阿里云百炼官方文档。