> 技术文档 > SpringAI之多模态

SpringAI之多模态


文章目录

    • 1_多模态介绍
    • 2_定义模型
    • 3_多模态对话
    • 4_测试

1_多模态介绍

多模态是指表达或感知事物的方式,例如视觉、听觉、嗅觉。

对应的信息传递媒介可以是不同类型的数据,如文本、图像、声音、视频等。

多模态就是从多个模态表达或感知事物。

大部分情况与大模型交互都是基于普通文本输入,只有需要解析图片等其他类型数据时才会用到多模态模型。

deepseekqwen-plus 等模型都是纯文本模型,在 Ollama 和百炼平台,也能找到很多多模态模型。

以 Ollama 为例,在搜索时点击 Vision,就能找到支持图像识别的模型:

SpringAI之多模态

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

SpringAI之多模态

阿里云百炼平台的 qwen-omni 模型是支持文本、图像、音频、视频输入的全模态模型,还能支持语音合成功能,非常强大。

2_定义模型

创建用于多模态对话的 ChatClient:

@Beanpublic 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\")@RequiredArgsConstructorpublic 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 来识别了:

SpringAI之多模态

但是存在其他问题,比如对于音频数据格式的解析 qwen 与 OpenAI 并不兼容,所以会报错。

可以使用 spring-alibaba-ai ,或者重写 OpenAiModel 的实现逻辑。