Spring AI 从提示词到多模态

从提示词到多模态:Spring AI 企业级应用开发实践

大语言模型正在从"能聊天的工具"变成企业系统中的一部分。对于 Java 开发者来说,真正有价值的不是单独体验某个 AI 产品,而是把模型能力接入到已有业务系统里,让它参与内容生成、图像生成、语音合成、智能问答、流程自动化等场景。

Spring AI 的定位正好落在这个方向上:它把不同厂商、不同类型的模型能力抽象成统一的 Spring 风格 API,让开发者可以沿用熟悉的工程方式完成 AI 应用开发。与其把 AI 看成一个神秘的黑盒,不如把它当成一种新的基础设施:有输入、有配置、有响应、有异常、有监控,也需要清晰的工程规范。

学习这类技术时,最重要的不是只记住代码怎么写,而是理解为什么要这样组织:为什么要抽象模型接口,为什么要把密钥放到环境变量里,为什么要控制输出格式,为什么要用规则约束 AI 生成代码。只有理解这些底层思路,后续遇到 Spring AI 版本升级、模型厂商切换、业务场景变化时,才能独立完成迁移和扩展。

先学会和 AI 正确协作

很多人刚开始使用 AI 时,会直接输入一句很模糊的话,例如"帮我写个登录页面""帮我优化代码""写个故事"。这种提问方式看起来省事,但输出往往不稳定:有时风格不对,有时结构不对,有时遗漏关键限制,甚至会生成不符合项目架构的代码。

原因很简单:大语言模型虽然拥有大量知识,但它并不知道你的真实业务背景、目标用户、技术约束和输出要求。它只能根据你提供的信息生成结果。提示词的质量,直接决定了 AI 输出的相关性、可用性和专业度。

一个高质量提示词,本质上是一份清晰的任务说明。通常可以从以下几个维度组织:

要素 作用 示例
目标 明确希望 AI 完成什么任务 将技术说明改写成通俗中文
背景 说明任务发生在什么场景 面向一家智能家居创业公司的新品发布
受众 决定表达难度和信息密度 给 CEO 汇报、面向高中生、发布到公众号
风格 控制内容类型和表达方式 科普风、技术博客风、口语化风格
语气 决定情绪色彩 正式严谨、轻松自然、客观中立
格式 约束输出结构 Markdown、表格、JSON、固定段落结构
限制 明确不能做什么 不虚构数据、不使用夸张宣传词、不超过 500 字

比如,要让 AI 写一份 Java 后端工程师招聘文案,不要只说"写个招聘启事"。更好的写法是:说明公司背景、目标岗位、目标候选人、技术栈、发布渠道、语气风格、字数范围,以及哪些表达不能出现。这样 AI 才能从"自由发挥"变成"按要求交付"。

用结构化方法提升提示词稳定性

当提示词变复杂之后,只靠临场发挥很容易遗漏信息。CO-STAR 是一种常用的结构化提示词框架,它把任务拆成 Context、Objective、Style、Tone、Audience、Response 六个部分,分别对应背景、目标、风格、语气、受众和响应格式。

它的价值不在于创造新概念,而是把零散的提示词要素变成一套可复用的清单。个人使用时,它能减少遗漏;团队协作时,它能统一大家和 AI 沟通的方式。

对于格式固定、风格特殊或逻辑复杂的任务,还可以使用少样本提示。也就是先给 AI 几组"输入到输出"的示例,再让它处理新的输入。相比单纯描述规则,示例更直观,尤其适合情感分类、数据提取、风格仿写和固定格式生成。

text 复制代码
示例:
世界越来越糟,没有改善的可能。 -> 悲观
每天都是新的开始,充满希望! -> 乐观
只要努力,梦想终会实现。 -> 乐观

现在判断:
生活太艰难了,看不到出路。 ->

遇到数学计算、逻辑推理、决策分析这类任务时,可以使用思维链提示,让 AI 在给出结果前先拆解问题。比如让它先分析已知条件,再列出计算过程,最后输出结论。这样不仅能提升复杂任务的准确率,也方便开发者定位 AI 到底在哪一步出了问题。

如果问题本身比较容易产生多种推理路径,可以再加入自我一致性策略:让 AI 从不同角度独立推理多次,再比较多个结果,选择最稳定、最合理的结论。这种方式尤其适合复杂推理、数据判断和业务规则分析。

在 AI 编程工具中,提示词能力还可以沉淀为长期规则。以 Cursor Rules 为例,它相当于给 AI 编程助手设置一套行为准则,让它在生成或修改代码时遵循固定的技术规范、架构约定和编码风格。

