
本示例演示如何通过 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: 10014
spring:
application:
name: spring-ai-alibaba-dashscope-chat-example
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
ai:
openai:
api-key: ${AI_DASHSCOPE_API_KEY}
base-url: https://dashscope.aliyuncs.com/compatible-mode
chat:
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 {
// 默认使用JPEG
return "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: 10MB
max-request-size: 10MB