专栏:Spring AI 探索手札

个人主页:手握风云

目录

一、Qianfan

1.1. 平台概述

1.2. 项目搭建

1.3. 聊天模型

1.4. 图像模型

二、Spring AI Alibaba

2.1. 环境与密钥配置

2.2. 项目搭建

2.3. 图像生成

2.4. 语音合成


一、Qianfan

1.1. 平台概述

        百度千帆是百度智能云推出的AI 原生应用开发平台,基于文心大模型打造,提供从模型开发到应用部署的全栈 AI 能力支持。千帆 V2 版本完全兼容 OpenAI 标准(身份认证、接口协议);V1 为早期独立接口,自2025 年 4 月 30 日起关闭推理服务创建入口,新服务默认基于 V2 接口开发。依托兼容特性,项目搭建、代码开发可复用 OpenAI 相关依赖与编码逻辑,仅需小幅修改配置即可完成适配。

        使用千帆服务的前置条件需完成账号登录、申请密钥、实名认证、开通模型服务四步操作,新用户可领取免费调用额度。

1.2. 项目搭建

  • Maven 依赖
<dependencies>
	<!-- Web依赖 -->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<!-- 复用OpenAI启动器,兼容千帆V2接口 -->
	<dependency>
		<groupId>org.springframework.ai</groupId>
		<artifactId>spring-ai-starter-model-openai</artifactId>
	</dependency>
</dependencies>

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
	</plugins>
</build>
  • 启动类
package com.yang.qianfan;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class QianfanApplication {
    public static void main(String[] args) {
        SpringApplication.run(QianfanApplication.class, args);
    }
}

1.3. 聊天模型

        千帆 V2 对话接口路径与 OpenAI 默认路径不同,需手动指定接口地址、基础域名、模型等参数。参考文档:文本生成 - 千帆AI应用开发者中心-API参考qianfan-api | 百度智能云文档

        配置文件代码:

spring:
  ai:
    openai:
      api-key: ${qian-fan-api-key}$
      # 千帆V2基础域名
      base-url: https://qianfan.baidubce.com
      chat:
        options:
          model: "ernie-lite-pro-128k" # 指定文心系列聊天模型
        completions-path: /v2/chat/completions # 千帆V2聊天接口路径

        接口代码:

package com.yang.qianfan.controller;

import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/qianfan")
public class QianfanController {
    @Autowired
    private OpenAiChatModel openAiChatModel;

    @RequestMapping("/chat")
    public String chat(String message) {
        return openAiChatModel.call(message);
    }
}

1.4. 图像模型

        配置代码:

spring:
  ai:
    openai:
      api-key: ${QIANFAN_API_KEY}
      # 千帆V2基础域名
      base-url: https://qianfan.baidubce.com
      image:
        options:
          model: flux.1-schnell # 指定千帆图像模型
        images-path: /v2/images/generations # 千帆V2图像生成接口路径

        接口代码:

package com.yang.qianfan.controller;

import org.springframework.ai.image.ImagePrompt;
import org.springframework.ai.image.ImageResponse;
import org.springframework.ai.openai.OpenAiImageModel;
import org.springframework.ai.openai.OpenAiImageOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/qianfan")
public class QianfanController {
    @Autowired
    private OpenAiImageModel openAiImageModel;

    @RequestMapping("/image")
    public void image() {
        ImageResponse response = openAiImageModel.call(
                new ImagePrompt("一个穿着宇航服的猫咪在月球上弹吉他", OpenAiImageOptions.builder()
                        .quality("medium")
                        .N(1)
                        .height(1024)
                        .width(1024)
                        .build())
        );

        String imageUrl = response.getResult().getOutput().getUrl();
        System.out.println(imageUrl);
    }
}

