Spring AI 集成国内大模型实战:千问/豆包(含多模态)+ Spring Boot 4.0.1 全攻略

引言

Spring AI 作为 Spring 官方推出的 AI 开发框架,极大简化了 Java 开发者集成大模型的流程;而 Spring Boot 4.0.1 作为最新稳定版,凭借 Java 17+ 优化、原生镜像等特性,能让 AI 应用兼具开发效率与运行性能。

国内开发者常面临的痛点是:如何基于 Spring AI 适配阿里通义千问、字节豆包等本土化大模型?是否支持多模态(图文问答)能力?本文将从「环境准备→文本交互集成→多模态能力落地」全流程拆解,结合 Spring Boot 4.0.1 给出可直接复用的代码示例,覆盖国内模型的核心使用场景。

一、前置准备:基础环境与依赖配置

1.1 环境要求(必满足)

  • JDK:17+(Spring Boot 4.0.1 强制要求)
  • 构建工具:Maven 3.8.8+ / Gradle 8.0+
  • Spring 版本:Spring Boot 4.0.1 + Spring AI 0.8.1(最佳兼容组合)
  • 网络:确保服务器/本地能访问国内大模型 API 地址(国内服务器无需代理)

1.2 国内模型 API 密钥获取

模型 密钥获取平台 核心信息
通义千问 阿里云百炼大模型平台(dashscope.aliyun.com) 获取 API-KEY
字节豆包 火山方舟平台(volcengine.com/product/ark) 获取 api-key + 接口地址

1.3 基础依赖配置

先搭建 Spring Boot 4.0.1 项目,在 pom.xml 中添加核心依赖(后续按模型补充专属依赖):

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>4.0.1</version>
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>spring-ai-china-llm-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <!-- 核心基础依赖 -->
    <dependencies>
        <!-- Spring Web:提供接口测试能力 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Spring AI 核心依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-ai</artifactId>
            <version>0.8.1</version>
        </dependency>
        <!-- 测试依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

二、核心场景1:文本交互集成(最常用)

2.1 集成阿里通义千问(官方适配,推荐)

Spring AI 对千问有官方适配依赖,无需自定义客户端,配置即可用。

步骤1:添加千问专属依赖
xml 复制代码
<!-- Spring AI 通义千问适配依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-ai-dashscope</artifactId>
    <version>0.8.1</version>
</dependency>
步骤2:配置千问 API 信息

在 application.yml 中添加配置(替换为你的 API-KEY):

yaml 复制代码
spring:
  ai:
    dashscope:
      api-key: sk-xxxxxx  # 阿里云百炼平台获取的API-KEY
      chat:
        model: qwen-turbo  # 可选:qwen-plus、qwen-max、qwen-72b-chat等
        temperature: 0.7   # 随机性(0-1),值越小越精准
        max-tokens: 2048   # 最大生成token数
步骤3:编写千问文本调用代码

Spring AI 自动配置 DashScopeChatClient,直接注入使用:

java 复制代码
import org.springframework.ai.dashscope.DashScopeChatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 通义千问文本交互控制器
 */
@RestController
public class QwenTextController {

    @Autowired
    private DashScopeChatClient dashScopeChatClient;

    /**
     * 调用千问生成文本回答
     * @param prompt 提问内容
     * @return AI 回答
     */
    @GetMapping("/ai/qwen/chat")
    public String chatWithQwen(@RequestParam String prompt) {
        // 极简调用:直接传入Prompt
        return dashScopeChatClient.call(prompt);

        // 进阶调用(自定义参数):
        /*
        DashScopeChatRequest request = DashScopeChatRequest.builder()
                .prompt(prompt)
                .model("qwen-plus")  // 覆盖配置文件模型
                .temperature(0.5)
                .maxTokens(1000)
                .build();
        return dashScopeChatClient.call(request).getResult().getOutput().getContent();
        */
    }
}
步骤4:测试接口

启动项目后访问:
http://localhost:8080/ai/qwen/chat?prompt=用Spring Boot 4.0.1写一个用户注册接口

即可得到千问生成的标准化代码回答。

2.2 集成字节豆包(OpenAI 兼容模式)

豆包暂无 Spring AI 官方适配,但支持「OpenAI 兼容模式」,可复用 OpenAI 客户端调用。

步骤1:添加 OpenAI 适配依赖
xml 复制代码
<!-- Spring AI OpenAI 适配依赖(兼容豆包接口) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-ai-openai</artifactId>
    <version>0.8.1</version>
</dependency>
步骤2:配置豆包兼容接口信息
yaml 复制代码
spring:
  ai:
    openai:
      api-key: your-doubao-api-key  # 豆包平台获取的API-KEY
      base-url: https://www.doubao.com/api/v1  # 豆包OpenAI兼容接口前缀
      chat:
        model: doubao-pro  # 豆包模型名称(如doubao-pro、doubao-lite)
        temperature: 0.7
        max-tokens: 2048
