DeepSeek

本站(springdoc.cn)中的内容来源于 spring.io ,原始版权归属于 spring.io。由 springdoc.cn 进行翻译,整理。可供个人学习、研究,未经许可,不得进行任何转载、商用或与之相关的行为。 商标声明:Spring 是 Pivotal Software, Inc. 在美国以及其他国家的商标。

Spring AI 支持 DeepSeek 的多种 AI 语言模型。你可以通过 DeepSeek 语言模型构建多语言对话助手。

前提条件

你需要创建 DeepSeek API Key 才能访问 DeepSeek 语言模型。

DeepSeek 注册页面 创建账户,并在 API Key 页面 生成访问令牌(Token)。

Spring AI 项目定义了名为 spring.ai.deepseek.api-key 的配置属性,你需将其设置为从 API Key 页面获取的密钥值。

你可以在 application.properties 文件中设置该配置属性:

spring.ai.deepseek.api-key=<your-deepseek-api-key>

为增强处理敏感信息(如 API Key)时的安全性,可以使用 Spring 表达式语言(SpEL)引用自定义环境变量:

# In application.yml
spring:
  ai:
    deepseek:
      api-key: ${DEEPSEEK_API_KEY}
# In your environment or .env file
export DEEPSEEK_API_KEY=<your-deepseek-api-key>

你还可以在应用程序代码中以编程方式设置此配置:

// Retrieve API key from a secure source or environment variable
String apiKey = System.getenv("DEEPSEEK_API_KEY");

添加仓库和 BOM

Spring AI 组件已发布在 Spring Milestone 和 Snapshot 仓库。请参阅 Artifact 仓库 章节将这些仓库添加到你的构建系统。

为简化依赖管理,Spring AI 提供 BOM 以确保整个项目使用统一版本的 Spring AI。请参阅 依赖管理 章节将 Spring AI BOM 添加到你的构建系统。

自动配置

Spring AI 为 DeepSeek 聊天模型提供 Spring Boot 自动配置。要启用该功能,请将以下依赖添加到项目的 Maven pom.xml 文件中:

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-deepseek</artifactId>
</dependency>

或添加到 Gradle build.gradle 文件中:

dependencies {
    implementation 'org.springframework.ai:spring-ai-starter-model-deepseek'
}
请参阅 依赖管理 章节将 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

api.deepseek.com

spring.ai.deepseek.api-key

API Key

-

连接属性

前缀 spring.ai.deepseek.chat 用于配置 DeepSeek 聊天模型实现的属性参数。

属性 说明 默认值

spring.ai.deepseek.chat.enabled

启用 DeepSeek 聊天模型

true

spring.ai.deepseek.chat.base-url

可选地覆盖 spring.ai.deepseek.base-url 以提供聊天专用的 URL

api.deepseek.com/

spring.ai.deepseek.chat.api-key

可选地覆盖 spring.ai.deepseek.api-key 以提供聊天专用的 API Key

-

spring.ai.deepseek.chat.completions-path

聊天补全端点的路径。

/chat/completions

spring.ai.deepseek.chat.beta-prefix-path

测试功能端点的前缀路径

/beta/chat/completions

spring.ai.deepseek.chat.options.model

要使用的模型的ID。你可以使用 deepseek-coder 或 deepseek-chat。

deepseek-chat

spring.ai.deepseek.chat.options.frequencyPenalty

介于 -2.0 到2 .0 之间的数值。正值会根据 Token 在已生成文本中的现有频率进行惩罚,从而降低模型逐字重复相同内容的可能性。

0.0f

spring.ai.deepseek.chat.options.maxTokens

聊天补全中生成的最大 Token 数量。输入 Token 和生成 Token 的总长度受模型上下文长度限制。

-

spring.ai.deepseek.chat.options.presencePenalty

介于 -2.0 到 2.0 之间的数值。正值会根据 Token 是否已在已生成文本中出现进行惩罚,从而提高模型讨论新话题的可能性。

0.0f

spring.ai.deepseek.chat.options.stop

最多可设置 4 个停止序列,当 API 生成这些序列时将终止输出。

-

spring.ai.deepseek.chat.options.temperature

