Spring AI 应用开发

Spring AI 应用开发从入门到智能聊天机器人

生成式 AI 正在进入 Java 企业应用的日常开发流程。对于已经熟悉 Java、Spring Boot 和 Web 开发的开发者来说,Spring AI 的价值在于把大模型能力封装成符合 Spring 生态习惯的组件,让聊天、流式响应、结构化输出、本地模型、云模型、多模态和对话记忆等能力可以通过统一方式接入业务系统。

本文按照从概念到实践、从单次调用到完整聊天机器人的路线,梳理 Spring AI 应用开发的关键知识。

AI 与 Spring AI 的起点

AI 即 Artificial Intelligence,通常指通过计算机系统模拟人类智能,让机器具备学习、推理、决策、识别和生成等能力。它的本质并不是"魔法",而是算法与数据共同作用的结果。医疗影像识别、金融风控、制造业质检、智能驾驶、教育学情分析等场景,都可以看到 AI 技术落地后的实际价值。

从发展历程看,AI 并不是突然出现的新概念。早期的神经元模型和图灵测试奠定了理论基础,达特茅斯会议让"人工智能"成为正式术语,专家系统、国际象棋程序、深度学习、AlphaGo、ChatGPT 以及 DeepSeek-R1 等标志性事件不断推动行业向前。今天开发者面对的重点,已经不只是理解 AI 是什么,而是如何把大模型能力稳定、低成本、可维护地接入应用。

Spring AI 正是在这个背景下出现的。它是 Spring 生态面向 AI 工程的应用框架,目标是把 Spring 一贯强调的可移植性、模块化和 POJO 编程模型带到 AI 应用开发中。开发者可以使用统一的 API 调用不同模型提供商,例如 OpenAI、Anthropic、Microsoft、Amazon、Google、Ollama 以及兼容 OpenAI API 的服务。

Spring AI 支持聊天模型、嵌入模型、图像模型、音频模型和内容审核等能力,并提供同步调用与流式调用。它最大的意义在于降低接入成本:业务代码不用直接处理不同厂商的 HTTP 细节,可以围绕统一抽象构建功能,也更容易在后续切换模型或替换底层服务。

先理解几个核心术语

模型可以理解为经过大量数据训练后得到的一套规则或模式。开发者向模型提供输入,模型根据自身训练得到的能力生成输出。比如点咖啡时,用户的点单就是输入,咖啡师掌握的配方和经验类似模型,最终做出的咖啡就是输出。在 Spring AI 应用中,开发者通常需要选择模型、构造输入、发送请求、接收并处理输出。

LLM 是 Large Language Model 的缩写,也就是大语言模型。它专门处理文本,通常拥有大量参数,能够完成总结、翻译、问答、情感分析、代码生成等任务。常见模型包括 OpenAI 的 GPT 系列、DeepSeek-R1、通义千问 Qwen、Google Gemini 等。不同模型的能力侧重点不同,选择时要结合推理能力、上下文长度、语言支持、成本、响应速度和部署方式。

提示词是提供给模型的指令或文本,用于引导模型生成目标输出。它可以是一个问题、一段描述,也可以是结构化任务说明。从工程角度看,提示词常分为用户提示词和系统提示词。用户提示词用于表达本次请求,例如"总结这段文本";系统提示词用于设定模型角色、行为规范和边界,例如"你是一名严谨的 Java 开发助手,回答要包含关键代码和注意事项"。

词元 Tokens 是大语言模型处理文本时的基本单位。模型的上下文窗口、API 计费、推理耗时和内存占用都与 Tokens 数量有关。输入越冗长,成本越高,响应也可能越慢。因此实际开发中应尽量减少无意义内容,把提示词写得明确、紧凑、结构化。

开发环境与准备工作

使用 Spring AI 前,需要准备合适的 Java 和 Spring Boot 环境。JDK 至少使用 17,因为 Spring Boot 3.x 对 JDK 有明确要求;如果是新项目,JDK 21 也是不错的选择。Spring Boot 推荐使用 3.2 以上版本,新项目可优先选择较新的稳定版本。

