SpringBoot+DeepSeek实现第一个AI聊天接口
作者:我有满天星辰
Spring AI 实战:Spring Boot + DeepSeek 实现第一个 AI 聊天接口
我们不再停留在概念层面,而是从 0 创建一个 Spring Boot 项目,接入 DeepSeek,并使用 Spring AI 提供的 ChatClient 实现一个真正可以运行的 AI 聊天接口。
本章最终效果非常简单:
用户 ↓ HTTP 请求 ↓ Spring Boot ↓ Spring AI ChatClient ↓ DeepSeek ↓ AI 返回答案
最终我们可以通过接口:
POST /api/ai/chat
发送:
{
"message": "什么是 Spring AI?"
}得到:
{
"answer": "Spring AI 是 Spring 生态面向 AI 应用开发提供的框架和抽象..."
}这也是后续学习 RAG、Tool Calling、Agent 等高级能力的基础。
一、本章目标
完成本章之后,我们将拥有一个最基础的 Spring AI AI 聊天 服务。
具体完成:
✓ 创建 Spring Boot 项目 ✓ 添加 Spring AI 依赖 ✓ 配置 DeepSeek ✓ 创建 ChatClient ✓ 创建 AI 聊天接口 ✓ 启动项目 ✓ 使用 Postman 测试 ✓ 理解 ChatClient 调用流程
最终项目结构:
spring-ai-chat-demo
├── pom.xml
└── src
└── main
├── java
│ └── com.example.ai
│ ├── AiApplication.java
│ └── controller
│ └── AiChatController.java
│
└── resources
└── application.yml二、先理解一下整体架构
在真正开始写代码之前,我们先搞清楚整个请求是怎么走的。
┌───────────────┐
│ 用户 │
└───────┬───────┘
│
│ HTTP POST
↓
┌────────────────────┐
│ Spring Boot │
│ AiChatController │
└────────┬───────────┘
│
↓
┌────────────────────┐
│ Spring AI │
│ ChatClient │
└────────┬───────────┘
│
↓
┌────────────────────┐
│ Spring AI │
│ ChatModel │
└────────┬───────────┘
│
│ API Request
↓
┌────────────────────┐
│ DeepSeek │
│ LLM │
└────────┬───────────┘
│
│ AI Response
↓
┌────────────────────┐
│ ChatClient │
└────────┬───────────┘
↓
┌────────────────────┐
│ Spring Boot API │
└────────┬───────────┘
↓
用户
这里需要记住一个非常重要的关系:
Controller
↓
ChatClient
↓
ChatModel
↓
DeepSeek
后面学习 Spring AI 的过程中,这几个概念会反复出现。
三、环境准备
开始之前,需要准备以下环境。
3.1 JDK
建议使用:
JDK 17+
检查 Java 版本:
java -version
例如:
java version "17.x.x"
四、创建 Spring Boot 项目
可以使用 Spring Initializr 创建项目。
项目基础信息可以设置为:
Project: Maven Language: Java Spring Boot: 当前稳定版本 Group: com.example Artifact: spring-ai-chat-demo Name: spring-ai-chat-demo Packaging: Jar Java: 17
项目创建完成之后,用 IntelliJ IDEA 打开。
五、添加 Spring AI 依赖
Spring AI 项目建议通过 Spring AI BOM 管理版本。
在 pom.xml 中加入对应的 Spring AI BOM,然后添加 OpenAI 兼容模型相关的 Starter。
一个典型配置可以写成:
<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>然后添加:
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>这里需要注意:
Spring AI 的版本需要与你使用的 Spring Boot 版本保持兼容。
不同 Spring AI 版本的 Starter 名称、配置属性和 API 可能存在差异。
因此实际项目中不要机械复制旧教程里的版本号,应该以你当前使用的 Spring AI 版本官方文档为准。
六、为什么使用 OpenAI Starter?
这里可能会产生一个疑问:
“我们明明使用的是 DeepSeek,为什么添加的是 OpenAI Starter?”
这是因为很多国产大模型提供了与 OpenAI API 兼容的接口。
也就是说:
Spring AI ↓ OpenAI-compatible API ↓ DeepSeek
因此,我们可以利用 Spring AI 的 OpenAI 模型集成能力连接 DeepSeek。
这也是一个非常实用的设计:
应用层不需要关心底层 API 的大量 HTTP 细节。
七、配置 DeepSeek
接下来配置 DeepSeek API。
在:
src/main/resources/application.yml
添加:
spring:
ai:
openai:
api-key: ${DEEPSEEK_API_KEY}
base-url: https://api.deepseek.com
chat:
options:
model: deepseek-chat这里有几个非常重要的配置。
7.1 api-key
api-key: ${DEEPSEEK_API_KEY}不要直接把 API Key 写死在代码里面。
不推荐:
api-key: sk-xxxxxxxx
推荐:
api-key: ${DEEPSEEK_API_KEY}
然后通过环境变量提供:
export DEEPSEEK_API_KEY=你的API_KEY
Windows 可以使用对应的环境变量配置方式。
这样做的好处是:
代码 ↓ 不会保存 Secret ↓ Git 提交 ↓ 不会意外泄露 API Key
八、base-url 是什么?
这里:
base-url: https://api.deepseek.com
表示:
Spring AI 应该把模型请求发送到哪里。
如果你使用的是 OpenAI,那么对应地址会不同。
如果使用 DeepSeek,则需要配置 DeepSeek 的 API 地址。
因此可以理解成:
ChatClient ↓ ChatModel ↓ base-url ↓ DeepSeek API
九、model 是什么?
这里:
model: deepseek-chat
表示:
使用哪个模型处理请求。
模型是 AI 应用非常重要的一个概念。
例如:
deepseek-chat
用于普通聊天场景。
具体可使用哪些模型,需要以 DeepSeek 当前提供的模型列表和 API 文档为准。
十、创建 Spring Boot 启动类
创建:
AiApplication.java
代码:
package com.example.ai;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AiApplication {
public static void main(String[] args) {
SpringApplication.run(AiApplication.class, args);
}
}这是标准的 Spring Boot 启动类。
启动:
mvn spring-boot:run
如果看到:
Started AiApplication
说明 Spring Boot 已经启动成功。
十一、创建 ChatClient
接下来进入 Spring AI 最核心的一步。
我们需要创建:
ChatClient
可以使用 Spring AI 自动配置的 ChatClient.Builder 创建:
package com.example.ai.controller;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/ai")
public class AiChatController {
private final ChatClient chatClient;
public AiChatController(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
}这里发生了什么?
Spring Boot 启动时会根据我们配置的模型自动创建相关 AI 组件。
然后 Spring AI 提供:
ChatClient.Builder
我们通过:
chatClientBuilder.build();
得到:
ChatClient
于是:
Spring Boot
↓
自动配置
↓
ChatClient.Builder
↓
ChatClient
十二、实现第一个 AI 聊天接口
接下来添加:
@PostMapping("/chat")
public String chat(@RequestParam String message) {
return chatClient
.prompt()
.user(message)
.call()
.content();
}完整代码:
package com.example.ai.controller;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/ai")
public class AiChatController {
private final ChatClient chatClient;
public AiChatController(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
@PostMapping("/chat")
public String chat(@RequestParam String message) {
return chatClient
.prompt()
.user(message)
.call()
.content();
}
}现在我们的第一个 AI 接口就完成了。
十三、这几行代码到底做了什么?
第一次看到:
chatClient
.prompt()
.user(message)
.call()
.content();可能会觉得:
“这么简单?”
没错,Spring AI 的目标之一就是把底层复杂度封装起来。
我们拆开来看。
13.1 prompt()
chatClient.prompt()
表示:
创建一次 AI 请求。
可以理解成:
ChatClient
↓
创建 Prompt 请求
13.2 user()
.user(message)
表示:
设置用户发送给 AI 的消息。
例如:
message = "什么是 Spring AI?"
最终形成:
User Message
↓
什么是 Spring AI?
13.3 call()
.call()
表示:
真正执行模型调用。
前面的:
prompt() user()
主要是在构建请求。
到了:
call()
才真正发起调用。
整体过程:
prompt() ↓ 构建 Prompt ↓ user() ↓ 添加 User Message ↓ call() ↓ 调用 DeepSeek
13.4 content()
最后:
.content()
表示:
获取模型返回的文本内容。
所以整个代码可以翻译成人话:
创建一次 AI 请求
↓
告诉 AI 用户的问题
↓
发送请求
↓
获取 AI 返回的文本
十四、启动项目
启动:
mvn spring-boot:run
或者直接使用 IntelliJ IDEA 启动:
AiApplication ↓ Run
默认情况下:
http://localhost:8080
十五、使用 Postman 测试
发送:
POST http://localhost:8080/api/ai/chat?message=什么是Spring%20AI?
如果配置正确,你应该能够得到类似:
Spring AI 是 Spring 生态面向 AI 应用开发提供的框架和抽象……
这意味着:
Spring Boot
↓
Spring AI
↓
DeepSeek
↓
AI
已经完整打通。
十六、使用 curl 测试
也可以直接使用:
curl -X POST \ "http://localhost:8080/api/ai/chat?message=请介绍一下Spring%20AI"
如果调用成功,就会直接看到模型返回结果。
十七、目前的接口有什么问题?
虽然我们的接口已经可以运行,但是它还比较简陋。
现在请求:
POST /api/ai/chat?message=你好
返回:
你好!有什么可以帮助你的吗?
这对于 Demo 足够了。
但是如果是真正的后端项目,我们一般不会让接口直接返回一个字符串。
更合理的是:
{
"message": "你好",
"answer": "你好!有什么可以帮助你的吗?"
}所以我们可以定义请求对象。
十八、定义 ChatRequest
创建:
ChatRequest.java
package com.example.ai.dto;
public record ChatRequest(
String message
) {
}然后修改 Controller:
@PostMapping("/chat")
public String chat(@RequestBody ChatRequest request) {
return chatClient
.prompt()
.user(request.message())
.call()
.content();
}请求:
{
"message": "什么是 Spring AI?"
}这样更符合 REST API 的开发习惯。
十九、进一步封装 Service
随着项目越来越复杂,我们不建议把 AI 调用逻辑全部放到 Controller。
更合理的结构:
Controller
↓
Service
↓
ChatClient
↓
DeepSeek
创建:
AiChatService.java
package com.example.ai.service;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.stereotype.Service;
@Service
public class AiChatService {
private final ChatClient chatClient;
public AiChatService(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
public String chat(String message) {
return chatClient
.prompt()
.user(message)
.call()
.content();
}
}Controller:
package com.example.ai.controller;
import com.example.ai.dto.ChatRequest;
import com.example.ai.service.AiChatService;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/ai")
public class AiChatController {
private final AiChatService aiChatService;
public AiChatController(AiChatService aiChatService) {
this.aiChatService = aiChatService;
}
@PostMapping("/chat")
public String chat(@RequestBody ChatRequest request) {
return aiChatService.chat(request.message());
}
}这样结构就变成:
HTTP ↓ Controller ↓ Service ↓ ChatClient ↓ ChatModel ↓ DeepSeek
这才是更接近真实项目的写法。
二十、为什么要进行 Controller / Service 分层?
因为 AI 应用后面会越来越复杂。
现在:
chat(message)
以后可能变成:
chat() ├── Prompt ├── Memory ├── Advisor ├── RAG ├── Tool Calling ├── Logging └── Exception Handling
如果全部写在 Controller:
Controller ↓ 大量 AI 业务逻辑
代码很容易失控。
所以:
Controller ↓ 只负责 HTTP Service ↓ 负责业务 Spring AI ↓ 负责 AI 能力
职责更加清晰。
二十一、完整项目结构
现在我们的项目可以整理成:
spring-ai-chat-demo
│
├── pom.xml
│
└── src
└── main
├── java
│ └── com.example.ai
│ │
│ ├── AiApplication.java
│ │
│ ├── controller
│ │ └── AiChatController.java
│ │
│ ├── service
│ │ └── AiChatService.java
│ │
│ └── dto
│ └── ChatRequest.java
│
└── resources
└── application.yml虽然项目很小,但已经有一个基本的分层结构。
二十二、完整请求流程
现在重新看一次整个流程:
用户
│
│ POST
↓
┌────────────────────┐
│ AiChatController │
└─────────┬──────────┘
│
↓
┌────────────────────┐
│ AiChatService │
└─────────┬──────────┘
│
↓
┌────────────────────┐
│ ChatClient │
└─────────┬──────────┘
│
↓
┌────────────────────┐
│ ChatModel │
└─────────┬──────────┘
│
↓
┌────────────────────┐
│ DeepSeek │
└─────────┬──────────┘
│
↓
AI Response
│
↓
用户
这张图非常重要。
后面我们学习 Spring AI 的其他能力,本质上都是在这个基础上不断扩展。
二十三、到这里,我们真正学到了什么?
表面上看,这一章只是写了一个:
/api/ai/chat
但实际上我们已经建立了 Spring AI 的第一个核心认知:
Spring Boot
↓
Spring AI
↓
ChatClient
↓
ChatModel
↓
LLM
同时理解了:
prompt() user() call() content()
分别承担什么作用。
二十四、为什么不直接使用 RestClient?
这是一个非常值得思考的问题。
当然可以。
你完全可以自己:
RestClient ↓ HTTP ↓ DeepSeek API
但是随着项目变复杂,你还需要自己处理:
模型适配 消息结构 Streaming Tool Calling Structured Output Embedding Vector Store RAG
Spring AI 的价值就在这里。
它不是让:
“调用一个 API”
变得多么神奇。
而是希望:
把 AI 应用开发过程中大量重复的基础能力进行抽象,让开发者可以把更多精力放在业务本身。
二十五、常见问题
问题 1:启动时报 API Key 错误
例如:
401 Unauthorized
首先检查:
echo $DEEPSEEK_API_KEY
确认环境变量是否存在。
然后检查:
spring:
ai:
openai:
api-key: ${DEEPSEEK_API_KEY}是否配置正确。
问题 2:模型不存在
如果出现类似:
model not found
检查:
model: deepseek-chat
是否仍然是当前 DeepSeek API 支持的模型名称。
模型名称会随着模型服务商的产品变化,因此应以当前官方模型列表为准。
问题 3:为什么 DeepSeek 使用 OpenAI Starter?
因为 DeepSeek 提供了 OpenAI 兼容接口。
因此 Spring AI 可以使用 OpenAI 模型集成能力连接 DeepSeek。
需要注意:
OpenAI Starter 并不意味着你必须使用 OpenAI 模型。
这里主要使用的是兼容的 API 接口规范。
问题 4:为什么不把 API Key 写在 application.yml?
不推荐:
api-key: sk-xxxx
因为:
Git ↓ 提交代码 ↓ API Key 泄露
更推荐:
api-key: ${DEEPSEEK_API_KEY}
使用环境变量或者安全的 Secret 管理系统。
二十六、本章总结
这一章我们从 0 开始创建了一个 Spring AI 项目,并成功完成:
Spring Boot
↓
Spring AI
↓
ChatClient
↓
DeepSeek
↓
AI Response
我们还学习了:
ChatClient ChatModel Prompt User Message call() content()
并最终实现了:
POST /api/ai/chat
可以把用户问题发送给 DeepSeek,并获得 AI 返回结果。
二十七、但是,现在的 AI 还非常“笨”
目前我们只是:
用户 ↓ 问题 ↓ DeepSeek ↓ 答案
它还不知道:
你的身份 你的业务 你的公司 你的知识库 你的数据库 你的系统能力
例如用户问:
“我们公司的退款规则是什么?”
现在的 AI 很可能无法回答。
那么怎么办?
我们需要学习:
Prompt
通过 System Prompt,我们可以告诉 AI:
你是谁? 你的职责是什么? 你应该如何回答? 你不能回答什么? 回答需要遵循什么格式?
再进一步,我们还可以让 AI:
读取公司文档 ↓ 查询数据库 ↓ 调用 Java 方法 ↓ 检索知识库
这时候 AI 才真正开始进入企业业务系统。
以上就是SpringBoot+DeepSeek实现第一个AI聊天接口的详细内容,更多关于SpringBoot DeepSeek AI聊天接口的资料请关注脚本之家其它相关文章!
