SpringAI之多模态
文章目录
1_多模态介绍
多模态是指表达或感知事物的方式,例如视觉、听觉、嗅觉。
对应的信息传递媒介可以是不同类型的数据,如文本、图像、声音、视频等。
多模态就是从多个模态表达或感知事物。
大部分情况与大模型交互都是基于普通文本输入,只有需要解析图片等其他类型数据时才会用到多模态模型。
deepseek
、qwen-plus
等模型都是纯文本模型,在 Ollama 和百炼平台,也能找到很多多模态模型。
以 Ollama 为例,在搜索时点击 Vision,就能找到支持图像识别的模型:
在阿里云百炼平台也一样:
阿里云百炼平台的 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 来识别了:
但是存在其他问题,比如对于音频数据格式的解析 qwen 与 OpenAI 并不兼容,所以会报错。
可以使用 spring-alibaba-ai
,或者重写 OpenAiModel 的实现逻辑。