Spring AI多模态接口开发

项目地址

创建项目

  1. 打开IDEA创建一个新的spring boot项目,填写项目名称和位置,类型选择maven,组、工件、软件包名称可以自定义,JDK选择17+即可,java语言标准和JDK相同即可
    在这里插入图片描述
  2. 配置Spring Boot版本和开发所需的依赖,主要如下图所示
    • Spring Boot版本可以选择3.2.5或者更高的版本(作者使用3.2.5和3.2.6(SNAPSHOT)可以正常开发)
    • Spring Boot DevTools:spring项目热部署工具,修改完代码(不含application和pom配置文件)即刻热部署项目
    • Lombok:通过配置快速配置对象的get、set、toString
    • Spring AI:Spring AI是一个用于AI工程的应用框架
      在这里插入图片描述
  3. 创建完成后,项目结构大体如下(这里删除了无用的maven文件内容、修改application的文件格式为yaml)
    在这里插入图片描述

配置项目

  • 注意:修改pom文件,重新下载spring ai依赖需要科学上网,请确保网络连接没有问题
  1. 打开项目的pom文件,修改spring ai的版本(项目默认使用稳定版0.8.1)
    • 主要注意默认的spring ai版本和配置依赖jar包仓库(maven仓库中还没有spring ai的依赖)
<properties>
    <java.version>21</java.version>
    <spring-ai.version>0.8.1</spring-ai.version>
</properties>

<repositories>
    <repository>
        <id>spring-snapshots</id>
        <name>Spring Snapshots</name>
        <url>https://repo.spring.io/snapshot</url>
        <releases>
            <enabled>false</enabled>
        </releases>
    </repository>
</repositories>
  1. 配置application文件(api-key的获取参考Spring AI开发前期开发指导
spring:
  application:
    name: ChatMultiModel
  ai:
    openai:
      api-key: hk-xxx #请使用自己的api-key
      base-url: https://api.openai-hk.com
server:
  port: 8084

接口开发

import jakarta.annotation.Resource;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.chat.messages.Media;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.MediaType;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@RestController
public class MultiModelController {

    @Resource
    private ChatClient chatClient;
    @PostMapping("/ai/multiChatTest")
    public Object multiChatTest() throws IOException {
        byte[] imageData = new ClassPathResource("/multimodal.test.png").getContentAsByteArray();

        var userMessage = new UserMessage("请解释在图片中有什么?",
                List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData)));

        ChatResponse response = chatClient.call(
                new Prompt(
                        List.of(userMessage),
                        OpenAiChatOptions
                                .builder()
                                .withModel(OpenAiApi.ChatModel.GPT_4_VISION_PREVIEW.getValue())
                                .build()
                )
        );
        return response.getResult().getOutput();
    }

    /**
     * 多模态对话
     * @param msg 文本信息
     * @param imageUrl 在线图片地址信息
     */
    @PostMapping("/ai/multiChat")
    public Object multiChat(String msg,String imageUrl){
        // 一张电脑主板背部接口的图片地址 https://img-blog.csdnimg.cn/direct/761932564968468690c3d52c889f329a.png
        UserMessage userMessage = new UserMessage(msg, List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageUrl)));
        ChatResponse response = chatClient.call(
                new Prompt(
                        List.of(userMessage),
                        OpenAiChatOptions
                                .builder()
                                .withModel(OpenAiApi.ChatModel.GPT_4_VISION_PREVIEW.getValue())
                                .build()
                )
        );
        return response.getResult().getOutput();
    }

    /**
     * 多模态批量图片上传对话
     * @param msg 文本信息
     * @param imageFiles 图片内容 图片过大提示错误
     */
    @PostMapping("/ai/multiChat2")
    public Object multiChatWithUploadImage(String msg, List<MultipartFile> imageFiles) {
        List<Media> mediaList = new ArrayList<>();

        for (MultipartFile file : imageFiles) {
            try {
                byte[] imageData = file.getBytes();
                MediaType mediaType = MediaType.valueOf(Objects.requireNonNull(file.getContentType()));
                mediaList.add(new Media(mediaType, imageData));
            } catch (IOException e) {
                // 处理读取图片文件时的异常
                e.printStackTrace();
            }
        }

        UserMessage userMessage = new UserMessage(msg, mediaList);

        ChatResponse response = chatClient.call(
                new Prompt(
                        List.of(userMessage),
                        OpenAiChatOptions
                                .builder()
                                .withModel(OpenAiApi.ChatModel.GPT_4_VISION_PREVIEW.getValue())
                                .build()
                )
        );

        return response.getResult().getOutput();
    }
}

结果测试