二、Spring AI Alibaba

        Spring AI Alibaba 是基于 Spring AI 开源构建的 Java AI 开发框架,深度对接阿里云百炼(DashScope)平台的通义、万相等大模型与多模态服务,提供云原生统一 AI API 抽象层,屏蔽不同模型的接口差异,帮助 Spring 生态开发者快速落地对话、图像、语音、视频等多模态 AI 应用。框架提供 Spring Boot Starter(框架集成)和原生 DashScope SDK(通用 Java 项目)两种使用形态,新用户可领取阿里云百炼免费调用额度。

2.1. 环境与密钥配置

        获取 API-KEY:百炼平台

        我们首先需要登录阿里云百炼平台,开通大模型推理、训练等服务,领取新人免费 Token 额度,并且需要完成实名认证。进入 API-Key 管理页面创建密钥:

2.2. 项目搭建

        Maven 依赖配置:

<dependencies>
	<!-- Spring Boot Web 基础(接口开发必备) -->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>

	<!-- WebFlux 响应式组件(流式对话/流式语音推荐引入) -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-webflux</artifactId>
	</dependency>

	<!-- Spring Boot 单元测试 -->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>

	<!-- Spring AI Alibaba 核心启动器(整合百炼全能力:对话/图像/语音/视频) -->
	<dependency>
		<groupId>com.alibaba.cloud.ai</groupId>
		<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
	</dependency>
</dependencies>

<dependencyManagement>
	<dependencies>
		<!-- Spring AI Alibaba 版本统一管理BOM -->
		<dependency>
			<groupId>com.alibaba.cloud.ai</groupId>
			<artifactId>spring-ai-alibaba-bom</artifactId>
			<version>1.0.0.2</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>

        配置文件:

spring:
  ai:
    dashscope:
      api-key: ${DASHSCOPE_API_KEY}

        启动类:

package com.yang.alibaba;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AlibabaApplication {
    public static void main(String[] args) {
        SpringApplication.run(AlibabaApplication.class, args);
    }
}

        基础对话测试:自动注入 DashScopeChatModel,调用 call() 方法即可完成基础大模型对话。

package com.yang.alibaba;

import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class ChatModelTest {
    @Autowired
    private DashScopeChatModel chatModel;

    @Test
    public void chat() {
        String message = chatModel.call("你是谁?");
        System.out.println(message);
    }
}

2.3. 图像生成

        阿里云百炼 DashScope 的 Spring AI Alibaba 框架实现 AI 图像生成能力,依托 Spring AI 统一 ImageModel 标准接口,对接通义万相、通义文生图系列模型。

        核心 API 统一使用 DashScopeImageModel,该类实现 Spring AI 通用 ImageModel 顶层接口,屏蔽不同图像模型的底层接口差异,一套代码可切换通义全系绘图模型。

        图像生成功能的最简调用分为四步:首先注入 DashScopeImageModel 模型实例,接着构建携带文字描述提示词的 ImagePrompt 对象,随后执行 call() 方法发起绘图请求,该方法会返回ImageResponse 响应对象,最后从响应结果中解析提取出生成图片对应的在线 URL。配套基础示例以提示词 “孩子在海边玩耍” 作为输入,完整走完上述调用流程后,程序会输出打印本次生成图片的访问链接。

package com.yang.alibaba;

import com.alibaba.cloud.ai.dashscope.image.DashScopeImageModel;
import org.junit.jupiter.api.Test;
import org.springframework.ai.image.ImagePrompt;
import org.springframework.ai.image.ImageResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class ImageModelTest {
    @Autowired
    private DashScopeImageModel imageModel;

    @Test
    public void textToImage() {
        // 默认为通义万相模型
        ImageResponse imageResponse = imageModel.call(new ImagePrompt("孩子们在海边玩耍"));
        String imgUrl = imageResponse.getResult().getOutput().getUrl();
        System.out.println(imgUrl);
    }
}

        自动配置类 DashScopeImageAutoConfiguration:框架自动装配图像模型 Bean,装配依赖:阿里云连接配置、图像专属属性、RestClient/WebClient、重试模板、异常处理器、链路观测组件;仅当未自定义 DashScopeImageModel 时自动创建。

        DashScopeImageProperties 是图像生成功能的配置属性载体,其配置前缀统一为 spring.ai.dashscope.image ;该配置类默认开启图像生成相关能力,内部内置了 DashScopeImageOptions 的全套默认参数,且框架默认使用 wanx-v1 也就是通义万相初代绘图模型作为图像生成基础模型。

        DashScopeImageOptions 是核心参数配置,支持 yml 全局配置、代码链式构建两种配置方式,参数适配通义万相(wan 系列)、通义文生图(qwen-image)两类模型,两类模型参数支持范围存在明显差异。