如果选择 DeepSeek 作为模型服务,需要在 DeepSeek 开放平台创建 API Key。API Key 只会在创建时展示,应妥善保存,不能提交到代码仓库,也不要暴露在浏览器端或其他客户端代码中。DeepSeek 兼容 OpenAI API,这意味着 Spring AI 的 OpenAI Starter 可以直接用于接入 DeepSeek,只需要配置 API 地址、密钥和模型名称。

初始化 Spring Boot 项目

项目可以采用 Maven 多模块结构。父工程只保留 pom.xml,打包方式设置为 pom,并继承 Spring Boot Starter Parent:

xml 复制代码
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.5.3</version>
    <relativePath/>
</parent>

<properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
</properties>

子模块中添加 Web 和测试依赖,再配置 Spring Boot Maven 插件。为了避免 Spring AI 相关依赖版本冲突,需要引入 Spring AI BOM。BOM 的作用是集中管理一组兼容依赖的版本,项目中具体依赖就不需要逐个写版本号。

xml 复制代码
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>1.0.0-M6</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

然后创建启动类,并在 application.yml 中配置应用名:

yaml 复制代码
spring:
  application:
    name: spring-ai-demo

接入 DeepSeek

Spring AI 为 OpenAI 以及兼容 OpenAI API 的服务提供了 Starter。接入 DeepSeek 时,可以添加如下依赖:

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

配置文件中指定 API Key、基础地址、模型和生成参数:

yaml 复制代码
spring:
  ai:
    openai:
      api-key: sk-your-key
      base-url: https://api.deepseek.com
      chat:
        options:
          model: deepseek-chat
          temperature: 0.7

temperature 用于控制输出随机性。值越高,生成结果越发散;值越低,结果越稳定。实践中不要盲目调高参数,尤其是问答、客服、代码生成等场景,更稳定的输出通常更重要。

配置完成后,业务接口不需要手写 HTTP 请求,只要注入 Spring AI 提供的对象即可完成调用。DeepSeek 接入完成后,切换到 ChatGPT 或其他 OpenAI 兼容服务时,核心业务写法基本保持不变,只需要替换密钥、地址和模型配置。

使用 ChatClient 构建对话

ChatClient 是 Spring AI 中面向业务开发的高阶 API。它封装了与大模型交互的大量细节,提供链式 Fluent API,适合快速实现对话、角色设定、结构化输出、流式响应和拦截增强。

最简单的对话接口可以这样写:

java 复制代码
@GetMapping("/call")
public String chat(String userInput) {
    return chatClient.prompt()
            .user(userInput)
            .call()
            .content();
}

如果希望给智能助手设置固定身份,可以通过默认系统消息完成:

java 复制代码
@Bean
public ChatClient chatClient(ChatClient.Builder builder) {
    return builder
            .defaultSystem("你是一名 Java 学习助手,擅长解释 Spring Boot 和 AI 应用开发问题")
            .build();
}

系统消息会作为对话的基础设定持续影响模型输出。它适合定义角色、语气、回答格式、安全边界和业务范围。

Spring AI 还支持结构化输出。比如让模型生成菜谱,并映射到 Java 对象:

java 复制代码
record Recipe(String dish, List<String> ingredients) {}

@GetMapping("/recipe")
public Recipe recipe(String name) {
    return chatClient.prompt()
            .user("请生成 " + name + " 的菜谱,返回菜名和食材列表")
            .call()
            .entity(Recipe.class);
}

这种写法适合菜单生成、信息抽取、表单填充、分类结果返回等场景。需要注意的是,结构化输出依赖模型按规范生成 JSON,系统提示词和用户提示词应尽量明确字段要求。

流式响应与 SSE

大模型生成长文本时,如果等全部内容完成后再返回,用户会感觉等待时间过长。流式响应的思路是让模型边生成边返回,前端可以逐步渲染结果。ChatClient 使用 stream() 返回响应流:

java 复制代码
@GetMapping(value = "/stream", produces = "text/html;charset=utf-8")
public Flux<String> stream(String userInput) {
    return chatClient.prompt()
            .user(userInput)
            .stream()
            .content();
}

Web 端常用 SSE,也就是 Server-Sent Events。它基于 HTTP,浏览器可通过 EventSource 接收服务端持续推送的数据。SSE 是单向通信,适合模型输出、日志推送、进度反馈等服务端主动返回内容的场景。服务端响应头通常需要声明:

http 复制代码
Content-Type: text/event-stream;charset=utf-8
Connection: keep-alive

SSE 的优点是轻量、兼容性好、部署简单,并且浏览器支持自动重连。对于聊天应用来说,它比一次性响应更接近真实对话体验。

用 Advisor 增强请求与响应

Spring AI 的 Advisor 类似面向 AI 调用链的中间件。它可以在请求发送前和响应返回后插入逻辑,用于日志、敏感词处理、上下文管理、对话记忆、RAG 检索增强等场景。

内置的 SimpleLoggerAdvisor 可以记录请求和响应,方便调试:

java 复制代码
@Bean
public ChatClient chatClient(ChatClient.Builder builder) {
    return builder
            .defaultSystem("你是一名 Java 学习助手")
            .defaultAdvisors(new SimpleLoggerAdvisor())
            .build();
}

也可以只在某次调用中添加 Advisor:

java 复制代码
return chatClient.prompt()
        .user(userInput)
        .advisors(new SimpleLoggerAdvisor())
        .call()
        .content();

如果要看到详细日志,可以在配置中打开对应日志级别:

yaml 复制代码
logging:
  level:
    org.springframework.ai.chat.client.advisor: debug

ChatModel 与 ChatClient 的关系

ChatModel 是更底层的模型交互接口,它接收 Prompt,返回 ChatResponse。开发者可以手动构造用户消息、系统消息和 Prompt,再调用模型:

java 复制代码
Prompt prompt = new Prompt(new UserMessage(message));
ChatResponse response = chatModel.call(prompt);

ChatClient 本质上是对 ChatModel 的封装和增强。ChatModel 更接近原子能力,适合需要精细控制 Prompt 和响应解析的场景;ChatClient 更适合业务开发,链式 API 更简洁,还内置 Advisor、结构化输出、流式响应等扩展能力。

实际项目中,常见选择是优先使用 ChatClient。当业务需要深入控制消息列表、模型参数或响应元数据时,再直接使用 ChatModel。

本地大模型与 Ollama

模型部署有云服务和本地部署两种常见方式。云服务前期成本低、维护简单、扩展方便,但依赖网络,数据需要发送到外部服务;本地部署前期成本和维护复杂度更高,但隐私性更好,长期成本也可能更低。

Ollama 是本地部署大语言模型的常用工具,支持 qwen、deepseek、LLaMA 等模型,并提供本地 API。安装完成后,默认服务地址通常是:

text 复制代码
http://127.0.0.1:11434

拉取模型时可以根据机器配置选择不同参数规模。参数量越大,模型能力通常越强,硬件压力也越高。以 DeepSeek-R1 轻量模型为例:

bash 复制代码
ollama run deepseek-r1:1.5b

Spring AI 接入 Ollama 时,添加 Ollama Starter:

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

配置本地地址和模型:

yaml 复制代码
spring:
  ai:
    ollama:
      base-url: http://localhost:11434
      chat:
        model: deepseek-r1:1.5b

然后可以直接使用 OllamaChatModel 调用,也可以封装成 ChatClient,继续沿用统一的业务写法。

Spring AI Alibaba 与通义模型

对于使用阿里云生态的 Java 开发者,Spring AI Alibaba 提供了面向通义系列模型和百炼平台的适配。它基于 Spring AI 构建,提供 ChatClient、ChatModel、结构化输出、流式响应、向量数据库、函数调用、工具调用、对话记忆和 RAG 等能力。

