首页 / Spring AI 入门教程 / 接入 DeepSeek

Spring AI 入门教程

接入 DeepSeek

本教程共 45 篇 · 第 13 篇 · 更新于 2026-08-16 · 约 6 分钟阅读

Spring AIDeepSeek国产大模型deepseek-chatdeepseek-reasoner流式响应思维链OpenAI 兼容

本节目标:用官方 starter 接入 DeepSeek,理解它与 OpenAI 的兼容关系,学会流式调用、前缀补全和推理模型的思维链读取。

13.1 为什么选 DeepSeek

DeepSeek 是国内热度最高的大模型厂商之一。它的卖点很直接:能力接近一线模型,价格便宜很多,对中文支持好。

官方文档给 DeepSeek 的定位是”OpenAI-proxy”类型:API 规范完全兼容 OpenAI。这意味着你既可以用官方 starter,也可以用 OpenAI 的客户端连它的地址。两条路都通,后面分别讲。

先到 platform.deepseek.com 注册账号,充值后创建 API Key。DeepSeek 平台需要先实名认证才能充值。

13.2 方式一:官方 starter

Spring AI 提供专门的 DeepSeek starter,依赖坐标:

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

配置前缀是 spring.ai.deepseek

spring.ai.deepseek.api-key=${DEEPSEEK_API_KEY}
spring.ai.deepseek.base-url=https://api.deepseek.com

spring.ai.deepseek.chat.model=deepseek-v4-flash
spring.ai.deepseek.chat.temperature=0.8

可用的模型名有四个:

模型名定位
deepseek-v4-flash默认模型,快,便宜
deepseek-v4-pro更强,适合复杂任务
deepseek-chat通用对话模型
deepseek-reasoner推理模型,输出思维链

模型名可以在运行时通过 DeepSeekChatOptions 覆盖:

ChatResponse response = chatModel.call(new Prompt(
        "列出 5 种常见前端框架",
        DeepSeekChatOptions.builder()
                .model(DeepSeekApi.ChatModel.DEEPSEEK_V4_PRO.getValue())
                .temperature(0.8)
                .build()));

13.3 方式二:OpenAI 兼容接入

网上大量 DeepSeek 教程用的是这条路:引入 OpenAI starter,把 base-url 指向 DeepSeek。原因就是前面说的,DeepSeek 完全兼容 OpenAI 规范。

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
spring.ai.openai.api-key=${DEEPSEEK_API_KEY}
spring.ai.openai.base-url=https://api.deepseek.com
spring.ai.openai.chat.model=deepseek-chat

代码里注入的是 OpenAiChatModel 或 ChatClient,调用方式和第 11 章完全一样。

两条路的区别在抽象层级:官方 starter 的模型叫 DeepSeekChatModel,响应里能直接拿到 DeepSeek 特有的思维链字段;OpenAI 方式没有这个类型,但可以通过元数据读到。日常对话场景,两条路体验没差别。

Tip

同一份代码想同时兼容多个 OpenAI 规范厂商(DeepSeek、通义千问、Moonshot),用 OpenAI 方式最省事,只改 base-url 和模型名。

13.4 流式响应

DeepSeek 流式输出用 ChatClient 一行搞定,这也是网上博客最常见的需求。1.x 博客里写的是 chatClient.prompt(input).stream().content(),这套 API 在 2.0 依然是 ChatClient 的一等公民,写法不变:

@GetMapping(value = "/ai/stream", produces = "text/html;charset=UTF-8")
public Flux<String> stream(@RequestParam(defaultValue = "讲个笑话") String message) {
    return chatClient.prompt()
            .user(message)
            .stream()
            .content();
}

浏览器直接访问这个接口,能看到逐字输出的打字机效果。接入层代码只有这么点,剩下的解析和推流都由框架完成。

13.5 前缀补全

DeepSeek 有个特色功能叫前缀补全(prefix completion):你给模型一个”开头的半句话”,它接着往下写。典型场景是强制输出格式,比如让模型只写 Python 代码。

用法是构造一个带 prefix 标记的 DeepSeekAssistantMessage,放在消息列表最后:

@RestController
public class CodeController {

    private final DeepSeekChatModel chatModel;

    public CodeController(DeepSeekChatModel chatModel) {
        this.chatModel = chatModel;
    }

    @GetMapping("/ai/python")
    public String python(@RequestParam(defaultValue = "写一个快速排序") 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());

        return chatModel.call(prompt).getResult().getOutput().getText();
    }
}

这里给模型喂了”python\n"这个前缀,模型会从代码块开始写。stop 参数设成 ,模型写完代码碰到结束标记就停,不会追加多余解释。

Note

前缀补全要求消息列表最后一条必须是 DeepSeekAssistantMessage,并且 prefix 置为 true。普通对话不要加这个标记。

13.6 推理模型与思维链