采样温度值,范围0到2。较高值(如0.8)使输出更随机,较低值(如0.2)使输出更集中和确定。通常建议仅调整此参数或 top_p 参数,而非同时修改两者。

1.0F

spring.ai.deepseek.chat.options.topP

温度采样的替代方案——核采样(nucleus sampling),模型仅考虑概率质量累计达到 top_p 阈值的token。例如0.1表示仅考虑概率质量排名前 10% 的 Token。通常建议仅调整此参数或 temperature 参数,而非同时修改两者。

1.0F

spring.ai.deepseek.chat.options.logprobs

是否返回输出 Token 的对数概率。若为 true,则返回消息内容中每个输出 Token 的对数概率。

-

spring.ai.deepseek.chat.options.topLogprobs

0 到 20 之间的整数,指定每个 Token 位置返回的最可能 Token 数量(每个附带关联的对数概率)。若使用此参数,必须将 logprobs 设为 true。

-

你可以为 ChatModel 实现覆盖通用的 spring.ai.deepseek.base-urlspring.ai.deepseek.api-key 配置。若设置了 spring.ai.deepseek.chat.base-urlspring.ai.deepseek.chat.api-key 属性,它们将优先于通用属性生效。此特性适用于需要为不同模型使用不同 DeepSeek 账户及终端点的场景。
所有以 spring.ai.deepseek.chat.options 为前缀的属性,都可通过在 Prompt 调用中添加请求特定的 运行时选项 进行覆盖。

运行时选项

DeepSeekChatOptions.java 提供模型配置参数,包括使用的模型名称、温度值(temperature)、频率惩罚系数(frequency penalty)等。

在启动时,默认选项可通过 DeepSeekChatModel(api, options) 构造函数或 spring.ai.deepseek.chat.options.* 属性进行配置。

在运行时,你可以通过向 Prompt 调用添加新的、特定于请求的选项来覆盖默认配置。例如,针对特定请求覆盖默认模型和温度参数:

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_CHAT.getValue())
            .withTemperature(0.8f)
        .build()
    ));
除了模型专用的 DeepSeekChatOptions 外,你还可以使用通过 ChatOptionsBuilder#builder() 创建的通用 ChatOptions 实例。

示例 Controller(自动配置)

创建 一个新的 Spring Boot 项目,并在 pom(或gradle)依赖项中添加 spring-ai-starter-model-deepseek

src/main/resources 目录下添加 application.properties 文件以启用并配置 DeepSeek 聊天模型:

spring.ai.deepseek.api-key=YOUR_API_KEY
spring.ai.deepseek.chat.options.model=deepseek-chat
spring.ai.deepseek.chat.options.temperature=0.8
api-key 替换为你的 DeepSeek 凭证密钥。

这将创建一个可注入到类中的 DeepSeekChatModel 实现。以下是一个简单的 @Controller 类示例,使用该聊天模型进行文本生成:

@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);
    }
}

聊天前缀补全

聊天前缀补全遵循 Chat Completion API 规范,用户提供助手(assistant)的消息前缀,由模型完成后续消息内容。

使用前缀补全时,用户必须确保消息列表中的最后一条是 DeepSeekAssistantMessage 类型。

以下是一个完整的聊天前缀补全 Java 代码示例。本示例将助手的消息前缀设置为 "```python\n" 以强制模型输出 Python 代码,并通过设置stop参数为 [‘`’] 阻止模型生成额外解释:

@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.prefixAssistantMessage("```python\\n");
		Prompt prompt = new Prompt(List.of(userMessage, assistantMessage), ChatOptions.builder().stopSequences(List.of("```")).build());
		ChatResponse response = chatModel.call(prompt);
		return response.getResult().getOutput().getText();
    }
}

推理模型(deepseek-reasoner)

deepseek-reasoner 是 DeepSeek 开发的推理模型。在生成最终答案前,该模型会先生成思维链(Chain of Thought, CoT)以提高响应准确性。我们的 API 支持用户访问 deepseek-reasoner 生成的 CoT 内容,便于查看、展示和提炼。

你可以通过 DeepSeekAssistantMessage 获取 deepseek-reasoner 生成的思维链(CoT)内容。