使用前需要在阿里云百炼平台开通模型服务并创建 API Key。拿到密钥后,可以添加 Spring AI Alibaba 依赖:

xml 复制代码
<dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-starter</artifactId>
    <version>1.0.0-M6.1</version>
</dependency>

配置示例:

yaml 复制代码
server:
  port: 8082
spring:
  ai:
    dashscope:
      api-key: sk-your-key

在 Controller 中注入 ChatClient 后,就可以调用通义模型:

java 复制代码
@RestController
@RequestMapping("/ali")
public class AliController {
    private final ChatClient chatClient;

    public AliController(ChatClient.Builder builder) {
        this.chatClient = builder
                .defaultSystem("你是一个博学的智能聊天助手")
                .defaultAdvisors(new SimpleLoggerAdvisor())
                .build();
    }

    @GetMapping("/chat")
    public String chat(String message) {
        return chatClient.prompt(message).call().content();
    }
}

由于 Spring AI Alibaba 沿用了 Spring AI 的核心抽象,流式响应、结构化输出、默认系统消息、默认用户消息、默认函数、Advisor 等能力都可以继续使用。

多模态能力

多模态指模型同时理解和处理文本、图像、音频、视频等多种信息的能力。人类认识世界并不只依赖文字,还会同时使用视觉、听觉、触觉等多种感知方式。多模态 AI 的目标也是把不同类型的数据融合起来理解。

传统聊天模型只处理文本;多模态模型则可以看图回答、图文结合问答、解析截图、理解设计草图并生成说明。使用阿里云通义视觉模型时,可以开启多模态配置:

yaml 复制代码
spring:
  ai:
    dashscope:
      api-key: sk-your-key
      chat:
        options:
          model: qwen-vl-max-latest
          multi-model: true

业务中可以把图片作为媒体输入,与文本提示词一起发送给模型。典型场景包括图片内容识别、商品图分析、报表截图解读、设计稿转需求说明等。

智能聊天机器人的实现路线

完成基础能力后,可以进一步实现一个智能聊天机器人。目标包括自然对话、流式返回、多轮上下文、历史记录管理,以及在本地模型和云端 API 之间灵活切换。

项目可以使用 Spring Boot Web、Spring AI Ollama Starter、Lombok 和 Spring AI BOM。配置文件中指定本地 Ollama 地址和模型:

yaml 复制代码
spring:
  application:
    name: spring-chat-bot
  ai:
    ollama:
      base-url: http://127.0.0.1:11434
      chat:
        model: deepseek-r1:7b
logging:
  level:
    org.springframework.ai.chat.client.advisor: debug

先定义 ChatClient:

java 复制代码
@Bean
public ChatClient ollamaChatClient(OllamaChatModel model) {
    return ChatClient.builder(model)
            .defaultSystem("你是一款学习助手,用清晰、友好的方式回答问题")
            .defaultAdvisors(new SimpleLoggerAdvisor())
            .build();
}

再实现流式对话接口:

java 复制代码
@RequestMapping(value = "/stream", produces = "text/html;charset=utf-8")
public Flux<String> stream(String prompt) {
    return chatClient.prompt()
            .user(prompt)
            .stream()
            .content();
}

此时机器人已经能回答问题,但还没有记忆。大语言模型本身通常是无状态的,如果希望它理解多轮对话,就要把历史消息与当前输入一起交给模型。Spring AI 提供了 ChatMemory,用于按照会话标识存储和读取消息。

java 复制代码
@Bean
public ChatMemory chatMemory() {
    return new InMemoryChatMemory();
}

把 ChatMemory 注入 ChatClient,并添加记忆 Advisor:

java 复制代码
@Bean
public ChatClient ollamaChatClient(OllamaChatModel model, ChatMemory chatMemory) {
    return ChatClient.builder(model)
            .defaultSystem("你是一款学习助手")
            .defaultAdvisors(
                    new SimpleLoggerAdvisor(),
                    new MessageChatMemoryAdvisor(chatMemory)
            )
            .build();
}

