SpringAI之多模态
多模态是指表达或感知事物的方式,例如视觉、听觉、嗅觉。对应的信息传递媒介可以是不同类型的数据,如文本、图像、声音、视频等。多模态就是从多个模态表达或感知事物。大部分情况与大模型交互都是基于普通文本输入,只有需要解析图片等其他类型数据时才会用到多模态模型。deepseekqwen-plus等模型都是纯文本模型,在 Ollama 和百炼平台,也能找到很多多模态模型。以 Ollama 为例,在搜索时点击
1_多模态介绍
多模态是指表达或感知事物的方式,例如视觉、听觉、嗅觉。
对应的信息传递媒介可以是不同类型的数据,如文本、图像、声音、视频等。
多模态就是从多个模态表达或感知事物。
大部分情况与大模型交互都是基于普通文本输入,只有需要解析图片等其他类型数据时才会用到多模态模型。
deepseek 、qwen-plus 等模型都是纯文本模型,在 Ollama 和百炼平台,也能找到很多多模态模型。
以 Ollama 为例,在搜索时点击 Vision,就能找到支持图像识别的模型:

在阿里云百炼平台也一样:

阿里云百炼平台的 qwen-omni 模型是支持文本、图像、音频、视频输入的全模态模型,还能支持语音合成功能,非常强大。
2_定义模型
创建用于多模态对话的 ChatClient:
@Bean
public ChatClient chatClient(OpenAiChatModel model, ChatMemory chatMemory) {
return ChatClient.builder(model)
.defaultOptions(ChatOptions.builder().model("qwen-omni-turbo").build())
.defaultSystem("你是我的助手,名字叫小微")
.defaultAdvisors(
new SimpleLoggerAdvisor(),
MessageChatMemoryAdvisor.builder(chatMemory).build()
).build();
}
application.yaml 配置文件中 spring.ai.openai.chat.options.model 属性已经指定了 qwen-plus 为默认的 Chat 模型(由于其他业务使用的原因,不能改变)。
也就是说会产生冲突,因此创建 Bean 时使用 defaultOptions 方法指定了模型名称。
3_多模态对话
定义 ChatController 接口,让它支持文件上传和多模态对话。
@RestController
@RequestMapping("/ai")
@RequiredArgsConstructor
public class ChatController {
private final ChatClient chatClient;
private final ChatHistoryRepository chatHistoryRepository;
@RequestMapping(value = "/chat", produces = "text/html;charset=utf-8")
public Flux<String> chat(String prompt, String chatId, List<MultipartFile> files) {
// 请求聊天前先保存会话id,已经做了重复添加的校验
chatHistoryRepository.save("chat", chatId);
// 请求文本模型
if (files == null || files.isEmpty()) {
return textChat(prompt, chatId);
}
// 多模态模型
return multiModelChat(prompt, chatId, files);
}
private Flux<String> multiModelChat(String prompt, String chatId,
@RequestParam(required = false) List<MultipartFile> files) {
//1.解析多媒体
List<Media> medias = files.stream().map(file ->
new Media(
MimeType.valueOf(Objects.requireNonNull(file.getContentType())),
file.getResource()
)).toList();
return chatClient.prompt()
.user(u -> u.text(prompt).media(medias.toArray(Media[]::new)))
.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, chatId))
.stream().content();
}
private Flux<String> textChat(String prompt, String chatId) {
return chatClient.prompt()
.user(prompt)
.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, chatId))
.stream().content();
}
}
4_测试
进入聊天页面,可以上传图片让 AI 来识别了:

但是存在其他问题,比如对于音频数据格式的解析 qwen 与 OpenAI 并不兼容,所以会报错。
可以使用 spring-alibaba-ai ,或者重写 OpenAiModel 的实现逻辑。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)