deepseek-reasoner 是推理模型,回答前会先输出一段思维链(CoT)。这段内容通过 DeepSeekAssistantMessage 读取:

DeepSeekChatOptions options = DeepSeekChatOptions.builder().build();
Prompt prompt = new Prompt("9.11 和 9.8 哪个大?", options);

ChatResponse response = chatModel.call(prompt);

DeepSeekAssistantMessage message = (DeepSeekAssistantMessage) response.getResult().getOutput();
String reasoningContent = message.getReasoningContent();  // 思维链
String text = message.getText();                          // 最终答案

思维链和最终答案是分开的两个字段。

走 OpenAI 兼容方式也能拿到思维链。DeepSeek 的兼容端点会返回 reasoning_content 字段,Spring AI 自动映射到响应元数据的 reasoningContent

spring.ai.openai.api-key=${DEEPSEEK_API_KEY}
spring.ai.openai.base-url=https://api.deepseek.com
spring.ai.openai.chat.model=deepseek-reasoner
ChatResponse response = chatModel.call(new Prompt("9.11 和 9.8 哪个大?"));

AssistantMessage message = response.getResult().getOutput();
String reasoning = message.getMetadata().get("reasoningContent");

流式调用时思维链会跨多个 chunk 累积,每个 chunk 都从元数据里取,拼起来就是完整推理过程。

Note

官方 OpenAI 模型不暴露思维链,reasoningContent 元数据只对 DeepSeek 这类兼容服务有效。读不到时检查模型名是不是 deepseek-reasoner。

推理模型的多轮对话有个特点:历史轮次的思维链不会拼进下一轮上下文。每次请求只带之前的最终答案,模型重新推理。这是 DeepSeek 的既定设计,能省 token,也避免模型被自己之前的推理过程带偏。需要长对话时,把多轮消息列表完整传给 Prompt 即可,框架会处理好角色映射。

13.7 工具调用

DeepSeek 支持工具调用,走统一的 ToolCallback 机制。ChatClient 自动注册 ToolCallingAdvisor,闭环处理工具调用循环。

工具调用的完整写法与第 12 章相同:定义 FunctionToolCallback,通过 .tools() 注册进请求。唯一要改的是把示例里的 chatModel 换成 DeepSeekChatModel,其余代码一字不动。完整示例回到 12.8 看。

13.8 重试与限流

DeepSeek 官方 starter 的重试配置和 OpenAI 共用一套前缀 spring.ai.retry。默认最多重试 10 次,指数退避从 2 秒开始,最大间隔 3 分钟。

spring.ai.retry.max-attempts=5
spring.ai.retry.on-client-errors=false

4xx 客户端错误默认不重试,这类错误重试也没用。限流(429)和超时属于瞬时错误,重试策略对它们有效。

DeepSeek 是预付费模式,账户余额不足会直接报错。开发调试阶段建议小额充值,控制每次调用的 max-tokens,避免一次测试烧掉太多额度。

13.9 网上博客经验的映射

DeepSeek 的博客教程大多基于 1.x,看的时候对照这张表转换:

1.x 写法2.0 写法
spring-ai-openai-spring-boot-starterspring-ai-starter-model-openai
spring.ai.openai.chat.options.modelspring.ai.openai.chat.model
new Prompt(message) 手拼消息ChatClient.prompt().user()
chatModel.stream(prompt) 手动 mapchatClient.prompt().stream().content()

核心经验不受版本影响:DeepSeek 兼容 OpenAI 规范,OpenAI 的客户端可以连 DeepSeek;流式响应返回 Flux,前端按流消费;系统提示词用 SystemMessage 设定人设。这些在 2.0 里依然成立,只是依赖名和属性路径变了。

13.10 常见问题排查

DeepSeek 的报错和 OpenAI 兼容服务基本同源,几个高频问题:

401 认证失败,检查 api-key。DeepSeek 是预付费模式,余额不足时请求会被直接拒绝,平台充值后立即恢复。

429 限流,触发并发限制。spring.ai.retry 对这类瞬时错误有效,配置见 13.8;持续被限就查官网的额度说明。

思维链读不到,先确认模型名是 deepseek-reasoner。普通对话模型不输出思维链,元数据里自然没有 reasoningContent,规则见 13.6。

前缀补全不生效,检查消息列表最后一条:必须是 DeepSeekAssistantMessage 且 prefix 置为 true,普通消息结尾没有效果。

模型名报不存在,对照官网模型列表核对。教程里写的名字可能过时,以 platform.deepseek.com 的文档为准。

13.11 小结

DeepSeek 接入有官方和兼容两条路。官方 starter 类型更完整,能直接读思维链;OpenAI 方式一套代码兼容多家厂商。流式、前缀补全、工具调用都是它的可用能力。下一章接入 Ollama,把模型跑在本地。