调用时传入 chatId,让不同会话相互隔离:

java 复制代码
@RequestMapping(value = "/stream", produces = "text/html;charset=utf-8")
public Flux<String> stream(String prompt, String chatId) {
    return chatClient.prompt()
            .user(prompt)
            .advisors(spec -> spec.param(
                    AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY,
                    chatId
            ))
            .stream()
            .content();
}

有了对话记忆后,还需要管理历史会话列表。可以定义 ChatInfo 保存标题和会话标识,再通过内存 Map 保存会话索引:

java 复制代码
@Data
public class ChatInfo {
    private String title;
    private String chatId;
}

历史记录接口通常包含这些能力:保存会话、获取会话列表、根据 chatId 读取最近若干条消息、删除指定会话。读取消息时,可以把 Spring AI 的 Message 转成前端更容易使用的 VO,例如包含 rolecontent 字段。

如果后续要从本地 Ollama 切换到 DeepSeek 开放 API,只需要添加 OpenAI Starter,改为 OpenAI 兼容配置,并把 ChatClient 构建时注入的模型从 OllamaChatModel 换成 OpenAiChatModel

yaml 复制代码
spring:
  ai:
    openai:
      api-key: sk-your-key
      base-url: https://api.deepseek.com
      chat:
        options:
          model: deepseek-chat
          temperature: 0.7
java 复制代码
@Bean
public ChatClient deepSeekChatClient(OpenAiChatModel model, ChatMemory chatMemory) {
    return ChatClient.builder(model)
            .defaultSystem("你是一款学习助手")
            .defaultAdvisors(
                    new SimpleLoggerAdvisor(),
                    new MessageChatMemoryAdvisor(chatMemory)
            )
            .build();
}

这正是 Spring AI 抽象带来的好处:上层接口、流式返回、记忆和历史管理逻辑基本不需要重写,底层模型服务可以根据成本、效果和部署要求进行替换。

总结

Spring AI 让 Java 开发者可以用熟悉的 Spring Boot 方式构建 AI 应用。入门时先理解模型、提示词、Tokens、ChatClient 和 ChatModel,再接入 DeepSeek 或 OpenAI 兼容服务;随后加入流式响应、日志 Advisor、结构化输出和 SSE;当需要私有化能力时,可以使用 Ollama 部署本地模型;当使用阿里云生态时,可以通过 Spring AI Alibaba 接入通义模型和多模态能力。

最终落到业务应用,智能聊天机器人并不只是一个调用大模型的接口。它需要角色设定、流式体验、对话记忆、历史记录、会话隔离,以及灵活切换模型服务的能力。把这些能力组合起来,才是一个可扩展、可维护、接近真实业务需求的 Spring AI 应用。

相关推荐
码不停蹄的玄黓1 小时前
Arthas 线上问题排查实战:CPU过高、频繁GC
java
Michaelwubo1 小时前
swagger全集通+mock(prism)
java
诸葛务农1 小时前
共沸脱水技术及其在光刻胶用PGMEA纯化中的应用(中)
linux·数据库·人工智能
roman_日积跬步-终至千里1 小时前
【SDD】高风险场景下的 SDD 最佳实践:分层风控+分级落地,约束AI编程边界
大数据·人工智能·ai编程
小小高不懂写代码1 小时前
Vibe Coding时代的自我鞭策
前端·人工智能
计算机安禾1 小时前
【算法分析与设计】第36篇:计算几何基础:凸包问题的分治与扫描线解法
大数据·人工智能·算法·机器学习·剪枝
人员安全定位1 小时前
喜报!品铂科技获2025年度电力建设科学技术进步奖
大数据·人工智能·科技
库拉大叔1 小时前
GPT-5.5 新手快速上手与实战指南
网络·人工智能·gpt
AI智图坊1 小时前
拒绝模板同质化:拆解自由生图功能,如何通过GPT-Image-2与Nano Banana Pro双模型驱动电商AIGC?
大数据·人工智能·gpt·ai作画·aigc