对于 Spring Boot 项目,规则可以包含这些内容:

  • 使用标准分层结构组织代码,例如 controller、service、repository、model、configuration。
  • 接口设计遵循 RESTful 风格。
  • 类名使用 PascalCase,方法和变量名使用 camelCase,常量使用大写下划线。
  • 优先使用构造器注入,避免字段注入。
  • 使用 @ControllerAdvice@ExceptionHandler 做统一异常处理。
  • 使用 JUnit 5、MockMvc、@DataJpaTest 编写对应层级的测试。
  • 使用 Spring Security、BCrypt、CORS 配置保障安全性。
  • 使用 SLF4J、Logback、Actuator 完成日志与运行状态观测。

规则越具体,AI 越容易执行。与其写"代码写好一点",不如写"Controller 只负责参数接收和响应返回,业务逻辑放到 Service 层"。与其每次都纠正 AI,不如提前把团队经验写成可复用的规则。

在 Spring AI 中接入图像生成能力

图像模型主要处理视觉相关任务,可以分为两类:一类是图像生成,根据文本或图片条件生成新图像;另一类是图像理解,对输入图片做分类、检测、分割或内容分析。

在应用开发中,图像生成是很常见的入口。例如输入"一个古朴小镇,雨夜,霓虹灯倒映在湿润街道上",模型就能根据描述生成画面。Spring AI 为这类能力提供了统一的 Image Model API,开发者可以用相似的调用方式接入不同图像模型,并在需要时切换服务商。

项目基础配置通常会选择 Java 17、Spring Boot 3.x 和 Spring AI 1.x。父工程中统一管理版本:

xml 复制代码
<properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <spring-ai.version>1.0.1</spring-ai.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>${spring-ai.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

子模块引入 Web 和 OpenAI 模型 starter:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>

密钥不要硬编码在代码里,建议通过环境变量读取:

yaml 复制代码
spring:
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}

完成配置后,可以通过 OpenAiImageModel 发起图像生成请求:

java 复制代码
@RestController
@RequestMapping("/openai")
public class OpenAIController {

    private final OpenAiImageModel imageModel;

    public OpenAIController(OpenAiImageModel imageModel) {
        this.imageModel = imageModel;
    }

    @GetMapping("/image")
    public String image() {
        ImageResponse response = imageModel.call(
                new ImagePrompt("孩子在海边玩耍",
                        OpenAiImageOptions.builder()
                                .quality("hd")
                                .N(1)
                                .height(1024)
                                .width(1024)
                                .build())
        );
        return response.getResult().getOutput().getUrl();
    }
}

如果希望直接把图片输出到浏览器,可以读取生成结果中的图片 URL,再把图片字节写入 HttpServletResponse。如果模型支持 b64_json,也可以让接口返回 Base64 数据,再在服务端解码为字节数组输出或保存为文件。

Spring AI 的图像抽象主要由几个对象组成:

  • ImageModel:图像模型调用入口,核心方法是 call(ImagePrompt request)
  • ImagePrompt:封装图像生成请求,包含文本消息和模型选项。
  • ImageMessage:表示图像提示文本,也可以携带权重。
  • ImageOptions:描述图像数量、模型、宽高、响应格式等通用参数。
  • ImageResponse:封装模型返回结果。
  • ImageGeneration:表示单张图像的生成结果和元数据。

开发时还要注意常见异常。参数不合法时,接口可能返回 400,例如图像质量、生成数量、尺寸等参数不被当前模型支持;账户额度不足时,会出现计费限制相关错误;部分模型还要求组织认证,认证未完成时可能返回 403。处理这类问题时,优先查看模型官方参数范围、账户状态和认证状态。

除了 OpenAI,Spring AI 也支持 Azure OpenAI 的 DALL-E 图像生成能力。可以把 OpenAI 理解为模型提供方,把 Azure OpenAI 理解为微软云上的企业级托管入口。企业项目如果已经使用 Azure 云资源,通常会更关注权限管理、合规、区域部署和账单体系。

国内平台方面,百度千帆的新版本接口已经兼容 OpenAI 标准协议,因此可以继续复用 spring-ai-starter-model-openai,通过调整 base-url、模型名和接口路径完成接入。例如图像生成可以配置千帆的 base URL、图片生成路径和具体模型,从而用相似代码调用不同平台。

在 Spring AI 中实现文本转语音

语音模型用于处理人类语音信号,常见能力包括语音识别、语音合成和语音助手。这里重点关注文本转语音,也就是把一段文本转换为自然语音音频。

