网站首页 > 技术文章 正文
SpringBoot集成DeepSeek的步骤如下:
- 关于deepseek部分的开发
import com.kclm.springboot3deepseek.deepseek.model.ChatRequest;
import com.kclm.springboot3deepseek.deepseek.model.ChatResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
/**
* 类名称:DeepSeekApiClient
* 类描述:负责与DeepSeek API的HTTP通信
*/
@Component
public class DeepSeekApiClient {
private final RestTemplate restTemplate;
private final String apiKey;
private final String apiUrl;
public DeepSeekApiClient(
RestTemplate restTemplate,
@Value("${deepseek.api.key}") String apiKey,
@Value("${deepseek.api.url}") String apiUrl) {
this.restTemplate = restTemplate;
this.apiKey = apiKey;
this.apiUrl = apiUrl;
}
/**
* 发送聊天请求到DeepSeek API
*
* @param chatRequest 聊天请求对象
* @return API的响应
*/
public ChatResponse sendChatRequest(ChatRequest chatRequest) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer " + apiKey);
HttpEntity<ChatRequest> requestEntity = new HttpEntity<>(chatRequest, headers);
return restTemplate.postForObject(apiUrl, requestEntity, ChatResponse.class);
}
}
package com.kclm.springboot3deepseek.deepseek.model;
import java.util.List;
public class ChatRequest {
private String model;
private List<Message> messages;
private double temperature;
private int max_tokens;
private boolean stream;
}
import java.util.List;
public class ChatResponse {
private String id;
private String object;
private long created;
private String model;
private List<Choice> choices;
}
/**
* 类名称:Choice
* 类描述:表示DeepSeek API响应中的选择项
*/
public class Choice {
private int index;
private Message message;
private String finishReason;
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public Message getMessage() {
return message;
}
public void setMessage(Message message) {
this.message = message;
}
public String getFinishReason() {
return finishReason;
}
public void setFinishReason(String finishReason) {
this.finishReason = finishReason;
}
}
package com.kclm.springboot3deepseek.deepseek.model;
/**
* 类名称:Message
* 类描述:表示聊天消息的模型类
*/
public class Message {
private String role;
private String content;
}
import com.kclm.springboot3deepseek.deepseek.client.DeepSeekApiClient;
import com.kclm.springboot3deepseek.deepseek.model.ChatRequest;
import com.kclm.springboot3deepseek.deepseek.model.ChatResponse;
import com.kclm.springboot3deepseek.deepseek.model.Message;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 类名称:DeepSeekChatService
* 类描述:主服务类,协调API客户端和对话历史管理
*/
@Service
public class DeepSeekChatService {
private final DeepSeekApiClient apiClient;
private final ConversationService conversationService;
private final String model;
private final double temperature;
private final int maxTokens;
public DeepSeekChatService(
DeepSeekApiClient apiClient,
ConversationService conversationService,
@Value("${deepseek.model}") String model,
@Value("${deepseek.temperature:0.7}") double temperature,
@Value("${deepseek.max-tokens:2048}") int maxTokens) {
this.apiClient = apiClient;
this.conversationService = conversationService;
this.model = model;
this.temperature = temperature;
this.maxTokens = maxTokens;
}
/**
* 与DeepSeek进行聊天
*
* @param userMessage 用户消息
* @return AI的响应
*/
public String chatWithDeepSeek(String userMessage) {
// 添加用户消息到对话历史
Message userMsg = new Message("user", userMessage);
conversationService.addMessage(userMsg);
// 准备请求
ChatRequest chatRequest = new ChatRequest();
chatRequest.setModel(model);
chatRequest.setMessages(conversationService.getConversationHistory());
chatRequest.setTemperature(temperature);
chatRequest.setMax_tokens(maxTokens);
chatRequest.setStream(false);
// 发送请求并获取响应
ChatResponse response = apiClient.sendChatRequest(chatRequest);
// 处理响应
if (response != null && response.getChoices() != null && !response.getChoices().isEmpty()) {
Message assistantMessage = response.getChoices().get(0).getMessage();
// 添加AI响应到对话历史
conversationService.addMessage(assistantMessage);
return assistantMessage.getContent();
}
return "抱歉,我无法生成回复。";
}
/**
* 清除对话历史
*/
public void clearConversationHistory() {
conversationService.clearConversationHistory();
}
}
import com.kclm.springboot3deepseek.deepseek.model.Message;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* 类名称:ConversationService
* 类描述:负责管理对话历史
*/
@Service
public class ConversationService {
private final List<Message> conversationHistory = new ArrayList<>();
/**
* 添加消息到对话历史
*
* @param message 要添加的消息
*/
public void addMessage(Message message) {
conversationHistory.add(message);
}
/**
* 获取当前对话历史
*
* @return 对话历史列表
*/
public List<Message> getConversationHistory() {
return new ArrayList<>(conversationHistory);
}
/**
* 清除对话历史
*/
public void clearConversationHistory() {
conversationHistory.clear();
}
}
import com.kclm.springboot3deepseek.deepseek.service.DeepSeekChatService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 类名称:ChatController
* 类描述:处理聊天相关的HTTP请求
*/
@RestController
public class ChatController {
private final DeepSeekChatService deepSeekChatService;
@Autowired
public ChatController(DeepSeekChatService deepSeekChatService) {
this.deepSeekChatService = deepSeekChatService;
}
@RequestMapping("/api/chat")
public String chat(@RequestBody String userMessage) {
System.out.println("收到用户消息: " + userMessage);
return deepSeekChatService.chatWithDeepSeek(userMessage);
}
@PostMapping("/clear")
public String clearConversation() {
deepSeekChatService.clearConversationHistory();
return "对话历史已清除";
}
}
deepseek.api.key=你自己的key
deepseek.api.url=https://api.deepseek.com/v1/chat/completions
deepseek.model=deepseek-chat
deepseek.temperature=0.7
deepseek.max-tokens=2048
- 前端界面使用VUE3
<template>
<div class="chat-container">
<div class="chat-history">
<div v-for="(message, index) in messages" :key="index" :class="['message', message.role]">
<div class="message-content">{{ message.content }}</div>
</div>
<div v-if="loading" class="message assistant">
<div class="message-content">思考中...</div>
</div>
</div>
<div class="chat-input">
<textarea v-model="userInput" @keyup.enter="sendMessage" placeholder="输入消息..."></textarea>
<button @click="sendMessage">发送</button>
<button @click="clearConversation">清空对话</button>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
import axios from 'axios';
const messages = ref([]);
const userInput = ref('');
const loading = ref(false);
const sendMessage = async () => {
if (!userInput.value.trim()) return;
// 添加用户消息
messages.value.push({ role: 'user', content: userInput.value });
const currentInput = userInput.value;
userInput.value = '';
loading.value = true;
try {
// 调用后端API
const response = await axios.post('http://localhost:8080/api/chat', {
message: currentInput
}, {
headers: {
'Content-Type': 'application/json'
}
});
// 添加AI回复
messages.value.push({ role: 'assistant', content: response.data });
} catch (error) {
console.error('调用API失败:', error);
messages.value.push({ role: 'assistant', content: '抱歉,出错了: ' + error.message });
} finally {
loading.value = false;
}
};
const clearConversation = async () => {
try {
await axios.post('http://localhost:8080/api/chat/clear');
messages.value = [];
} catch (error) {
console.error('清除对话失败:', error);
}
};
</script>
<style scoped>
.chat-container {
display: flex;
flex-direction: column;
height: 100vh;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.chat-history {
flex: 1;
overflow-y: auto;
margin-bottom: 20px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
}
.message {
margin-bottom: 15px;
padding: 10px;
border-radius: 5px;
}
.message.user {
background-color: #e3f2fd;
margin-left: 20%;
text-align: right;
}
.message.assistant {
background-color: #f5f5f5;
margin-right: 20%;
}
.message-content {
white-space: pre-wrap;
}
.chat-input {
display: flex;
gap: 10px;
}
.chat-input textarea {
flex: 1;
padding: 10px;
border: 1px solid #ddd;
border-radius: 5px;
resize: none;
height: 60px;
}
.chat-input button {
padding: 10px 15px;
background-color: #1976d2;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
.chat-input button:hover {
background-color: #1565c0;
}
</style>
- 效果
猜你喜欢
- 2025-08-02 React Native 常见问题集合
- 2025-08-02 React-Native 样式指南
- 2025-08-02 课堂点名总尴尬?试试 DeepSeek,或能实现点名自由!(附教程)
- 2025-08-02 手把手带你完成OpenHarmony藏头诗App
- 2025-08-02 Web设计练习:制作人脸识别网页(基于TensorFlow的开源模型)
- 2025-08-02 CSS支持 if / else 了
- 2025-08-02 CSS粘性页脚布局:从Flexbox到Grid的现代实现指南
- 2025-08-02 CSS 2025新特性解析:容器查询与嵌套选择器的高级应用案例
- 2025-08-02 如何设置Flexbox项目之间的距离
- 2025-08-02 教师如何制作随机点名系统,活跃课堂气氛
- 08-02C|在一个结构体嵌套一个共用体实现一体多用
- 08-02C++中,常用的强制类型转换函数
- 08-02如何使用C语言编程实现一个推箱子游戏?技术核心和算法实现
- 08-02C++20 新特性(24):模板访问权限和typename的放宽
- 08-02C++零基础到工程实践
- 08-02[深度学习] Python人脸识别库face_recognition使用教程
- 08-02AI算法之怎么利用Python实现支持向量机SVM算法
- 08-02【机器学习】SVM支持向量机
- 1520℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 623℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 526℃MySQL service启动脚本浅析(r12笔记第59天)
- 492℃启用MySQL查询缓存(mysql8.0查询缓存)
- 491℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 479℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 460℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 458℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- windowsscripthost (69)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- c语言min函数头文件 (68)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)