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,例如包含 role 和 content 字段。
如果后续要从本地 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 应用。