文本转语音的应用场景很多:把博客内容朗读出来,为多语言内容生成配音,为客服系统生成语音回复,或者在实时交互场景中流式输出音频。Spring AI 对 OpenAI TTS API 做了封装,提供 SpeechModelStreamingSpeechModel 等抽象,使开发者可以通过简单调用完成音频生成。

基础配置和图像生成类似,可以复用 OpenAI API Key,并继续使用同一个 starter:

yaml 复制代码
spring:
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}

一个典型的文本转语音接口如下:

java 复制代码
@RestController
@RequestMapping("/openai")
public class SpeechController {

    private final OpenAiAudioSpeechModel speechModel;

    public SpeechController(OpenAiAudioSpeechModel speechModel) {
        this.speechModel = speechModel;
    }

    @GetMapping("/tts")
    public void tts() throws IOException {
        OpenAiAudioSpeechOptions options = OpenAiAudioSpeechOptions.builder()
                .model("tts-1")
                .voice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY)
                .responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)
                .speed(1.0f)
                .build();

        SpeechPrompt prompt = new SpeechPrompt(
                "Hello, this is a text-to-speech example.",
                options
        );

        SpeechResponse response = speechModel.call(prompt);
        File file = new File(System.getProperty("user.dir") + "/output.mp3");

        try (FileOutputStream fos = new FileOutputStream(file)) {
            fos.write(response.getResult().getOutput());
        }
    }
}

其中 OpenAiAudioSpeechOptions 用来控制语音生成参数:

  • model:语音生成模型,例如 tts-1
  • voice:发音人,例如 alloy、echo、fable、onyx、nova、shimmer。
  • responseFormat:输出格式,例如 mp3、wav、aac、opus。
  • speed:语速,1.0 表示正常速度,大于 1.0 更快,小于 1.0 更慢。

如果要生成更柔和的女声,并降低朗读速度,可以这样配置:

java 复制代码
OpenAiAudioSpeechOptions options = OpenAiAudioSpeechOptions.builder()
        .model("tts-1")
        .voice(OpenAiAudioApi.SpeechRequest.Voice.NOVA)
        .responseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.OPUS)
        .speed(0.5f)
        .build();

语音请求和响应也有清晰的对象模型:

  • SpeechPrompt:把待转换文本和语音选项组合成完整请求。
  • SpeechMessage:封装文本内容。
  • SpeechResponse:封装模型返回结果。
  • Speech:保存生成后的音频二进制数据。

最终拿到的音频本质上是 byte[],可以保存成文件,也可以写入 HTTP 响应直接播放。对于真实业务系统,还需要进一步考虑文件存储、访问权限、异步任务、失败重试、成本控制和日志追踪。

写在最后

Spring AI 应用开发可以从三条线逐步推进:先掌握提示词工程,保证 AI 输出足够稳定;再熟悉 Spring AI 的模型抽象,理解请求、选项、响应和异常处理;最后把图像、语音等多模态能力接入业务流程。

真正的重点不是调用某一个模型接口,而是建立一套可维护的 AI 工程方式。提示词让模型听得懂需求,Rules 让 AI 编程符合团队规范,Spring AI 的统一抽象让模型能力进入 Java 应用体系。把这三者结合起来,AI 才能从演示效果走向可落地的企业级能力。

相关推荐
标书畅畅行3 小时前
全流程企业级 AI 标书系统技术实现与工程实践
大数据·人工智能
银河麒麟操作系统3 小时前
银河麒麟安全SDK 3.0全面升级
人工智能·安全
赴山海bi3 小时前
AI驱动亚马逊电商增长:DeepBI如何重塑盈利模式
大数据·人工智能
Halo_tjn3 小时前
反射与设计模式1
java·开发语言·算法
神仙别闹3 小时前
基于Python + SQL server 实现(GUI)原神圣遗物管理与角色数值模拟系统
java·数据库·python
萤丰信息3 小时前
AI赋能安全治理,构筑智慧园区全域智能安防新防线
人工智能·安全
智慧景区与市集主理人3 小时前
市集的 “IP 化” 打造路径——从单次活动到长期品牌资产
人工智能·科技·tcp/ip
DreamLife☼4 小时前
OpenBCI-实战五:脑电数据可视化仪表板
人工智能·机器学习·信息可视化·开源硬件·脑机接口·openbci
是有头发的程序猿4 小时前
电商自动化实战:淘宝/天猫item_get商品详情API全量采集教程(Python源码)
java·python·自动化