public void deepSeekReasonerExample() {
    DeepSeekChatOptions promptOptions = DeepSeekChatOptions.builder()
            .model(DeepSeekApi.ChatModel.DEEPSEEK_REASONER.getValue())
            .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 deepseek-reasoner, only available when using deepseek-reasoner model
    DeepSeekAssistantMessage deepSeekAssistantMessage = (DeepSeekAssistantMessage) response.getResult().getOutput();
    String reasoningContent = deepSeekAssistantMessage.getReasoningContent();
    String text = deepSeekAssistantMessage.getText();
}

推理模型多轮对话

在每轮对话中,模型会输出思维链(reasoning_content)和最终答案(content)。在下一轮对话时,前几轮的思维链不会拼接到上下文中,如下所示:

多模态模型测试图片

请注意:若输入消息序列中包含 reasoning_content 字段,API 将返回 400 错误。因此,在发起 API 请求前应移除 API 响应中的 reasoning_content 字段,如 API 示例所示。

public String deepSeekReasonerMultiRoundExample() {
    List<Message> messages = new ArrayList<>();
    messages.add(new UserMessage("9.11 and 9.8, which is greater?"));
    DeepSeekChatOptions promptOptions = DeepSeekChatOptions.builder()
            .model(DeepSeekApi.ChatModel.DEEPSEEK_REASONER.getValue())
            .build();

    Prompt prompt = new Prompt(messages, promptOptions);
    ChatResponse response = chatModel.call(prompt);

    DeepSeekAssistantMessage deepSeekAssistantMessage = (DeepSeekAssistantMessage) response.getResult().getOutput();
    String reasoningContent = deepSeekAssistantMessage.getReasoningContent();
    String text = deepSeekAssistantMessage.getText();

    messages.add(new AssistantMessage(Objects.requireNonNull(text)));
    messages.add(new UserMessage("How many Rs are there in the word 'strawberry'?"));
    Prompt prompt2 = new Prompt(messages, promptOptions);
    ChatResponse response2 = chatModel.call(prompt2);

    DeepSeekAssistantMessage deepSeekAssistantMessage2 = (DeepSeekAssistantMessage) response2.getResult().getOutput();
    String reasoningContent2 = deepSeekAssistantMessage2.getReasoningContent();
    return deepSeekAssistantMessage2.getText();
}

手动配置

DeepSeekChatModel 实现了 ChatModelStreamingChatModel 接口,并通过 底层 DeepSeekApi 客户端 连接 DeepSeek 服务。

将以下依赖添加到项目的 Maven pom.xml 文件中:

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-deepseek</artifactId>
</dependency>

或添加到 Gradle build.gradle 文件中:

dependencies {
    implementation 'org.springframework.ai:spring-ai-deepseek'
}
请参阅 依赖管理 章节将 Spring AI BOM 添加到你的构建文件。

接下来,创建 DeepSeekChatModel 并用于文本生成:

var deepSeekApi = new DeepSeekApi(System.getenv("DEEPSEEK_API_KEY"));

var chatModel = new DeepSeekChatModel(deepSeekApi, DeepSeekChatOptions.builder()
                .withModel(DeepSeekApi.ChatModel.DEEPSEEK_CHAT.getValue())
                .withTemperature(0.4f)
                .withMaxTokens(200)
                .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 支持 Fluent 式选项构建。

底层 DeepSeekApi 客户端

DeepSeekApi 是用于 DeepSeek API 的轻量级 Java 客户端。

以下是编程方式调用 API 的简单示例:

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_CHAT.getValue(), 0.7f, false));

// Streaming request
Flux<ChatCompletionChunk> streamResponse = deepSeekApi.chatCompletionStream(
        new ChatCompletionRequest(List.of(chatCompletionMessage), DeepSeekApi.ChatModel.DEEPSEEK_CHAT.getValue(), 0.7f, true));

更多详细信息请参阅 DeepSeekApi.java 的 JavaDoc 文档。

DeepSeekApi 示例

DeepSeekApiIT.java 测试类提供了一些通用示例,展示了如何使用该轻量级库与 DeepSeek 提供的 API 进行交互。