步骤3:编写豆包文本调用代码
java 复制代码
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 豆包文本交互控制器(兼容OpenAI模式)
 */
@RestController
public class DouBaoTextController {

    @Autowired
    private OpenAiChatClient openAiChatClient;

    @GetMapping("/ai/doubao/chat")
    public String chatWithDouBao(@RequestParam String prompt) {
        // 调用逻辑与OpenAI完全一致
        return openAiChatClient.call(prompt);
    }
}

三、核心场景2:多模态集成(图文问答)

Spring AI 0.8.1+ 原生支持多模态能力(文本+图片),核心是将图片转为 Base64 编码后传入 Prompt,不同国内模型的适配方式略有差异。

3.1 千问多模态集成(官方适配,最便捷)

千问 qwen-vl/qwen-vl-plus 模型原生支持图文问答,Spring AI 提供完整封装。

步骤1:确认配置(复用千问依赖,修改模型为多模态版本)
yaml 复制代码
spring:
  ai:
    dashscope:
      api-key: sk-xxxxxx
      chat:
        model: qwen-vl  # 多模态专属模型
        temperature: 0.7
步骤2:编写千问多模态调用代码
java 复制代码
import org.springframework.ai.dashscope.DashScopeMultiModalChatClient;
import org.springframework.ai.image.ImageContent;
import org.springframework.ai.multimodal.MultiModalPrompt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.Base64;

/**
 * 千问多模态(图文问答)控制器
 */
@RestController
public class QwenMultiModalController {

    @Autowired
    private DashScopeMultiModalChatClient multiModalChatClient;

    /**
     * 上传图片+文本提问,调用千问图文问答
     * @param file 图片文件(PNG/JPG)
     * @param prompt 文本提问
     * @return 多模态回答
     * @throws Exception 图片编码异常
     */
    @PostMapping("/ai/qwen/multimodal/chat")
    public String multiModalChat(
            @RequestParam("file") MultipartFile file,
            @RequestParam("prompt") String prompt) throws Exception {
        
        // 1. 图片转Base64编码(千问要求图片为Base64格式)
        byte[] imageBytes = file.getBytes();
        String base64Image = Base64.getEncoder().encodeToString(imageBytes);
        
        // 2. 封装多模态Prompt:文本+图片
        ImageContent imageContent = new ImageContent("data:image/jpeg;base64," + base64Image);
        MultiModalPrompt multiModalPrompt = new MultiModalPrompt(prompt, imageContent);
        
        // 3. 调用千问多模态模型
        return multiModalChatClient.call(multiModalPrompt).getResult().getOutput().getContent();
    }
}
步骤3:测试多模态接口

通过 Postman/表单提交:

  • 请求方式:POST
  • 地址:http://localhost:8080/ai/qwen/multimodal/chat
  • 参数:
    • file:上传图片(如代码截图、流程图);
    • prompt:文本提问(如"分析这张图片的代码逻辑并优化")。

3.2 豆包多模态集成(兼容/自定义模式)

方式1:OpenAI 兼容模式(推荐)
java 复制代码
import org.springframework.ai.openai.OpenAiChatClient;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.ai.openai.api.OpenAiChatCompletionRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.Base64;
import java.util.List;

/**
 * 豆包多模态控制器(兼容OpenAI模式)
 */
@RestController
public class DouBaoMultiModalController {

    @Autowired
    private OpenAiChatClient openAiChatClient;

    @PostMapping("/ai/doubao/multimodal/chat")
    public String douBaoMultiModalChat(
            @RequestParam("file") MultipartFile file,
            @RequestParam("prompt") String prompt) throws Exception {
        
        // 1. 图片转Base64
        byte[] imageBytes = file.getBytes();
        String base64Image = Base64.getEncoder().encodeToString(imageBytes);
        
        // 2. 构建OpenAI格式多模态消息
        OpenAiChatCompletionRequest.Message message = OpenAiChatCompletionRequest.Message.builder()
                .role(OpenAiApi.ChatRole.USER.value())
                .content(List.of(
                        // 文本部分
                        OpenAiChatCompletionRequest.Message.ContentPart.builder()
                                .type("text")
                                .text(prompt)
                                .build(),
                        // 图片部分
                        OpenAiChatCompletionRequest.Message.ContentPart.builder()
                                .type("image_url")
                                .imageUrl(OpenAiChatCompletionRequest.Message.ImageUrl.builder()
                                        .url("data:image/jpeg;base64," + base64Image)
                                        .build())
                                .build()
                ))
                .build();
        
        // 3. 调用豆包兼容接口
        return openAiChatClient.call(List.of(message)).getResult().getOutput().getContent();
    }
}
方式2:自定义客户端(原生接口)

若兼容模式不可用,直接调用豆包原生多模态接口:

java 复制代码
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.util.Base64;
import java.util.List;
import java.util.Map;

