352-Spring AI Alibaba OpenAI DashScope 多模态示例

本示例演示如何通过 Spring AI 的 OpenAI 客户端接口调用阿里云 DashScope 的多模态模型(如 qwen-vl-max-latest),实现图片分析功能。虽然依赖了 Spring AI 的 OpenAI 模块,但底层实际调用的是 DashScope 的兼容模式接口。
1. 案例目标
我们将创建一个 Spring Boot 应用,实现以下功能:
- 图片 URL 分析:通过 GET 请求传入图片 URL 和描述文本,由 DashScope 多模态模型分析图片内容。
- 图片文件上传分析:通过 POST 请求上传本地图片文件,结合提示词进行多模态分析。
2. 技术栈与核心依赖
- Spring Boot 3.x
- Spring AI OpenAI Starter(用于调用 DashScope 兼容模式接口)
- Maven(项目构建工具)
在 pom.xml 中,你需要引入以下核心依赖:
<dependencies><!-- Spring Web 用于构建 RESTful API --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring AI OpenAI Starter --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-openai</artifactId></dependency>
</dependencies>3. 项目配置
在 src/main/resources/application.yml 文件中,配置 DashScope API Key 和服务地址。
server:port: 10014spring:application:name: spring-ai-alibaba-dashscope-chat-exampleservlet:multipart:max-file-size: 10MBmax-request-size: 10MBai:openai:api-key: ${AI_DASHSCOPE_API_KEY}base-url: https://dashscope.aliyuncs.com/compatible-modechat:options:model: qwen-plus-latest重要提示:请将 AI_DASHSCOPE_API_KEY 环境变量设置为你从阿里云获取的有效 API Key。你也可以直接将其写在配置文件中,但这不推荐用于生产环境。
4. 编写 Java 代码
4.1 主应用类
OpenAiDashScopeMultiModelApplication.java - Spring Boot 应用的入口点。
package com.alibaba.cloud.ai.example.multi;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class OpenAiDashScopeMultiModelApplication {public static void main(String[] args) {SpringApplication.run(OpenAiDashScopeMultiModelApplication.class, args);}
}4.2 控制器类
OpenAiChatClientController.java - 实现多模态图片分析功能的核心控制器。
package com.alibaba.cloud.ai.example.multi.controller;import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.content.Media;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import java.net.URI;@RestController
@RequestMapping("openai/client")
public class OpenAiChatClientController {private final ChatClient chatClient;public OpenAiChatClientController(@Qualifier("openAiChatModel") ChatModel chatModel) {chatClient = ChatClient.builder(chatModel).defaultAdvisors(new SimpleLoggerAdvisor()).defaultOptions(OpenAiChatOptions.builder().temperature(0.7).build()).build();}/*** 图片分析接口 - 通过 URL* 使用 OpenAI 多模态模型分析图片内容*/@GetMapping("/image/analyze/url")public String analyzeImageByUrl(@RequestParam(defaultValue = "请分析这张图片的内容") String prompt,@RequestParam String imageUrl) {try {// 创建包含图片的用户消息String mineType = determineMimeTypeFromUrl(imageUrl);Media media = Media.builder().data(new URI(imageUrl)).mimeType(MimeTypeUtils.parseMimeType(mineType)).build();UserMessage message = UserMessage.builder().text(prompt).media(media).build();// 创建提示词,使用 OpenAI 多模态模型Prompt chatPrompt = new Prompt(message,OpenAiChatOptions.builder().model("qwen-vl-max-latest")  // 使用 OpenAI 视觉模型.temperature(0.7).maxTokens(1000).build());// 调用模型进行图片分析return chatClient.prompt(chatPrompt).call().content();} catch (Exception e) {return "图片分析失败: " + e.getMessage();}}/*** 图片分析接口 - 通过文件上传*/@PostMapping("/image/analyze/upload")public String analyzeImageByUpload(@RequestParam(defaultValue = "请分析这张图片的内容") String prompt,@RequestParam("file") MultipartFile file) {try {// 验证文件类型if (!file.getContentType().startsWith("image/")) {return "请上传图片文件";}// 创建包含图片的用户消息Media media = new Media(MimeTypeUtils.parseMimeType(file.getContentType()), file.getResource());UserMessage message = UserMessage.builder().text(prompt).media(media).build();// 创建提示词,启用多模态模型// 创建提示词,使用 OpenAI 多模态模型Prompt chatPrompt = new Prompt(message,OpenAiChatOptions.builder().model("qwen-vl-max-latest")  // 使用 OpenAI 视觉模型.temperature(0.7).maxTokens(1000).build());// 调用模型进行图片分析return chatClient.prompt(chatPrompt).call().content();} catch (Exception e) {return "图片分析失败: " + e.getMessage();}}/*** 根据URL确定MIME类型* @param imageUrl 图片URL* @return MIME类型字符串*/private String determineMimeTypeFromUrl(String imageUrl) {String lowerUrl = imageUrl.toLowerCase();if (lowerUrl.endsWith(".jpg") || lowerUrl.endsWith(".jpeg")) {return "image/jpeg";} else if (lowerUrl.endsWith(".png")) {return "image/png";} else if (lowerUrl.endsWith(".gif")) {return "image/gif";} else if (lowerUrl.endsWith(".webp")) {return "image/webp";} else {// 默认使用JPEGreturn "image/jpeg";}}
}5. 环境准备
- API 密钥配置:配置阿里云 DashScope 的 API Key:export AI_DASHSCOPE_API_KEY=your_api_key_here
- 依赖服务:无需额外依赖,DashScope 服务通过公网访问。
6. 运行与测试
- 构建项目:mvn clean install
- 运行服务:cd openai-dashscope-multi-model mvn spring-boot:run
- 访问接口:服务启动后,默认监听端口 10014。
测试 1:图片 URL 分析
使用 curl 或浏览器访问以下 URL,分析网络图片:
http://localhost:10014/openai/client/image/analyze/url?imageUrl=https://example.com/image.jpg&prompt=请描述这张图片中的内容预期响应:
这是一张[图片内容描述]的图片。图片中包含[详细描述]...
测试 2:图片文件上传分析
使用 curl 或 Postman 上传本地图片文件:
curl -X POST -F "file=@/path/to/your/image.jpg" -F "prompt=请分析这张图片" http://localhost:10014/openai/client/image/analyze/upload预期响应:
根据您上传的图片,我可以看到[图片内容分析]...
7. 实现思路与扩展建议
实现思路
本示例的核心思想是利用 Spring AI 的 OpenAI 兼容接口调用 DashScope 多模态模型。关键点包括:
- 兼容模式配置:通过设置 base-url为 DashScope 的兼容模式地址,使 Spring AI OpenAI 客户端能够调用 DashScope 服务。
- 多模态消息构建:使用 UserMessage和Media对象构建包含图片和文本的多模态消息。
- 模型选择:通过 OpenAiChatOptions指定使用 DashScope 的多模态模型qwen-vl-max-latest。
扩展建议
- 多模型支持:扩展控制器以支持多种多模态模型,如 qwen-vl-plus等,通过参数动态选择模型。
- 批量处理:添加批量图片分析接口,支持一次请求分析多张图片。
- 结果缓存:对相同图片的分析结果进行缓存,提高响应速度并降低 API 调用成本。
- 异步处理:对于大文件或复杂分析场景,实现异步处理机制,避免请求超时。
- 安全增强:添加文件类型验证、大小限制和内容安全检查,防止恶意文件上传。
- 自定义提示词模板:实现提示词模板管理,支持不同场景下的定制化分析需求。
8. 特性说明
多模态兼容性
通过以下配置切换 DashScope 多模态模型:
spring:ai:openai:base-url: https://dashscope.aliyuncs.com/compatible-mode  # DashScope 兼容模式chat:options:model: qwen-vl-max-latest  # DashScope 多模态模型文件上传限制
默认支持最大 10MB 文件上传,可通过 application.yml 修改:
spring:servlet:multipart:max-file-size: 10MBmax-request-size: 10MB