参数 作用 模型差异化规则
model 指定绘图模型 1. qwen-image:擅长海报、对联等复杂文字渲染,仅支持 5 种固定比例尺寸2. wan2.2 系列(plus/flash):通用写实摄影;flash 极速出图、plus 高清专业;支持 512~1440 任意自定义宽高3. wanx-v1:初代模型,支持风格转换、图生图垫图;wanx2.0-t2i-turbo 低成本基础画质
n 生成图片数量 qwen-image 仅支持 1 张;万相系列支持 1~4 张
width/height/size 画布分辨率 size 参数已废弃;wan2.2 可自定义宽高;qwen-image 仅固定 5 种比例尺寸;尺寸超出范围直接报错
style 绘画风格 仅 wanx-v1 支持,可选摄影、人像、3D 卡通、动漫、油画、水彩、素描、中国画、扁平插画、auto 自动
seed 随机种子 固定相同 seed,可复现完全一致的生成图片;不传则自动随机
watermark AI 水印 true:图片右下角添加「AI 生成」水印;默认 false 无水印
package com.yang.alibaba;

import com.alibaba.cloud.ai.dashscope.image.DashScopeImageModel;
import com.alibaba.cloud.ai.dashscope.image.DashScopeImageOptions;
import org.junit.jupiter.api.Test;
import org.springframework.ai.image.ImageGeneration;
import org.springframework.ai.image.ImagePrompt;
import org.springframework.ai.image.ImageResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.ArrayList;
import java.util.List;

@SpringBootTest
public class ImageModelTest {
    @Autowired
    private DashScopeImageModel imageModel;

    @Test
    public void textToImage1() {
        // 默认为通义万相模型
        // 风格为水彩
        DashScopeImageOptions options = DashScopeImageOptions.builder()
                .withStyle("<watercolor>")
                .build();
        ImageResponse imageResponse = imageModel.call(new ImagePrompt("孩子们在海边玩耍", options));
        String imgUrl = imageResponse.getResult().getOutput().getUrl();
        System.out.println(imgUrl);
    }

    @Test
    public void textToImage2() {
        String prompt = "中国女孩, 圆脸, 看着镜头, 优雅的民族服装, 商业摄影, 室外, 电影级光照, 半身特写, 精致的淡妆, 锐利的边缘。";
        // 模型为通义千问
        DashScopeImageOptions options = DashScopeImageOptions.builder()
                .withModel("qwen-image-2.0")
                .build();

        ImageResponse imageResponse = imageModel.call(new ImagePrompt(prompt, options));
        String imgUrl = imageResponse.getResult().getOutput().getUrl();
        System.out.println(imgUrl);
    }

    @Test
    public void textToImage3() {
        String prompt = "中国女孩, 圆脸, 看着镜头, 优雅的民族服装, 商业摄影, 室外, 电影级光照, 半身特写, 精致的淡妆, 锐利的边缘。";
        // 模型为通义千问
        DashScopeImageOptions options = DashScopeImageOptions.builder()
                .withModel("wan2.2-t2i-flash")
                .withWatermark(true)
                .withWidth(1024)
                .withWidth(1024)
                .build();

        ImageResponse imageResponse = imageModel.call(new ImagePrompt(prompt, options));
        String imgUrl = imageResponse.getResult().getOutput().getUrl();
        System.out.println(imgUrl);
    }