/**
 * 豆包多模态自定义客户端(原生接口)
 */
@RestController
public class CustomDouBaoMultiModalController {

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

    @Value("${doubao.base-url}")
    private String baseUrl;

    private final RestTemplate restTemplate = new RestTemplate();

    @PostMapping("/ai/doubao/custom/multimodal/chat")
    public String customMultiModalChat(
            @RequestParam("file") MultipartFile file,
            @RequestParam("prompt") String prompt) throws Exception {
        
        // 1. 图片转Base64
        byte[] imageBytes = file.getBytes();
        String base64Image = Base64.getEncoder().encodeToString(imageBytes);
        
        // 2. 构建请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("Authorization", "Bearer " + apiKey);
        
        // 3. 构建豆包原生请求体
        Map<String, Object> requestBody = Map.of(
                "model", "doubao-multimodal",
                "messages", List.of(Map.of(
                        "role", "user",
                        "content", List.of(
                                Map.of("type", "text", "text", prompt),
                                Map.of("type", "image", "image", base64Image)
                        )
                )),
                "temperature", 0.7
        );
        
        // 4. 发送请求并解析响应
        HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
        ResponseEntity<Map> response = restTemplate.postForEntity(
                baseUrl + "/chat/multimodal/completions",
                request,
                Map.class
        );
        
        if (response.getStatusCode().is2xxSuccessful()) {
            List<Map<String, Object>> choices = (List<Map<String, Object>>) response.getBody().get("choices");
            return (String) choices.get(0).get("message").get("content");
        }
        return "调用失败:" + response.getStatusCode();
    }
}

对应的配置:

yaml 复制代码
doubao:
  api-key: your-doubao-api-key
  base-url: https://www.doubao.com/api/v1

四、关键注意事项(避坑指南)

4.1 版本兼容

  • 必须使用 Spring AI 0.8.1+(适配 Spring Boot 4.0.1),低版本会出现依赖冲突;
  • 国内模型需选择对应版本(千问多模态用 qwen-vl,豆包多模态用 doubao-multimodal)。

4.2 密钥安全

生产环境切勿硬编码 API 密钥,通过环境变量注入:

yaml 复制代码
spring:
  ai:
    dashscope:
      api-key: ${DASHSCOPE_API_KEY}  # 从环境变量读取

4.3 图片处理

  • 图片格式:支持 JPG/PNG,部分模型限制大小(≤10MB);
  • 性能优化:大图片先压缩分辨率,再转 Base64(减少请求体积)。

4.4 网络与接口适配

  • 国内服务器无需代理,海外服务器需配置国内代理;
  • 定期确认模型官方接口地址(可能微调)。

五、总结

Spring AI 结合 Spring Boot 4.0.1 可高效集成国内主流大模型,核心要点如下:

  1. 文本交互:千问用官方适配依赖,豆包复用 OpenAI 兼容模式,配置简单、调用便捷;
  2. 多模态能力:核心是图片 Base64 编码,千问有官方封装,豆包可通过兼容/自定义模式实现;
  3. 核心原则:国内模型集成的关键是「鉴权方式 + 接口格式」适配,Spring AI 已封装通用逻辑,只需少量配置即可落地。

通过本文的实操方案,你可快速构建基于国内大模型的 AI 应用,兼顾 Spring 生态的优雅性与本土化模型的适配性。若需集成文心一言、讯飞星火等其他国内模型,核心逻辑一致:确认适配方式(官方/兼容/自定义)→ 配置 API 信息 → 封装 Prompt 调用。

相关推荐
十年Java程序媛11 分钟前
Java 接口和抽象类对比|Java8 新特性,抛弃老旧八股,正确选型
java·spring boot·后端
IT_陈寒14 分钟前
SpringBoot自动配置差点让我加班到凌晨
前端·人工智能·后端
yumgpkpm27 分钟前
Acceldata ODP(Open Data Platform)3.3.6.4(RHEL9)保姆级完整安装手册
大数据·人工智能·hive·hadoop·kafka·hbase·cloudera
程序员cxuan29 分钟前
腾讯又来一王炸,开源版 WorkBuddy 太夯了!
人工智能·后端·程序员
邓工说电40 分钟前
智慧断路器安全吗?数据加密、离线保护与合规认证全解读
大数据·数据库·人工智能·智能断路器·炜晔科技
阿里云大数据AI技术42 分钟前
Lance 数据检索怎么选,当然阿里云 Milvus 向量湖
人工智能
出海客43 分钟前
跨境电商多语言客服知识库怎么建:资料结构、检索边界与人工升级
大数据·人工智能
java资料站1 小时前
五、Spring AI Alibaba · Memory · Saver(短期会话)
java·spring·microsoft
xsd202411181 小时前
从自主导航到视觉读表:一台工业巡检机器人的全栈技术链路拆解
人工智能
袁哥大话安全1 小时前
巡隐WEBSHELL扫描软件
人工智能·安全·web