基于SpringAI使用云端大模型解析OSS中的文件实现多模态理解对话

基于SpringAI使用云端大模型解析OSS中的文件实现多模态理解对话

一、总体设计:多模态对话的完整链路

多模态对话涉及三个关键环节:

  1. 图片上传到对象存储(OSS)
    • 用户上传图片 → 由 aimin-ai 转发给 aimin-drug → OSS
    • aimin-drug 返回可公开访问的 OSS URL
  2. 将 OSS 图片 URL 作为 Vision 模型输入(例如 Qwen-VL-Max)
    • Spring AI 支持直接使用 .media() 上传 URL 或 Resource 对象给模型
  3. 结合文本 + 图片做多模态推理(Vision Chat)
    • AI 根据图片内容生成诊断分析

最终架构示意如下:

1
2
3
4
5
用户 → aimin-ai → aimin-drug → OSS  

AI Vision 模型(Spring AI ChatClient)

流式返回

二、Controller 层:对外暴露多模态对话接口

多模态接口如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Operation(summary = "多模态对话功能")
@PostMapping(value = "/vision", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Flux<String> visionChat(
@RequestParam("files") List<MultipartFile> files,
@RequestParam("question") String question
) throws IOException {


// 1. 调用 aimin-drug 上传 OSS
Result<List<DrugImgVO>> result = drugFeign.batchUpload(files);

if (result == null || result.getData() == null || result.getData().isEmpty()) {
return Flux.just("图片上传失败,无法进行分析");
}

// 2. 获取 OSS 图片 URL
String ossUrl = result.getData().getFirst().getExternalPath();
log.info("OSS 图片 URL: {}", ossUrl);

Resource resource = new UrlResource(ossUrl);

return chatClient
.prompt()
.system("你是一个医学影像分析助手,请根据图片内容进行诊断建议。")
.user(u -> u.text(question)
.media(MimeTypeUtils.IMAGE_PNG, resource))
.advisors(a -> a.param(ChatMemory.DEFAULT_CONVERSATION_ID, conversationId))
.stream()
.content();
}
  • 接收用户上传的图片 + 文本问题
  • 通过 Feign 调用 aimin-drug 微服务上传图片
    • 因为 aimin-drug 已经封装了一套非常完善的文件上传 + OSS 外链体系
  • 从 aimin-drug 返回的 VO 中获取 OSS 外链URL,例如:https://oss-xxx.aliyuncs.com/rag/2025/11/25/xxxxxx.png
  • 用 UrlResource 包装 URL
    • Spring AI 的 .media() 支持:
      • FileSystemResource
      • UrlResource
      • ClassPathResource
      • ByteArrayResource等多种资源类型
  • 构建 prompt,并将图片作为输入传入模型
  • 绑定多轮会话记忆
  • 最后流式返回

三、文件上传与 OSS 外链生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public Result<?> uploadDrugImg(List<MultipartFile> files) {

List<FileUploadResult> fileUploadResults =
fileService.batchUploadImages(files, Constants.DRUG_FILE_MODULE);

if (fileUploadResults.isEmpty()) {
return Result.error("图片上传失败");
}

List<DrugImg> list = objectConvertor.toDrugImg(fileUploadResults);

// 将上传结果缓存(省略)

List<DrugImgVO> drugImgVOS = objectConvertor.toVO(list);

drugImgVOS.forEach(img -> {
img.setExternalPath(fileService.externalPath(img.getPath()));
});

return Result.success(drugImgVOS);
}
  1. 将图片上传至 OSS
  2. 把 OSS 的内部路径转换为可外部访问的 URL
  3. 外链URL返回给 aimin-ai 作为 Vision 模型输入

四、Spring AI Vision 模型调用:多模态的核心

1
2
.user(u -> u.text(question)
.media(MimeTypeUtils.IMAGE_PNG, resource))

等价于告诉大模型:

  • 用户说这段话(question),并附带了一张图片,请结合图片理解并回答。

四、完整流程图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
用户上传图片 + 问题


aimin-ai (visionChat接口)
│ 通过Feign传文件

aimin-drug 微服务
│ 上传图片到 OSS

OSS 对象存储
│ 返回外链 externalPath

aimin-ai
│ 构造 UrlResource

Spring AI ChatClient

├── system:医学影像分析助手
├── user:文本 question
└── usermedia(图像 URL)

调用 Vision 模型(如 Qwen-VL-Max

流式推理返回 Flux<String>

前端实时显示诊断内容