    @Test
    public void textToImage4() {
        String prompt = "特斯拉 Model3";
        DashScopeImageOptions options = DashScopeImageOptions.builder()
                .withModel("wan2.2-t2i-flash")
                .withN(3)
                .build();

        ImageResponse imageResponse = imageModel.call(new ImagePrompt(prompt, options));
        List<ImageGeneration> results = imageResponse.getResults();
        List<String> urls = new ArrayList<>();
        for (ImageGeneration generation : results) {
            urls.add(generation.getOutput().getUrl());
        }

        System.out.println(urls);
    }
}

        不同绘图模型具备差异化能力与适用场景,其中 wanx-v1 模型擅长图生图、风格转换类需求,但无法自定义图片分辨率;wan2.2-t2i-flash 与 wan2.2-t2i-plus 两款模型侧重根据纯文字生成高清写实图像,支持自定义任意分辨率尺寸,缺点是不支持 style 美术风格参数;qwen-image 模型的文字渲染效果最优,适合制作海报、对联等带有文字元素的创意画面,该模型分辨率固定,无法自行调整。

        图像生成接口存在多项调用约束与异常触发规则,首先作为输入的参考图 URL 内不允许出现中文,同时图片文件大小、像素尺寸都有硬性区间要求;若设置的分辨率超出对应模型支持范围,程序会直接抛出请求异常;各模型参数体系相互独立无法通用,例如 wan2.2 系列模型不识别 style 美术风格参数,即便进行配置也不会生效;另外通义 qwen-image 模型单次调用仅能生成一张图片,用于设置生成数量的 n 参数对其不起作用。

2.4. 语音合成

        框架会自动装配 DashScopeSpeechSynthesisModel 对象,开发时只需使用 @Autowired 注解完成依赖注入,就能直接调用该语音合成模型。

        语音合成的标准调用分为四步:首先借助 DashScopeSpeechSynthesisOptions.builder() 构造语音合成所需的各类参数;接着把待转语音的文本和前面配置好的参数,一起封装成 SpeechSynthesisPrompt 请求实体;随后调用模型实例的call()方法发起合成请求,接口会返回 SpeechSynthesisResponse 响应结果;最后从响应对象中提取音频二进制数据 ByteBuffer,将数据流写入本地 MP3 文件,即可完成音频文件的保存。

package com.yang.alibaba;

import com.alibaba.cloud.ai.dashscope.audio.DashScopeSpeechSynthesisModel;
import com.alibaba.cloud.ai.dashscope.audio.synthesis.SpeechSynthesisPrompt;
import com.alibaba.cloud.ai.dashscope.audio.synthesis.SpeechSynthesisResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;

@SpringBootTest
public class AudioModelTest {
    @Autowired
    private DashScopeSpeechSynthesisModel speechSynthesisModel;

    private static final String TEXT = "IntelliJ IDEA 树立智能开发工具行业标杆,同时始终坚守创立初心。";

    @Test
    public void tts1() {
        SpeechSynthesisPrompt prompt = new SpeechSynthesisPrompt(TEXT);
        SpeechSynthesisResponse response = speechSynthesisModel.call(prompt);
        File file = new File(System.getProperty("user.dir") + "/out.mp3");
        try (FileOutputStream fos = new FileOutputStream(file)) {
            ByteBuffer audio = response.getResult().getOutput().getAudio();
            fos.write(audio.array());
        } catch (IOException e) {
            System.out.println("写入文件失败!");
        }
    }
}

        系统提供统一顶层抽象接口 SpeechSynthesisModel ,该接口定义了语音合成两大核心能力:同步一次性生成完整音频的 call(SpeechSynthesisPrompt) 方法、适配实时播报场景的流式音频输出stream(SpeechSynthesisPrompt) 方法,而 DashScopeSpeechSynthesisModel 是这套标准接口面向阿里云 DashScope 平台的专属实现类。

        DashScopeAudioSpeechAutoConfiguration 是 Spring Boot 实现自动装配的核心配置类,它会自动注入平台连接配置、语音合成专属配置、重试模板与监控观测相关组件,在无开发者自定义实现的条件下,自动创建并注册 DashScopeSpeechSynthesisModel Bean,简化项目初始化开发流程。

        DashScopeAudioSpeechSynthesisProperties 为全局语音合成配置承载类,配置前缀为 spring.ai.dashscope.audio.synthesis,内部预设默认语音模型、音色、语速、MP3 音频格式等基础参数,同时内置 DashScopeSpeechSynthesisOptions 对象,用于承载业务中动态自定义的各项合成参数。

        配置前缀:spring.ai.dashscope.audio.synthesis.options,所有参数支持 yml 全局配置、代码动态构建两种方式。

