主题
DeepSeek 聊天
Spring AI 支持来自 DeepSeek 的各类 AI 语言模型。你可以与 DeepSeek 语言模型交互,并基于 DeepSeek 模型创建一个多语言对话助手。
前置条件
你需要在 DeepSeek 创建一个 API 密钥才能访问 DeepSeek 语言模型。
在 DeepSeek 注册页 创建账户,并在 API Keys 页 生成一个令牌。
Spring AI 项目定义了一个名为 spring.ai.deepseek.api-key 的配置属性,你应把它设为从 API Keys 页获取的 API Key 的值。
你可以在 application.properties 文件中设置此配置属性:
properties
spring.ai.deepseek.api-key=<your-deepseek-api-key>为在 handling 诸如 API 密钥这类敏感信息时获得更强的安全性,你可以使用 Spring 表达式语言(SpEL)引用一个自定义环境变量:
yaml
# In application.yml
spring:
ai:
deepseek:
api-key: ${DEEPSEEK_API_KEY}bash
# In your environment or .env file
export DEEPSEEK_API_KEY=<your-deepseek-api-key>你也可以在应用代码中以编程方式设置此配置属性:
java
// Retrieve API key from a secure source or environment variable
String apiKey = System.getenv("DEEPSEEK_API_KEY");添加仓库与 BOM
Spring AI 制品发布在 Spring Milestone 和 Snapshot 仓库。参阅 制品仓库 一节,把这些仓库添加到你的构建系统。
为帮助依赖管理,Spring AI 提供一个 BOM(物料清单)以确保你整个项目使用一致版本的 Spring AI。参阅 依赖管理 一节,把 Spring AI BOM 添加到你的构建系统。
自动配置
Spring AI 为 DeepSeek 聊天模型提供 Spring Boot 自动配置。 要启用它,请将以下依赖添加到你的项目的 Maven pom.xml 文件:
xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-deepseek</artifactId>
</dependency>或添加到你的 Gradle build.gradle 文件。
groovy
dependencies {
implementation 'org.springframework.ai:spring-ai-starter-model-deepseek'
}TIP
参见 依赖管理 一节,把 Spring AI BOM 添加到你的构建文件。
聊天属性
重试属性
前缀 spring.ai.retry 用作配置 DeepSeek 聊天模型重试机制的属性前缀。
| 属性 | 描述 | 默认值 |
|---|---|---|
| spring.ai.retry.max-attempts | 最大重试尝试次数。 | 10 |
| spring.ai.retry.backoff.initial-interval | 指数退避策略的初始休眠时长。 | 2 sec. |
| spring.ai.retry.backoff.multiplier | 退避间隔倍数。 | 5 |
| spring.ai.retry.backoff.max-interval | 最大退避时长。 | 3 min. |
| spring.ai.retry.on-client-errors | 若为 false,抛出 NonTransientAiException,且对 4xx 客户端错误码不尝试重试 | false |
| spring.ai.retry.exclude-on-http-codes | 不应触发重试的 HTTP 状态码列表(例如以抛出 NonTransientAiException)。 | empty |
| spring.ai.retry.on-http-codes | 应触发重试的 HTTP 状态码列表(例如以抛出 TransientAiException)。 | empty |
连接属性
前缀 spring.ai.deepseek 用作连接 DeepSeek 的属性前缀。
| 属性 | 描述 | 默认值 |
|---|---|---|
| spring.ai.deepseek.base-url | 要连接到的 URL | +https://api.deepseek.com+ |
| spring.ai.deepseek.api-key | API 密钥 | - |
配置属性
NOTE
聊天自动配置的启用与禁用,现通过以 spring.ai.model.chat 为前缀的顶层属性来配置。
要启用,spring.ai.model.chat=deepseek(默认启用)
要禁用,spring.ai.model.chat=none(或任何不匹配 deepseek 的值)
做出此变更是为了支持配置多个模型。
前缀 spring.ai.deepseek.chat 是为 DeepSeek 配置聊天模型实现的属性前缀。
| 属性 | 描述 | 默认值 |
|---|---|---|
| spring.ai.deepseek.chat.enabled (Removed and no longer valid) | 启用 DeepSeek 聊天模型。 | true |
| spring.ai.model.chat | 启用 DeepSeek 聊天模型。 | deepseek |
| spring.ai.deepseek.chat.base-url | 可选,覆盖 spring.ai.deepseek.base-url 以提供一个聊天专用 URL | +https://api.deepseek.com/+ |
| spring.ai.deepseek.chat.api-key | 可选,覆盖 spring.ai.deepseek.api-key 以提供一个聊天专用 API 密钥 | - |
| spring.ai.deepseek.chat.completions-path | 聊天补全端点的路径 | /chat/completions |
| spring.ai.deepseek.chat.beta-prefix-path | beta 特性端点的前缀路径 | /beta |
| spring.ai.deepseek.chat.model | 要使用的模型 ID。你可以使用 deepseek-v4-flash、deepseek-v4-pro、deepseek-chat 或 deepseek-reasoner。 | deepseek-v4-flash |
| spring.ai.deepseek.chat.frequency-penalty | -2.0 到 2.0 之间的数。正值依据新令牌在迄今文本中的既有频率对其加以惩罚,降低模型逐字重复同一行的可能性。 | 0.0f |
| spring.ai.deepseek.chat.max-tokens | 在聊天补全中要生成的最大令牌数。输入令牌与生成令牌的总长度受模型上下文窗口长度限制。 | - |
| spring.ai.deepseek.chat.presence-penalty | -2.0 到 2.0 之间的数。正值依据新令牌是否已在迄今文本中出现对其加以惩罚,提升模型谈论新话题的可能性。 | 0.0f |
| spring.ai.deepseek.chat.stop | 最多 4 个序列,API 到此处会停止生成更多令牌。 | - |
| spring.ai.deepseek.chat.temperature | 要使用的采样温度,介于 0 与 2 之间。较高的值如 0.8 会让输出更随机,而较低的值如 0.2 会让它更聚焦、更确定。我们通常建议调整此项或 top_p,但不要同时调整两者。 | 1.0F |
| spring.ai.deepseek.chat.top-p | temperature 采样的替代方案,即核采样,模型会考虑具有 top_p 概率质量的那些令牌的结果。所以 0.1 意味着只考虑构成前 10% 概率质量的令牌。我们通常建议调整此项或 temperature,但不要同时调整两者。 | 1.0F |
| spring.ai.deepseek.chat.logprobs | 是否返回输出令牌的日志概率。若为 true,返回消息 content 中每个输出令牌的日志概率。 | - |
| spring.ai.deepseek.chat.top-logprobs | 一个介于 0 与 20 之间的整数,指定在每个令牌位置要返回的最可能令牌数,每个都附带一个相关日志概率。若使用此参数,logprobs 必须设为 true。 | - |
| spring.ai.deepseek.chat.thinking.type | 控制思考模式与非思考模式之间的切换。设为 enabled 时使用思考模式;设为 disabled 时使用非思考模式。 | - |
| spring.ai.deepseek.chat.reasoning-effort | 控制 DeepSeek 模型的推理力度级别。对普通请求,high 为默认;对复杂的 Agent 式请求(如 Claude Code、OpenCode),会自动使用 max。 | - |
| spring.ai.deepseek.chat.tool-callbacks | 注册到 ChatModel 的工具回调。 | - |
NOTE
你可以为 ChatModel 实现覆盖通用的 spring.ai.deepseek.base-url 和 spring.ai.deepseek.api-key。
若设置了 spring.ai.deepseek.chat.base-url 和 spring.ai.deepseek.chat.api-key 属性,它们优先于通用属性。 当你想为不同模型、不同模型端点使用不同的 DeepSeek 账户时,这很有用。
TIP
所有以 spring.ai.deepseek.chat 为前缀的属性,都可通过在 Prompt 调用中添加请求专用的 chat-options 在运行时被覆盖。
运行时选项
DeepSeekChatOptions.java 提供模型配置,例如要使用的模型、温度、频率惩罚等。
在启动时,可通过 DeepSeekChatModel(api, options) 构造器或 spring.ai.deepseek.chat.* 属性配置默认选项。
在运行时,你可以通过向 Prompt 调用添加新的、请求特定的选项来覆盖默认选项。 例如,要为某个特定请求覆盖默认的模型和温度:
java
ChatResponse response = chatModel.call(
new Prompt(
"Generate the names of 5 famous pirates. Please provide the JSON response without any code block markers such as ```json```.",
DeepSeekChatOptions.builder()
.withModel(DeepSeekApi.ChatModel.DEEPSEEK_V4_PRO.getValue())
.withTemperature(0.8f)
.build()
));TIP
除模型特定的 DeepSeekChatOptions 外,你还可以使用一个可移植的 ChatOptions 实例,通过 ChatOptions#builder() 创建。
示例控制器(自动配置)
创建 一个新的 Spring Boot 项目,并把 spring-ai-starter-model-deepseek 添加到你的 pom(或 gradle)依赖。
在 src/main/resources 目录下添加一个 application.properties 文件,以启用并配置 DeepSeek 聊天模型:
application.properties
spring.ai.deepseek.api-key=YOUR_API_KEY
spring.ai.deepseek.chat.model=deepseek-v4-pro
spring.ai.deepseek.chat.temperature=0.8TIP
用你的 DeepSeek 凭据替换 api-key。
这会创建一个可注入到你类中的 DeepSeekChatModel 实现。 下面是一个简单 @Controller 类的示例,它使用聊天模型进行文本生成。
java
@RestController
public class ChatController {
private final DeepSeekChatModel chatModel;
@Autowired
public ChatController(DeepSeekChatModel chatModel) {
this.chatModel = chatModel;
}
@GetMapping("/ai/generate")
public Map generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
return Map.of("generation", chatModel.call(message));
}
@GetMapping("/ai/generateStream")
public Flux<ChatResponse> generateStream(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
var prompt = new Prompt(new UserMessage(message));
return chatModel.stream(prompt);
}
}工具调用
DeepSeekChatModel 支持工具调用。模型可以请求执行工具,但它自己并不运行工具——由 Spring AI 处理执行。
对于大多数应用,请搭配自动注册的 ToolCallingAdvisor 使用 ChatClient —— 参见工具调用。若需要由你自己驱动该循环的底层控制,参见 ChatModel 工具调用。
聊天前缀补全
聊天前缀补全遵循 Chat Completion API,用户提供一个助手的 prefix 消息,让模型补全该消息的其余部分。
使用前缀补全时,用户必须确保 messages 列表中的最后一条消息是一个 DeepSeekAssistantMessage。
下面是关于聊天前缀补全的完整 Java 代码示例。在这个示例中,我们把助手的 prefix 消息设为 "python\n" 以强制模型输出 Python 代码,并把 stop 参数设为 [''] 以防止模型给出额外解释。
java
@RestController
public class CodeGenerateController {
private final DeepSeekChatModel chatModel;
@Autowired
public ChatController(DeepSeekChatModel chatModel) {
this.chatModel = chatModel;
}
@GetMapping("/ai/generatePythonCode")
public String generate(@RequestParam(value = "message", defaultValue = "Please write quick sort code") String message) {
UserMessage userMessage = new UserMessage(message);
Message assistantMessage = DeepSeekAssistantMessage.builder().content("```python\\n").prefix(true).build();
Prompt prompt = new Prompt(List.of(userMessage, assistantMessage), ChatOptions.builder().stopSequences(List.of("```")).build());
ChatResponse response = chatModel.call(prompt);
return response.getResult().getOutput().getText();
}
}推理支持
你可以用 DeepSeekAssistantMessage 获取支持该特性的模型生成的 CoT 内容。
java
public void deepSeekReasoningExample() {
DeepSeekChatOptions promptOptions = DeepSeekChatOptions.builder()
.build();
Prompt prompt = new Prompt("9.11 and 9.8, which is greater?", promptOptions);
ChatResponse response = chatModel.call(prompt);
// Get the CoT content generated by the model
DeepSeekAssistantMessage deepSeekAssistantMessage = (DeepSeekAssistantMessage) response.getResult().getOutput();
String reasoningContent = deepSeekAssistantMessage.getReasoningContent();
String text = deepSeekAssistantMessage.getText();
}思考模式
DeepSeek 模型支持思考模式与非思考模式之间的切换。 思考模式可通过 Thinking 选项控制,它接受 Thinking.ENABLED(思考模式)或 Thinking.DISABLED(非思考模式)。 禁用思考时,模型不产出任何推理内容。
java
public void deepSeekThinkingExample() {
DeepSeekChatOptions promptOptions = DeepSeekChatOptions.builder()
.thinking(Thinking.DISABLED)
.build();
Prompt prompt = new Prompt("9.11 and 9.8, which is greater?", promptOptions);
ChatResponse response = chatModel.call(prompt);
DeepSeekAssistantMessage deepSeekAssistantMessage = (DeepSeekAssistantMessage) response.getResult().getOutput();
// No reasoning content is produced when thinking is disabled
String reasoningContent = deepSeekAssistantMessage.getReasoningContent();
String text = deepSeekAssistantMessage.getText();
}思考模式也可用 enableThinking() 和 disableThinking() 构建器便捷方法来切换,或通过 spring.ai.deepseek.chat.thinking.type 属性全局配置。
推理力度
DeepSeek 模型让你通过 ReasoningEffort 选项控制推理力度级别。 ReasoningEffort.HIGH 是普通请求的默认,而 ReasoningEffort.MAX 会自动用于复杂的 Agent 式请求(如 Claude Code、OpenCode)。
java
public void deepSeekReasoningEffortExample() {
DeepSeekChatOptions promptOptions = DeepSeekChatOptions.builder()
.reasoningEffort(ReasoningEffort.MAX)
.build();
Prompt prompt = new Prompt("9.11 and 9.8, which is greater?", promptOptions);
ChatResponse response = chatModel.call(prompt);
DeepSeekAssistantMessage deepSeekAssistantMessage = (DeepSeekAssistantMessage) response.getResult().getOutput();
String reasoningContent = deepSeekAssistantMessage.getReasoningContent();
String text = deepSeekAssistantMessage.getText();
}推理力度也可用 reasoningEffortHigh() 和 reasoningEffortMax() 构建器便捷方法设置,或通过 spring.ai.deepseek.chat.reasoning-effort 属性全局配置。
推理模型多轮对话
在对话的每一轮,模型会输出 CoT(reasoning_content)和最终答案(content)。在下一轮对话中,先前各轮的 CoT 不会被串接进上下文,如下方图示:
手动配置
DeepSeekChatModel 实现了 ChatModel 和 StreamingChatModel,并使用底层 api 连接到 DeepSeek 服务。
把 spring-ai-deepseek 依赖添加到你的项目的 Maven pom.xml 文件:
xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-deepseek</artifactId>
</dependency>或添加到你的 Gradle build.gradle 文件。
groovy
dependencies {
implementation 'org.springframework.ai:spring-ai-deepseek'
}TIP
参见 依赖管理 一节,把 Spring AI BOM 添加到你的构建文件。
接下来,创建一个 DeepSeekChatModel 并将其用于文本生成:
java
DeepSeekApi deepSeekApi = DeepSeekApi.builder()
.apiKey(System.getenv("DEEPSEEK_API_KEY"))
.build();
DeepSeekChatOptions options = DeepSeekChatOptions.builder()
.model(DeepSeekApi.ChatModel.DEEPSEEK_V4_PRO.getValue())
.temperature(0.4)
.maxTokens(200)
.build();
DeepSeekChatModel chatModel = DeepSeekChatModel.builder()
.deepSeekApi(deepSeekApi)
.options(options)
.build();
ChatResponse response = chatModel.call(
new Prompt("Generate the names of 5 famous pirates."));
// Or with streaming responses
Flux<ChatResponse> streamResponse = chatModel.stream(
new Prompt("Generate the names of 5 famous pirates."));DeepSeekChatOptions 为聊天请求提供配置信息。 DeepSeekChatOptions.Builder 是一个流式选项构建器。
底层 DeepSeekApi 客户端
DeepSeekApi 是 DeepSeek API 的一个轻量级 Java 客户端。
下面是一个演示如何以编程方式使用该 API 的简单片段:
java
DeepSeekApi deepSeekApi =
new DeepSeekApi(System.getenv("DEEPSEEK_API_KEY"));
ChatCompletionMessage chatCompletionMessage =
new ChatCompletionMessage("Hello world", Role.USER);
// Sync request
ResponseEntity<ChatCompletion> response = deepSeekApi.chatCompletionEntity(
new ChatCompletionRequest(List.of(chatCompletionMessage), DeepSeekApi.ChatModel.DEEPSEEK_V4_FLASH.getValue(), 0.7, false));
// Streaming request
Flux<ChatCompletionChunk> streamResponse = deepSeekApi.chatCompletionStream(
new ChatCompletionRequest(List.of(chatCompletionMessage), DeepSeekApi.ChatModel.DEEPSEEK_V4_FLASH.getValue(), 0.7, true));关于更多信息,遵循 DeepSeekApi.java 的 JavaDoc。
DeepSeekApi 示例
- DeepSeekApiIT.java 测试提供了一些关于如何使用该轻量库的通用示例。