Spring Boot 集成通义千问大模型Qwen-VL:从配置到实战

        随着人工智能技术的发展,越来越多的企业开始利用大模型提升自身产品的智能化水平。阿里巴巴的通义千问大模型作为国内领先的语言模型之一,为企业提供了强大的自然语言处理能力。本文将详细介绍如何在Spring Boot项目中集成通义千问大模型,并通过具体的代码示例展示其实现过程。

一、环境准备

1. 导入依赖

        首先,在项目的pom.xml文件中添加通义千问SDK的依赖:

<!-- https://mvnrepository.com/artifact/com.alibaba/dashscope-sdk-java -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dashscope-sdk-java</artifactId>
    <version>the-latest-version</version>
</dependency>

        请前往mvnrepository获取最新的版本号。

2. 配置文件

        在application.yml中添加必要的API密钥和提示词配置:

spring:
  ai:
    api-key: sk-58xxxxxxxxxxxxxxxxx
    prompt: 注意,回答结果言简意赅

二、核心组件实现

1. 配置类

        创建一个配置类QwenVl来读取配置文件中的API密钥和提示词:

@Component
public class QwenVl implements InitializingBean {

    @Value("${spring.ai.api-key}")
    private String apiKey;

    @Value("${spring.ai.prompt}")
    private String prompt;

    public static String QWENVL_API_KEY;
    public static String PROMPT;

    @Override
    public void afterPropertiesSet() {
        QWENVL_API_KEY = apiKey;
        PROMPT = prompt;
    }
}

2. 通用工具类

        接下来,编写一个工具类QwenVlUtils,用于封装与通义千问模型交互的所有功能:

/**
 * 通义千问图文识别工具类
 *
 * @author zk
 * @date 2024/8/13
 */
public class QwenVlUtils {

    private static final String ERROR_MSG = "该%s文件类型暂不支持AI识别";

    /**
     * 识别单张图片,返回识别结果
     */
    public static String identify(@NotNull String url) throws NoApiKeyException, UploadFileException {
        if (url.startsWith("file")) {
            return identifyByLocalFile(url);
        }

        MultiModalConversation conv = new MultiModalConversation();
        MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
                .content(Arrays.asList(Collections.singletonMap("image", url),
                        Collections.singletonMap("text", QwenVl.PROMPT))).build();

        MultiModalConversationParam param = MultiModalConversationParam.builder()
                .model(MultiModalConversation.Models.QWEN_VL_PLUS)
                .apiKey(QwenVl.QWENVL_API_KEY)
                .message(userMessage)
                .build();

        MultiModalConversationResult result = conv.call(param);
        String msg = (String) result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text");
        System.err.println("qwen-AI-VL 回答结果  result:" + result);
        return msg;
    }

    /**
     * 识别本地单张图片,返回识别结果
     */
    @SneakyThrows
    public static String identifyByLocalFile(@NotNull String url) throws ApiException, NoApiKeyException, UploadFileException {
        MultiModalConversation conv = new MultiModalConversation();
        MultiModalMessage userMessage = MultiModalMessage.builder().role(Role.USER.getValue())
                .content(Arrays.asList(new HashMap<String, Object>() {{
                    put("image", url);
                }},
                        new HashMap<String, Object>() {{
                    put("text", QwenVl.PROMPT);
                }})).build();

        MultiModalConversationParam param = MultiModalConversationParam.builder()
                .model(MultiModalConversation.Models.QWEN_VL_PLUS)
                .apiKey(QwenVl.QWENVL_API_KEY)
                .message(userMessage)
                .build();

        Flowable<MultiModalConversationResult> result = conv.streamCall(param);
        MultiModalConversationResult last = result.blockingLast();
        String msg = (String) last.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text");
        System.err.println("qwen-AI-VL 结果  result:" + msg);

        // 识别完,删除文件
        URL url1 = new URL(url);
        String path = url1.getPath();
        if (path.startsWith("/")) {
            path = path.substring(1);
        }
        Path filePath = Paths.get(path);
        Files.delete(filePath);
        return msg;
    }
}

        其中,除了PROMPT提示词,读者也可以自定义要与模型交互的提问内容,而后和PROMPT拼接到一起即可。其中本地文件上传给模型识别,笔者是通过文件上传到本地,然后通过一些操作得到其需要的资源路径,如: file://D:/images/test.png,最后识别完成后,把这个上传的临时文件进行删除。当然,具体的操作可以随各自开发者的业务要求进行变化。

        注意Windows系统下,本地上传需要传入的文件路径:file:///{文件的绝对路径}

示例:file:///home/images/test.png

        而Linux或macOS系统下的传入的文件路径:file://{文件的绝对路径}

示例:file:///D:images/test.png。

3. 枚举类

        定义一个枚举类QwenVLImageEnum来存储所有支持的图片格式及其对应的MIME类型:

@Getter
public enum QwenVLImageEnum {
    BMP("image/bmp", ".bmp"),
    DIB("image/bmp", ".dib"), // 注意:DIB与BMP使用相同的MIME类型
    ICNS("image/icns", ".icns"),
    ICO("image/x-icon", ".ico"),
    JPEG("image/jpeg", ".jfif", ".jpe", ".jpeg", ".jpg"),
    JPEG2000("image/jp2", ".j2c", ".j2k", ".jp2", ".jpc", ".jpf", ".jpx"),
    PNG("image/png", ".apng", ".png"),
    SGI("image/sgi", ".bw", ".rgb", ".rgba", ".sgi"),
    TIFF("image/tiff", ".tif", ".tiff"),
    WEBP("image/webp", ".webp");

    private final String mimeType;
    private final String[] extensions;

    QwenVLImageEnum(String mimeType, String... extensions) {
        this.mimeType = mimeType;
        this.extensions = extensions;
    }

    public static boolean checkExtension(String extension) {
        for (QwenVLImageEnum format : values()) {
            for (String ext : format.getExtensions()) {
                if (ext.equalsIgnoreCase(extension)) {
                    return true;
                }
            }
        }
        return false;
    }
}

        对于输入的图片,图片文件大小不超过10MB。当然,笔者这里并没有做对图片大小的判断,后续开发者可以自己加上这一块的逻辑。

三、控制层接口

        在Spring Boot应用中添加一个RESTful API接口,用于接收图片链接并调用QwenVlUtils进行识别:        

@RestController
@RequestMapping("/ai")
public class AiController {

    /**
     * 通过AI识别
     *
     * @param url 图片URL
     */
    @GetMapping("/identify")
    public ResponseEntity<String> identify(@RequestParam String url) {
        try {
            String res = QwenVlUtils.identify(url);
            return ResponseEntity.ok(res);
        } catch (Exception e) {
            return ResponseEntity.badRequest().body("识别失败,上传的临时文件或已删除,请重新上传");
        }
    }
}

四、最后

        通过上述步骤,我们不仅实现了Spring Boot项目与通义千问大模型的集成,还展示了如何通过简单的API接口调用来实现图片识别功能。这为开发者提供了快速接入AI技术的途径,同时也为企业的智能化转型提供了有力支持。未来,随着技术的不断进步,相信会有更多类似的工具和服务涌现出来,进一步推动AI技术在各行各业的应用与发展。

  • 16
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值