SpringAI之多模态

发布于:2025-07-27 ⋅ 阅读:(21) ⋅ 点赞:(0)

1_多模态介绍

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

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

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

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

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

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

img

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

img

阿里云百炼平台的 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 来识别了:

img

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

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


网站公告

今日签到

点亮在社区的每一天
去签到