在Spring Boot项目中接入DeepSeek深度求索,感觉笨笨的呢
文章目录
- 引言
- 1. 什么是DeepSeek?
- 2. 准备工作
- 2.1 注册DeepSeek账号
- 3.实战演示
- 3.1 application增加DS配置
- 3.2 编写service
- 3.3 编写controller
- 3.4 编写前端界面chat.html
- 3.5 测试
- 总结
引言
在当今快速发展的数据驱动时代,企业越来越重视数据的价值。为了更好地理解和利用数据,许多公司开始采用先进的数据分析和搜索技术。DeepSeek(深度求索)就是一款强大的深度学习驱动的搜索和推荐系统,可以帮助企业高效地处理和分析大规模数据。本文将详细介绍如何在Spring Boot项目中接入DeepSeek,帮助各位大大快速上手并利用其强大的功能。
1. 什么是DeepSeek?
DeepSeek 是一款基于深度学习的搜索和推荐系统,能够帮助企业从海量数据中快速提取有价值的信息。它结合了自然语言处理(NLP)、机器学习和深度学习技术,提供精准的搜索结果和个性化推荐。DeepSeek的主要特点包括:
精准搜索:通过深度学习算法,DeepSeek能够理解用户查询的意图,提供更精准的搜索结果。
个性化推荐:基于用户行为和偏好,DeepSeek能够为用户提供个性化的推荐内容。
高效处理:支持大规模数据处理,能够快速响应用户请求。
易于集成:提供丰富的API接口,方便与其他系统集成。
2. 准备工作
在开始接入DeepSeek之前,需要完成以下准备工作:
2.1 注册DeepSeek账号
首先,访问DeepSeek的API开放平台( https://platform.deepseek.com/sign_in),注册一个账号。注册完成后,登录账号并创建一个新的项目,获取项目ID和API密钥。
注意:生成key后需要充值后才能正常调用其API。
3.实战演示
3.1 application增加DS配置
ds: key: 填写在官网申请的key url: https://api.deepseek.com/chat/completions
3.2 编写service
/** * DsChatService * @author senfel * @version 1.0 * @date 2025/3/13 17:30 */ public interface DsChatService { /** * chat * @param userId * @param question * @author senfel * @date 2025/3/13 17:30 * @return org.springframework.web.servlet.mvc.method.annotation.SseEmitter */ SseEmitter chat(String userId,String question); }
/** * DsChatServiceImpl * @author senfel * @version 1.0 * @date 2025/3/13 17:31 */ @Service @Slf4j public class DsChatServiceImpl implements DsChatService { @Value("${ds.key}") private String dsKey; @Value("${ds.url}") private String dsUrl; // 用于保存每个用户的对话历史 private final Map sessionHistory = new ConcurrentHashMap(); private final ExecutorService executorService = Executors.newCachedThreadPool(); private final ObjectMapper objectMapper = new ObjectMapper(); /** * chat * @param userId * @param question * @author senfel * @date 2025/3/13 17:36 * @return org.springframework.web.servlet.mvc.method.annotation.SseEmitter */ @Override public SseEmitter chat(String userId,String question) { SseEmitter emitter = new SseEmitter(-1L); executorService.execute(() -> { try { log.info("流式回答开始, 问题: {}", question); // 获取当前用户的对话历史 List messages = sessionHistory.getOrDefault(userId, new ArrayList()); // 添加用户的新问题到对话历史 Map userMessage = new HashMap(); userMessage.put("role", "user"); userMessage.put("content", question); Map systemMessage = new HashMap(); systemMessage.put("role", "system"); systemMessage.put("content", "senfel的AI助手"); messages.add(userMessage); messages.add(systemMessage); // 调用 DeepSeek API try (CloseableHttpClient client = HttpClients.createDefault()) { HttpPost request = new HttpPost(dsUrl); request.setHeader("Content-Type", "application/json"); request.setHeader("Authorization", "Bearer " + dsKey); Map requestMap = new HashMap(); requestMap.put("model", "deepseek-chat"); requestMap.put("messages", messages); requestMap.put("stream", true); String requestBody = objectMapper.writeValueAsString(requestMap); request.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8)); try (CloseableHttpResponse response = client.execute(request); BufferedReader reader = new BufferedReader( new InputStreamReader(response.getEntity().getContent(), StandardCharsets.UTF_8))) { StringBuilder aiResponse = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { if (line.startsWith("data: ")) { System.err.println(line); String jsonData = line.substring(6); if ("[DONE]".equals(jsonData)) { break; } JsonNode node = objectMapper.readTree(jsonData); String content = node.path("choices") .path(0) .path("delta") .path("content") .asText(""); if (!content.isEmpty()) { emitter.send(content); aiResponse.append(content); // 收集 AI 的回复 } } } // 将 AI 的回复添加到对话历史 Map aiMessage = new HashMap(); aiMessage.put("role", "assistant"); aiMessage.put("content", aiResponse.toString()); messages.add(aiMessage); // 更新会话状态 sessionHistory.put(userId, messages); log.info("流式回答结束, 问题: {}", question); emitter.complete(); } } catch (Exception e) { log.error("处理 DeepSeek 请求时发生错误", e); emitter.completeWithError(e); } } catch (Exception e) { log.error("处理 DeepSeek 请求时发生错误", e); emitter.completeWithError(e); } }); return emitter; } }
3.3 编写controller
/** * DsController * @author senfel * @version 1.0 * @date 2025/3/13 17:21 */ @RestController @RequestMapping("/deepSeek") @Slf4j public class DsController { @Resource private DsChatService dsChatService; /** * chat page * @param modelAndView * @author senfel * @date 2025/3/13 17:39 * @return org.springframework.web.servlet.ModelAndView */ @GetMapping() public ModelAndView chat(ModelAndView modelAndView) { modelAndView.setViewName("chat"); return modelAndView; } /** * chat * @param question * @author senfel * @date 2025/3/13 17:39 * @return org.springframework.web.servlet.mvc.method.annotation.SseEmitter */ @PostMapping(value = "/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public SseEmitter chat(@RequestBody String question) { //TODO 默认用户ID,实际场景从token获取 String userId = "senfel"; return dsChatService.chat(userId, question); } }
3.4 编写前端界面chat.html
DeepSeek Chat :root { --primary-color: #5b8cff; --user-bg: linear-gradient(135deg, #5b8cff 0%, #3d6ef7 100%); --bot-bg: linear-gradient(135deg, #f0f8ff 0%, #e6f3ff 100%); --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); } body { font-family: 'Segoe UI', system-ui, -apple-system, sans-serif; margin: 0; padding: 20px; display: flex; justify-content: center; min-height: 100vh; background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); } .chat-container { width: 100%; max-width: 800px; height: 90vh; background: rgba(255, 255, 255, 0.95); border-radius: 20px; box-shadow: var(--shadow); backdrop-filter: blur(10px); display: flex; flex-direction: column; overflow: hidden; } .chat-header { padding: 24px; background: var(--primary-color); color: white; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } .chat-header h1 { margin: 0; font-size: 1.8rem; font-weight: 600; letter-spacing: -0.5px; } .chat-messages { flex: 1; padding: 20px; overflow-y: auto; display: flex; flex-direction: column; gap: 12px; } .chat-message { max-width: 75%; padding: 16px 20px; border-radius: 20px; line-height: 1.5; animation: messageAppear 0.3s ease-out; position: relative; word-break: break-word; } .chat-message.user { background: var(--user-bg); color: white; align-self: flex-end; border-bottom-right-radius: 4px; box-shadow: var(--shadow); } .chat-message.bot { background: var(--bot-bg); color: #2d3748; align-self: flex-start; border-bottom-left-radius: 4px; box-shadow: var(--shadow); } .chat-input { padding: 20px; background: rgba(255, 255, 255, 0.9); border-top: 1px solid rgba(0, 0, 0, 0.05); display: flex; gap: 12px; } .chat-input input { flex: 1; padding: 14px 20px; border: 2px solid rgba(0, 0, 0, 0.1); border-radius: 16px; font-size: 1rem; transition: all 0.2s ease; background: rgba(255, 255, 255, 0.8); } .chat-input input:focus { outline: none; border-color: var(--primary-color); box-shadow: 0 0 0 3px rgba(91, 140, 255, 0.2); } .chat-input button { padding: 12px 24px; border: none; border-radius: 16px; background: var(--primary-color); color: white; font-size: 1rem; font-weight: 500; cursor: pointer; transition: all 0.2s ease; display: flex; align-items: center; gap: 8px; } .chat-input button:hover { background: #406cff; transform: translateY(-1px); } .chat-input button:disabled { background: #c2d1ff; cursor: not-allowed; transform: none; } .chat-input button svg { width: 18px; height: 18px; fill: currentColor; } @keyframes messageAppear { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .typing-indicator { display: inline-flex; gap: 6px; padding: 12px 20px; background: var(--bot-bg); border-radius: 20px; align-self: flex-start; } .typing-dot { width: 8px; height: 8px; background: rgba(0, 0, 0, 0.3); border-radius: 50%; animation: typing 1.4s infinite ease-in-out; } .typing-dot:nth-child(2) { animation-delay: 0.2s; } .typing-dot:nth-child(3) { animation-delay: 0.4s; } @keyframes typing { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-4px); } } @media (max-width: 640px) { body { padding: 10px; } .chat-container { height: 95vh; border-radius: 16px; } .chat-message { max-width: 85%; } }
DeepSeek Chat
发送3.5 测试
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。