SpringBoot调用DeepSeek API的完整操作指南

 更新时间:2025年02月10日 08:17:48   作者:老大白菜  
这篇文章主要为大家详细介绍了SpringBoot调用DeepSeek API的完整操作指南,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

1. 项目依赖

在 pom.xml 中添加以下依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>
</dependencies>

2. 项目结构

deepseek-project/
├── src/main/java/com/example/deepseek/
│   ├── DeepSeekApplication.java
│   ├── config/
│   │   └── DeepSeekConfig.java
│   ├── model/
│   │   ├── ChatRequest.java
│   │   ├── ChatResponse.java
│   │   └── Message.java
│   └── service/
│       └── DeepSeekService.java
└── conversation.txt

3. 完整代码实现

3.1 配置类 DeepSeekConfig.java

package com.example.deepseek.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

@Configuration
@Getter
public class DeepSeekConfig {
    @Value("${deepseek.api.url}")
    private String apiUrl;

    @Value("${deepseek.api.key}")
    private String apiKey;
}

3.2 请求/响应模型

Message.java:

package com.example.deepseek.model;

import lombok.Data;

@Data
public class Message {
    private String role;
    private String content;
}

ChatRequest.java:

package com.example.deepseek.model;

import lombok.Data;
import java.util.List;

@Data
public class ChatRequest {
    private String model = "deepseek-ai/DeepSeek-V3";
    private List<Message> messages;
    private boolean stream = true;
    private int max_tokens = 2048;
    private double temperature = 0.7;
    private double top_p = 0.7;
    private int top_k = 50;
    private double frequency_penalty = 0.5;
    private int n = 1;
    private ResponseFormat response_format = new ResponseFormat("text");

    @Data
    public static class ResponseFormat {
        private String type;
        
        public ResponseFormat(String type) {
            this.type = type;
        }
    }
}

ChatResponse.java:

package com.example.deepseek.model;

import lombok.Data;
import java.util.List;

@Data
public class ChatResponse {
    private List<Choice> choices;

    @Data
    public static class Choice {
        private Delta delta;
    }

    @Data
    public static class Delta {
        private String content;
    }
}

3.3 服务类 DeepSeekService.java

package com.example.deepseek.service;

import com.example.deepseek.config.DeepSeekConfig;
import com.example.deepseek.model.ChatRequest;
import com.example.deepseek.model.ChatResponse;
import com.example.deepseek.model.Message;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.Scanner;

@Service
@RequiredArgsConstructor
public class DeepSeekService {
    private final DeepSeekConfig config;
    private final WebClient.Builder webClientBuilder;
    private final ObjectMapper objectMapper = new ObjectMapper();

    public void startInteractiveChat() {
        try (Scanner scanner = new Scanner(System.in);
             PrintWriter fileWriter = new PrintWriter(new FileWriter("conversation.txt", true))) {

            while (true) {
                System.out.print("\n请输入您的问题 (输入 q 退出): ");
                String question = scanner.nextLine().trim();

                if ("q".equalsIgnoreCase(question)) {
                    System.out.println("程序已退出");
                    break;
                }

                // 保存问题
                saveToFile(fileWriter, question, true);

                // 发起对话请求
                Flux<String> responseFlux = sendChatRequest(question);

                StringBuilder fullResponse = new StringBuilder();
                responseFlux
                    .doOnNext(chunk -> {
                        System.out.print(chunk);
                        fullResponse.append(chunk);
                    })
                    .doOnComplete(() -> {
                        // 保存完整回复
                        saveToFile(fileWriter, fullResponse.toString(), false);
                        System.out.println("\n----------------------------------------");
                        fileWriter.println("\n----------------------------------------");
                        fileWriter.flush();
                    })
                    .blockLast();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private Flux<String> sendChatRequest(String question) {
        ChatRequest request = new ChatRequest();
        Message userMessage = new Message();
        userMessage.setRole("user");
        userMessage.setContent(question);
        request.setMessages(Collections.singletonList(userMessage));

        return webClientBuilder.build()
            .post()
            .uri(config.getApiUrl())
            .header("Authorization", "Bearer " + config.getApiKey())
            .header("Content-Type", "application/json")
            .bodyValue(request)
            .retrieve()
            .bodyToFlux(String.class)
            .filter(line -> line.startsWith("data: ") && !line.equals("data: [DONE]"))
            .map(line -> {
                try {
                    String jsonStr = line.substring(6);
                    ChatResponse response = objectMapper.readValue(jsonStr, ChatResponse.class);
                    return response.getChoices().get(0).getDelta().getContent();
                } catch (Exception e) {
                    return "";
                }
            })
            .filter(content -> !content.isEmpty());
    }

    private void saveToFile(PrintWriter fileWriter, String content, boolean isQuestion) {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        if (isQuestion) {
            fileWriter.printf("\n[%s] Question:\n%s\n\n[%s] Answer:\n", timestamp, content, timestamp);
        } else {
            fileWriter.print(content);
        }
        fileWriter.flush();
    }
}

3.4 主应用类 DeepSeekApplication.java

package com.example.deepseek;

import com.example.deepseek.service.DeepSeekService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class DeepSeekApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(DeepSeekApplication.class, args);
        DeepSeekService deepSeekService = context.getBean(DeepSeekService.class);
        deepSeekService.startInteractiveChat();
    }
}

3.5 配置文件 application.properties

deepseek.api.url=https://api.siliconflow.cn/v1/chat/completions
deepseek.api.key=YOUR_API_KEY

4. 代码详解

4.1 关键特性

使用 Spring WebFlux 的响应式编程模型

流式处理 API 响应

文件记录对话

错误处理和异常管理

4.2 主要组件

DeepSeekConfig: 管理 API 配置

DeepSeekService: 处理对话逻辑和 API 交互

模型类: 定义请求和响应结构

5. 使用方法

替换 application.properties 中的 YOUR_API_KEY

运行 DeepSeekApplication

在控制台输入问题

输入 ‘q’ 退出程序

查看 conversation.txt 获取对话记录

6. 性能和可扩展性

使用响应式编程提高并发性能

灵活的配置管理

易于扩展和定制

7. 注意事项

确保正确配置 API Key

处理网络异常

注意内存使用

总结

Spring Boot 实现提供了一个健壮、可扩展的 DeepSeek API 调用方案,利用响应式编程提供高效的流式对话体验。

到此这篇关于SpringBoot调用DeepSeek API的完整操作指南的文章就介绍到这了,更多相关SpringBoot调用DeepSeek API内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java引用队列和虚引用实例分析