测试接口测试

  • http://localhost:8084/ai/multiChatTest
{
    "messageType": "ASSISTANT",
    "metadata": {
        "finishReason": "STOP",
        "role": "ASSISTANT",
        "id": "chatcmpl-9NbNVih5y0iFMCmC2UBJpc8D9kLms",
        "messageType": "ASSISTANT"
    },
    "content": "图片中是一个金属制的水果篮,篮子的设计简约但优雅,呈现出一种现代感。水果篮中放着两根黄色的香蕉和至少一个红色的苹果。香蕉的表面有斑点,显示它们成熟了,这通常意味着它们会更加甜。背景是模糊的,所以我们无法确定具体的环境,但可以猜测这可能是家庭厨房或餐厅的一角。",
    "media": []
}

在线图片接口测试

在这里插入图片描述

{
    "messageType": "ASSISTANT",
    "metadata": {
        "finishReason": "STOP",
        "role": "ASSISTANT",
        "id": "chatcmpl-9NbZyTNrExouUI9hwaEkLMQKR5mzh",
        "messageType": "ASSISTANT"
    },
    "content": "这张图片展示的是一台计算机的后部接口面板。从左至右,我们可以看到:\n\n- 一个PS/2接口,通常用于连接键盘或鼠标。\n- 两个蓝色的USB 3.1或更高版本接口。\n- 一个DisplayPort接口,用于连接显示器。\n- 一个HDMI接口,同样用于连接显示器。\n- 四个红色的USB 3.2 Gen2接口,提供高速数据传输能力。\n- 一个USB Type-C接口。\n- 一个以太网接口,标有\"2.5 Gbps LAN\",表示其支持最高2.5吉比特每秒的网络速度。\n- 一组音频接口,包括麦克风输入(粉色)、线出(绿色)、以及其他音频输入/输出(橙色、灰色、蓝色)。\n- 两个Wi-Fi天线连接口,用于连接无线网络。\n- 一个内置Wi-Fi模块的标识,有无线网络信号的图标。\n\n整个面板设计呈现出现代化和高性能的特点,适用于高端桌面计算机主板。",
    "media": []
}

本地图片接口测试

在这里插入图片描述

{
    "messageType": "ASSISTANT",
    "metadata": {
        "finishReason": "STOP",
        "role": "ASSISTANT",
        "id": "chatcmpl-9Nc3JZ3cVGCIlsdJrlHnJYT7O5rbu",
        "messageType": "ASSISTANT"
    },
    "content": "第一张图片是一幅数字艺术作品,展示了一个多边形风格的狼头图案。这幅图使用了丰富的颜色和几何形状,表现了一种现代和抽象的风格。背景是纯黑色的,突出了狼头的彩色轮廓。\n\n第二张图片显示的是一个电脑系统信息的截图,界面是中文。根据截图上的信息,这台电脑运行的是64位的Windows 10操作系统,版本为22H2,支持DirectX 12。处理器是英特尔Xeon E5-2698B v3,频率为2.00GHz,共有22个核心。内存为128GB,使用的是DDR3类型,频率为1866MHz,是32GB内存条组成的四通道配置。图形卡为NVIDIA GeForce RTX 3060,带12GB显存。主板型号是华硕X99M-PLUS D3,芯片组为Lynx Point Q87。存储方面,有一块2TB(2048GB)的固态硬盘。网络接口为Realtek RTL8168/8111/8112 Gigabit Ethernet Controller。声卡是High Definition Audio。系统版本底部提示有Win11的升级提示。",
    "media": []
}
### Spring AI DeepSeek知识库文档及相关资源 DeepSeek作为集成于Spring AI框架下的高级功能模块,旨在通过增强型的知识图谱技术实现更精准的数据检索与分析能力。此模块不仅依赖传统的机器学习模型训练方式,还特别集成了RAG(Retrieval-Augmented Generation)机制[^2]。 #### 特性描述 - **动态数据获取**:借助RAG特性,当面对用户提出的复杂查询请求时,系统能够实时从指定的新数据源中抽取最新信息并将其融合至现有知识体系内。 - **高效索引构建**:针对特定领域内的大量非结构化文本资料建立高效的索引结构,支持快速定位及关联挖掘操作。 - **多模态理解力**:除了处理纯文字内容外,亦具备解析图像、音频等多种媒体形式的能力,从而拓宽了应用场景范围。 #### 开发者指南概览 为了帮助开发者更好地理解和应用这一强大工具,在官方提供的开发手册中涵盖了以下几个方面: 1. **环境搭建说明** - 描述如何安装必要的依赖包以及配置运行环境的具体步骤。 2. **API接口介绍** - 列举主要的服务端点及其参数定义,便于第三方应用程序调用。 3. **案例研究分享** - 收录了一系列实际项目实施过程中积累的成功经验和技术细节探讨文章。 4. **社区交流平台链接** - 提供指向活跃的技术讨论区网址,方便遇到问题时寻求外界支援。 ```python import requests def fetch_deepseek_docs(): url = 'https://springai.deepseek/docs' response = requests.get(url) if response.status_code == 200: return response.text else: raise Exception('Failed to load page') print(fetch_deepseek_docs()) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值