参数 说明 取值范围 / 规则
model 语音模型 支持 CosyVoice、Sambert 系列;模型与音色必须匹配,部分模型需单独开通权限
voice 音色 各模型专属音色(男声 / 女声),部分音色需申请权限
text 待合成文本 业务输入文本,一般通过 Prompt 传入
request_text_type 文本类型 默认PLAIN_TEXT纯文本
sample_rate 音频采样率 默认 48000
volume 音量 0~100,数值越大音量越高
speed 语速 0.5~2.0,1.0 为正常语速;小于 1 慢速,大于 1 快速
pitch 语调 0.5~2.0,调整声音高低
enable_word_timestamp 字级时间戳 true/false,开启后返回每个字的时间节点
enable_phoneme_timestamp 音素时间戳 true/false,精细化语音时间标记
response_format 音频输出格式 支持 mp3、wav、pcm,默认 mp3
@Test
public void tts2() {
    DashScopeSpeechSynthesisOptions options = DashScopeSpeechSynthesisOptions.builder()
            .model("cosyvoice-v3-flash")
            .voice("longanhuan")
            .speed(0.5f)
            .volume(10)
            .build();

    SpeechSynthesisPrompt prompt = new SpeechSynthesisPrompt(TEXT, options);
    SpeechSynthesisResponse response = speechSynthesisModel.call(prompt);
    File file = new File(System.getProperty("user.dir") + "/out.mp3");
    try (FileOutputStream fos = new FileOutputStream(file)) {
        ByteBuffer audio = response.getResult().getOutput().getAudio();
        fos.write(audio.array());
    } catch (IOException e) {
        System.out.println("写入文件失败!");
    }
}

        dashscope-sdk-java 是阿里云底层原生 Java SDK,不绑定任何开发框架,是语音合成能力的底层基础实现。原生 SDK 的引入方式十分简单,仅需要在 Maven 中单独引入 dashscope-sdk-java 依赖即可,不需要额外导入任何 Spring AI 相关 starter 包。
        原生 SDK 拥有一套完整独立的调用流程:首先构造 SpeechSynthesisParam 参数对象,完成 API Key、语音模型、音色等核心配置;接着实例化 SpeechSynthesizer 合成器;然后传入文本调用 call 方法,获取音频二进制 ByteBuffer 数据;再将二进制数据流写入本地磁盘,生成完整音频文件;同时该 SDK 支持两种 API Key 配置方式,既可以硬编码写入,也能读取系统环境变量,配置方式灵活度更高。

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dashscope-sdk-java</artifactId>
    <version>the-latest-version</version>
</dependency>
@Test
public void textToAudio() {
    SpeechSynthesisParam param = SpeechSynthesisParam.builder()
            .apiKey("sk-22c4373f299c4618ac31a64e299afafb")
            .model("cosyvoice-v3-flash")
            .text("今天天气怎么样?")
            .build();

    // 同步模式:直接调用 call 获取音频
    SpeechSynthesizer synthesizer = new SpeechSynthesizer();
    ByteBuffer audio = synthesizer.call(param);
    System.out.println("[Metric] requestId为:" + synthesizer.getLastRequestId());

    File file = new File("output.mp3");
    try (FileOutputStream fos = new FileOutputStream(file)) {
        fos.write(audio.array());
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

更多推荐