    Java引用队列和虚引用实例分析

    这篇文章主要介绍了Java引用队列和虚引用,结合实例形式分析了java引用队列和虚引用相关概念、原理与使用方法,需要的朋友可以参考下
    2019-08-08
  • Java中Stream的flatMap与map使用场景及区别详解

    Java中Stream的flatMap与map使用场景及区别详解

    这篇文章主要介绍了Java中Stream的flatMap与map使用场景及区别详解,Stream 流式操作,一般用于操作集合即 List 一类的数据结构,简单来说 Stream 的 map 使得其中的元素转为另一种元素的映射(map)方法,需要的朋友可以参考下
    2024-01-01
  • Java封装数组之添加元素操作实例分析

    Java封装数组之添加元素操作实例分析

    这篇文章主要介绍了Java封装数组之添加元素操作,结合实例形式分析了Java封装数组实现元素追加、插入等相关操作技巧,需要的朋友可以参考下
    2020-03-03
  • Java必备知识之位运算及常见进制解读

    Java必备知识之位运算及常见进制解读

    从现代计算机中所有的数据二进制的形式存储在设备中。即 0、1 两种状态,计算机对二进制数据进行的运算(+、-、*、/)都是叫位运算,即将符号位共同参与运算的运算
    2021-10-10
  • Java 静态机制之静态变量、方法、代码块与类加载深入理解

    Java 静态机制之静态变量、方法、代码块与类加载深入理解

    本文全面解析了Java中static关键字的特性与应用,静态机制使成员与类本身关联,包括静态变量(存储在方法区,所有对象共享)、静态方法(可通过类名直接调用,不能访问实例成员)和静态代码块(类加载时执行),感兴趣的朋友跟随小编一起看看吧
    2025-11-11
  • Hibernate中Session增删改查操作代码详解

    Hibernate中Session增删改查操作代码详解

    这篇文章主要介绍了Hibernate中Session增删改查操作代码详解,具有一定借鉴价值,需要的朋友可以参考下。
    2017-12-12
  • Springboot使用JustAuth实现各种第三方登陆

    Springboot使用JustAuth实现各种第三方登陆

    本文主要介绍了Springboot使用JustAuth实现各种第三方登陆,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • Java实现的分页工具类与用法示例

    Java实现的分页工具类与用法示例

    这篇文章主要介绍了Java实现的分页工具类与用法,结合完整实例形式分析了java分页工具类的定义、使用方法及相关操作技巧,需要的朋友可以参考下
    2019-10-10
  • scala 操作数据库的方法

    scala 操作数据库的方法

    这篇文章主要介绍了scala 操作数据库的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-06-06
  • 解决FeignClient Get请求参数接收不到的问题

    解决FeignClient Get请求参数接收不到的问题

    在使用FeignClient进行GET请求时,如果参数接收不到,通常是因为Feign默认将参数绑定为@RequestBody,而GET请求无法包含请求体,解决方法是在Feign接口中为参数添加@RequestParam注解,或者在SpringMVC的Controller中使用@RequestBody接收参数
    2024-11-11

最新评论