SpringBoot+DeepSeek实现第一个AI聊天接口

 更新时间:2026年08月26日 08:45:44   作者:我有满天星辰  
还在为SpringBoot接入DeepSeek发愁,本文手把手教你用SpringAI轻松实现AI聊天接口,从项目创建到调用DeepSeek模型,每一步都讲透,让你快速上手SpringAI开发,为后续RAG和Agent打下基础,需要的朋友可以参考下

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聊天接口的资料请关注脚本之家其它相关文章!

相关文章

  • SpringBoot如何优雅的处理重复请求

    SpringBoot如何优雅的处理重复请求

    对于一些用户请求,在某些情况下是可能重复发送的,如果是查询类操作并无大碍,但其中有些是涉及写入操作的,一旦重复了,可能会导致很严重的后果,所以本文给大家介绍了SpringBoot优雅的处理重复请求的方法,需要的朋友可以参考下
    2023-12-12
  • SpringBoot 静态资源导入及首页设置问题

    SpringBoot 静态资源导入及首页设置问题

    本节了解一下 SpringBoot 中 Web 开发的静态资源导入和首页设置,对应 SpringBoot-03-Web 项目,本节主要是从源码的角度,研究了一下静态资源导入和首页设置的问题
    2021-09-09
  • Failed to execute goal org...的解决办法

    Failed to execute goal org...的解决办法

    这篇文章主要介绍了Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1的解决办法的相关资料,需要的朋友可以参考下
    2017-06-06
  • Spring boot 打jar包分离lib的正确配置方式

    Spring boot 打jar包分离lib的正确配置方式

    spring boot打jar包分离lib后,配置文件的方式,在网上可以搜到很多答案,但是都不够完善,今天小编给大家带来了Spring boot 打jar包分离lib的正确配置方式,感兴趣的朋友一起看看吧
    2018-02-02
  • SpringBoot中自动配置原理解析

    SpringBoot中自动配置原理解析

    SpringBoost是基于Spring框架开发出来的功能更强大的Java程序开发框架,本文将以广角视觉来剖析SpringBoot自动配置的原理,涉及部分Spring、SpringBoot源码,需要的可以参考下
    2023-11-11
  • Mybatis模糊查询之三种定义参数方法和聚合查询、主键回填实现方法

    Mybatis模糊查询之三种定义参数方法和聚合查询、主键回填实现方法

    这篇文章主要介绍了Mybatis模糊查询之三种定义参数方法和聚合查询、主键回填实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • 浅谈Java中的hashcode方法(推荐)

    浅谈Java中的hashcode方法(推荐)

    本篇文章主要介绍了Java中的hashcode方法,详细的介绍了hashCode方法的作用,具有一定的参考价值,有需要的可以了解一下。
    2016-12-12
  • MVC页面之间参数传递实现过程图解

    MVC页面之间参数传递实现过程图解

    这篇文章主要介绍了MVC页面之间参数传递实现过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • Java实现实时监控目录下文件变化的方法

    Java实现实时监控目录下文件变化的方法

    今天小编就为大家分享一篇关于Java实现实时监控目录下文件变化的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • Java 的访问修饰符public,protected,private(封装、继承)

    Java 的访问修饰符public,protected,private(封装、继承)

    这篇文章主要介绍了Java 的访问修饰符public,protected,private(封装、继承),文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09

最新评论