本文介绍如何在 Spring Boot 项目中使用 Spring AI 接入 DeepSeek Chat 模型,实现一个简单的对话接口。示例包含 Maven 依赖、
application.yml配置、ChatClient调用代码以及常见问题排查。示例基于当前 Spring AI 2.0.x 的自动配置方式。Spring AI 和 DeepSeek 的模型名称会随版本变化,实际使用时请以对应版本的官方文档为准。
一、准备工作
开始之前,需要准备:
-
JDK 17 或更高版本;
-
Maven 3.9+;
-
一个 Spring Boot 项目;
-
一个 DeepSeek API Key。
DeepSeek API Key 可以在 DeepSeek API Keys 页面 创建。
不要把 API Key 直接提交到 Git 仓库。 推荐通过环境变量、配置中心或密钥管理服务注入。
二、创建项目并添加 Maven 依赖
下面给出一个完整的 pom.xml 关键配置。Spring AI 官方当前稳定版本为 2.0.x,示例使用 2.0.0 BOM;如果项目使用其他 Spring AI 版本,只需要将 BOM 版本替换为项目实际版本。
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.0.0</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>spring-ai-deepseek-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-ai-deepseek-demo</name>
<properties>
<java.version>17</java.version>
<spring-ai.version>2.0.0</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>
<dependencies>
<!-- Web 接口 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring AI DeepSeek Chat 自动配置 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-deepseek</artifactId>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
版本说明
-
Spring AI 2.0.x 对应 Spring Boot 4.0.x/4.1.x;
-
如果项目仍然使用 Spring Boot 3.x ,请选择与之匹配的 Spring AI 1.x 版本;
-
不建议只修改 Spring Boot 或 Spring AI 的单个版本号,最好按照 Spring AI 官方兼容矩阵整体调整。
三、配置 application.yml
在 src/main/resources/application.yml 中添加以下内容:
yaml
server:
port: 8080
spring:
application:
name: spring-ai-deepseek-demo
ai:
deepseek:
# 从环境变量中读取 API Key,避免将密钥写入源码
api-key: ${DEEPSEEK_API_KEY}
# DeepSeek OpenAI 兼容接口的基础地址
base-url: https://api.deepseek.com
chat:
# 当前 API 文档推荐使用 deepseek-flash;也可以根据账户能力选择其他模型
model: deepseek-flash
# 编程、数学类任务可以使用较低的 temperature
temperature: 0.7
# 是否启用思考模式 ,按模型和 Spring AI 版本支持情况选择
thinking:
type: enabled
在 Linux 或 macOS 中设置环境变量:
bash
export DEEPSEEK_API_KEY="你的 DeepSeek API Key"
Windows PowerShell:
$env:DEEPSEEK_API_KEY = "你的 DeepSeek API Key"
关于模型名称
不同时间点的 DeepSeek API 和 Spring AI 版本可能使用不同的模型名称。例如:
-
新版 DeepSeek API 文档中可见
deepseek-flash、deepseek-v4-pro; -
部分旧版示例使用
deepseek-chat、deepseek-reasoner; -
Spring AI 某些版本的默认值或示例可能出现
deepseek-v4-flash、deepseek-v4-pro。
如果启动后出现模型不存在、模型已下线等错误,应以 DeepSeek 控制台和当前 API 文档中的可用模型列表为准,并修改 spring.ai.deepseek.chat.model。
四、编写启动类
java
package com.example.deepseek;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DeepSeekApplication {
public static void main(String[] args) {
SpringApplication.run(DeepSeekApplication.class, args);
}
}
添加 spring-ai-starter-model-deepseek 后,Spring Boot 会自动创建 DeepSeek Chat 模型相关 Bean,同时提供可注入的 ChatClient.Builder。
五、使用 ChatClient 调用 DeepSeek
推荐使用 Spring AI 的 ChatClient,它提供了简洁的链式 API。
java
package com.example.deepseek.controller;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ChatController {
private final ChatClient chatClient;
public ChatController(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
@GetMapping("/ai/chat")
public String chat(
@RequestParam(value = "message", defaultValue = "请介绍一下 Spring AI")
String message) {
return chatClient.prompt()
.user(message)
.call()
.content();
}
}
启动项目:
bash
mvn spring-boot:run
调用接口:
bash
curl --get 'http://localhost:8080/ai/chat' \
--data-urlencode 'message=Spring AI 的 ChatClient 有什么作用?'
返回结果就是 DeepSeek 模型生成的文本 。
六、设置系统提示词
在实际项目中,通常需要通过系统提示词约束模型的角色和输出风格。例如,让模型始终以 Java 专家的身份回答问题:
java
package com.example.deepseek.config;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AiConfig {
@Bean
public ChatClient chatClient(ChatClient.Builder builder) {
return builder
.defaultSystem("你是一名资深 Java 专家,请使用简洁、准确的中文回答问题。")
.build();
}
}
此时控制器可以直接注入已经配置好的 ChatClient:
java
package com.example.deepseek.controller;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ChatController {
private final ChatClient chatClient;
public ChatController(ChatClient chatClient) {
this.chatClient = chatClient;
}
@GetMapping("/ai/java-question")
public String javaQuestion(@RequestParam String question) {
return chatClient.prompt()
.user(question)
.call()
.content();
}
}
七、使用 Service 层封装调用逻辑
如果项目规模较大,建议不要把所有 AI 调用逻辑写在 Controller 中,可以通过 Service 统一封装:
java
package com.example.deepseek.service;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.stereotype.Service;
@Service
public class DeepSeekService {
private final ChatClient chatClient;
public DeepSeekService(ChatClient.Builder builder) {
this.chatClient = builder
.defaultSystem("你是一个专业、严谨的中文智能助手。")
.build();
}
public String chat(String message) {
return chatClient.prompt()
.user(message)
.call()
.content();
}
}
Controller:
java
package com.example.deepseek.controller;
import com.example.deepseek.service.DeepSeekService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DeepSeekController {
private final DeepSeekService deepSeekService;
public DeepSeekController(DeepSeekService deepSeekService) {
this.deepSeekService = deepSeekService;
}
@GetMapping("/ai/ask")
public String ask(@RequestParam String message) {
return deepSeekService.chat(message);
}
}
八、在运行时覆盖模型参数
除了在 application.yml 中设置默认参数,也可以针对某一次请求使用运行时选项覆盖模型和温度。不同 Spring AI 版本的选项构造器 API 可能略有变化,下面给出常见写法:
java
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.deepseek.DeepSeekChatOptions;
public String creativeChat(ChatClient chatClient, String message) {
return chatClient.prompt()
.user(message)
.options(DeepSeekChatOptions.builder()
.model("deepseek-flash")
.temperature(1.2)
.build())
.call()
.content();
}
如果编译器提示 DeepSeekChatOptions 的构造方法或方法名不匹配,请以当前 Spring AI 版本的 JavaDoc 为准,因为不同版本可能使用 withModel、withTemperature 或新的 builder 方法命名。
九、异常处理建议
生产环境不要把完整异常堆栈直接返回给前端,可以统一处理异常并记录请求 ID:
java
package com.example.deepseek.handler;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.Map;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class )
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public Map<String, String> handleException(Exception ex) {
// 实际项目中应使用日志框架记录 ex,不建议将详细异常返回给客户端
return Map.of("message", "AI 服务调用失败,请稍后重试");
}
}
对于网络抖动、临时服务不可用等问题,可以结合 Spring AI 的 spring.ai.retry 配置调整重试策略:
yaml
spring:
ai:
retry:
max-attempts: 3
backoff:
initial-interval: 1s
multiplier: 2
max-interval: 10s
# 是否对客户端 4xx 错误进行重试,通常保持 false
on-client-errors: false
不要对无效 API Key、参数错误等 4xx 错误进行无限重试,否则可能放大问题并增加调用成本。
十、常见问题
1. 启动时报 API Key 为空
确认环境变量已经设置,并且启动 Spring Boot 的终端能够读取到该变量:
bash
echo "$DEEPSEEK_API_KEY"
也可以临时在本地 application.yml 中配置,但不要提交到公共仓库:
yaml
spring:
ai:
deepseek:
api-key: sk-xxxxxxxx
2. 返回 401 Unauthorized
通常表示 API Key 无效、已撤销,或请求使用了错误的账号密钥。重新检查 DeepSeek 控制台中的 Key,并确认没有多余的空格和引号。
3. 返回模型不存在
检查 spring.ai.deepseek.chat.model。模型名称会随着 DeepSeek API 版本调整,优先使用账户当前可用的模型名。旧教程中的 deepseek-chat 不一定适用于当前账号或当前 API。
4. 找不到 ChatClient.Builder
确认:
-
已添加
spring-ai-starter-model-deepseek; -
Spring AI BOM 与 starter 版本一致;
-
没有错误地使用旧版模块名;
-
项目确实启用了 Spring Boot 自动配置。
5. 为什么不直接使用 WebClient 调用接口
直接使用 WebClient 当然可以,但需要自己处理请求结构、响应解析、重试、模型选项和消息抽象。Spring AI 的价值在于提供统一的 Chat Model 和 ChatClient 抽象,后续切换其他模型时,业务代码改动更小。
十一、项目目录示例
spring-ai-deepseek-demo
├── pom.xml
└── src
└── main
├── java
│ └── com/example/deepseek
│ ├── DeepSeekApplication.java
│ ├── config
│ │ └── AiConfig.java
│ ├── controller
│ │ └── ChatController.java
│ └── service
│ └── DeepSeekService.java
└── resources
└── application.yml
十二、总结
使用 Spring AI 接入 DeepSeek 的核心步骤只有三步:
-
在
pom.xml中引入spring-ai-starter-model-deepseek; -
在
application.yml中配置spring.ai.deepseek.api-key和模型名称; -
注入
ChatClient.Builder,通过prompt().user(...).call().content()发起调用。
完整调用代码非常简洁:
java
return chatClient.prompt()
.user(message)
.call()
.content();
在生产环境中,还应进一步完善 API Key 管理、超时控制、重试策略、日志脱敏、调用限流、Token 成本统计以及敏感内容审核等机制。