【实战教程】零基础搭建DeepSeek大模型聊天系统 - Spring Boot+React完整开发指南

news2025/5/12 14:01:12

🔥 本文详细讲解如何从零搭建一个完整的DeepSeek AI对话系统,包括Spring Boot后端和React前端,适合AI开发入门者快速上手。即使你是编程萌新,也能轻松搭建自己的AI助手!

📚博主匠心之作,强推专栏

  • JAVA集合专栏 【夜话集】
  • JVM知识专栏
  • 数据库sql理论与实战【博主踩坑之道】
  • 小游戏开发【博主强推 匠心之作 拿来即用无门槛】

DeepSeek AI对话系统

文章目录

    • 项目介绍
    • 系统架构
    • 后端项目搭建
      • 1. 创建Spring Boot项目
      • 2. 创建DeepSeek客户端
      • 3. 创建模型类
      • 4. 创建Controller层
    • 前端项目搭建
      • 1. 创建React项目
      • 2. 配置项目
      • 3. 创建API服务
      • 4. 创建聊天组件
      • 5. 支持Markdown渲染
    • 运行项目
    • 项目运行效果
      • 1. 初始界面展示
      • 2. 请求发送与等待响应
      • 3. AI响应后界面效果
      • 4. 长文本Markdown渲染展示
      • 5. 一键复制功能展示
    • 项目优化
    • 踩坑与解决方案
    • 项目拓展方向
    • 源码下载
    • 写在最后

项目介绍

在AI大模型时代,拥有一个自己的AI助手已不再是高不可攀的梦想。本文将带你从零开始,搭建一个完整的DeepSeek AI对话系统,包括Spring Boot后端和React前端,让你无需深厚的技术背景,也能轻松构建专属AI应用。

这个项目的核心功能是:

  • 🚀 通过Spring Boot构建稳定的后端服务
  • 🔌 对接DeepSeek AI API实现智能对话
  • 💻 使用React打造美观的前端界面
  • 🎨 支持Markdown格式的AI回复展示

源码已附文章末尾,有需要的朋友自行获取

系统架构

整个系统采用前后端分离架构,主要包含两个部分:

  1. 后端服务 (DeepSeekExtProject)

    • 基于Spring Boot框架
    • 提供RESTful API接口
    • 封装DeepSeek API调用逻辑
    • 处理请求/响应数据转换
  2. 前端应用 (DeepSeekExtWeb)

    • 基于React + TypeScript
    • 美观的聊天界面
    • 实时消息交互
    • Markdown格式渲染支持

后端项目搭建

1. 创建Spring Boot项目

首先,我们需要创建一个Spring Boot项目。可以通过Spring Initializr网站或IDE插件完成:

// 项目关键依赖
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.squareup.okhttp3</groupId>
        <artifactId>okhttp</artifactId>
        <version>4.9.3</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>2.0.23</version>
    </dependency>
</dependencies>

2. 创建DeepSeek客户端

接下来,创建一个客户端类来调用DeepSeek API:

public class DeepSeekClient {
    private static final String API_URL = "https://api.deepseek.com/v1/chat/completions";
    public static String API_KEY = "你的DeepSeek API Key";  // 替换为你的API密钥
    
    private static final String MODEL_CHAT = "deepseek-chat";
    private final OkHttpClient client = new OkHttpClient();

    public String getResponse(String apiKey, String prompt) throws IOException {
        // 构建请求体
        DeepSeekRequestModel requestBody = DeepSeekRequestModel.builder()
                .model(MODEL_CHAT)
                .messages(Arrays.asList(
                        DeepSeekRequestModel.Message.builder()
                                .role("user")
                                .content(prompt)
                                .build()
                ))
                .build();

        String jsonBody = JSON.toJSONString(requestBody);
        Request request = new Request.Builder()
                .url(API_URL)
                .post(RequestBody.create(jsonBody, MediaType.get("application/json")))
                .addHeader("Authorization", "Bearer " + apiKey)
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful() && response.body() != null) {
                return response.body().string();
            }
            throw new IOException("Unexpected code " + response);
        }
    }
}

3. 创建模型类

我们需要几个模型类来处理请求和响应:

// 请求模型
@Data
@Builder
public class DeepSeekRequestModel {
    private String model;
    private List<Message> messages;
    
    @Data
    @Builder
    public static class Message {
        private String role;
        private String content;
    }
}

// 响应模型
@Data
public class DeepSeeekResponse {
    private String id;
    private String object;
    private long created;
    private String model;
    private List<Choice> choices;
    
    @Data
    public static class Choice {
        private Message message;
        private String finish_reason;
        private int index;
    }
    
    @Data
    public static class Message {
        private String role;
        private String content;
    }
}

4. 创建Controller层

最后,创建一个控制器来处理HTTP请求:

@Controller
@RequestMapping("/deepseek")
@ResponseBody
public class DeepSeekController {

    @RequestMapping(value = "/ask", method = RequestMethod.POST)
    public R<String> ask(@RequestBody AskParam askParam) {
        try {
            String responsestr = new DeepSeekClient().getResponse(DeepSeekClient.API_KEY, askParam.getAskInfo());
            DeepSeeekResponse response = JSONObject.parseObject(responsestr, DeepSeeekResponse.class);
            for (DeepSeeekResponse.Choice choice : response.getChoices()) {
                if ("stop".equals(choice.getFinish_reason())) {
                    // 成功
                    String content = choice.getMessage().getContent();
                    return R.ok(content);
                }
            }
            return R.error("请求失败");
        } catch (IOException e) {
            return R.error("异常:" + e.getMessage());
        }
    }
}

前端项目搭建

1. 创建React项目

首先,创建一个新的React项目:

# 创建新项目
mkdir DeepSeekExtWeb
cd DeepSeekExtWeb

# 初始化package.json
npm init -y

# 安装核心依赖
npm install react react-dom react-scripts typescript @types/react @types/react-dom axios antd @ant-design/icons styled-components react-markdown remark-gfm rehype-highlight rehype-raw

2. 配置项目

创建必要的配置文件:

// package.json 配置启动脚本
"scripts": {
  "start": "set PORT=8889 && react-scripts start",
  "build": "react-scripts build"
}

// tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": ["src"]
}

3. 创建API服务

创建一个service文件处理API调用:

// src/services/deepSeekService.ts
import axios from 'axios';

const API_BASE_URL = 'http://localhost:8888';

export interface ApiResponse<T> {
  code: number;
  msg: string;
  data: T;
}

export const deepSeekService = {
  askQuestion: async (question: string): Promise<string> => {
    try {
      const response = await axios.post<ApiResponse<string>>(`${API_BASE_URL}/deepseek/ask`, {
        askInfo: question
      });
      
      if (response.data.code === 0) {
        return response.data.data;
      } else {
        throw new Error(response.data.msg || '请求失败');
      }
    } catch (error) {
      console.error('API请求错误:', error);
      throw error;
    }
  }
};

4. 创建聊天组件

构建核心的聊天界面组件:

// src/components/ChatPage.tsx (部分核心代码)
const ChatPage: React.FC = () => {
  const [inputValue, setInputValue] = useState('');
  const [messages, setMessages] = useState<MessageType[]>([
    {
      id: '1',
      content: '欢迎使用DeepSeek聊天助手,请输入您的问题!',
      sender: 'bot',
      timestamp: new Date().toISOString(),
    },
  ]);
  const [loading, setLoading] = useState(false);

  const handleSendMessage = async () => {
    if (!inputValue.trim()) {
      return;
    }

    const userMessage = {
      id: Date.now().toString(),
      content: inputValue,
      sender: 'user',
      timestamp: new Date().toISOString(),
    };

    setMessages((prev) => [...prev, userMessage]);
    setInputValue('');
    setLoading(true);

    try {
      const response = await deepSeekService.askQuestion(inputValue);
      
      const botMessage = {
        id: (Date.now() + 1).toString(),
        content: response,
        sender: 'bot',
        timestamp: new Date().toISOString(),
      };

      setTimeout(() => {
        setMessages((prev) => [...prev, botMessage]);
        setLoading(false);
      }, 500);
    } catch (error) {
      console.error('发送消息失败:', error);
      setLoading(false);
    }
  };

  return (
    <ChatContainer>
      <MessagesContainer>
        {messages.map((msg) => (
          <ChatMessage key={msg.id} message={msg} />
        ))}
        
        {loading && (
          <TypingIndicator>
            DeepSeek正在思考...
          </TypingIndicator>
        )}
      </MessagesContainer>
      
      <InputContainer>
        <TextArea
          value={inputValue}
          onChange={(e) => setInputValue(e.target.value)}
          placeholder="输入您的问题..."
          disabled={loading}
        />
        <Button
          type="primary"
          onClick={handleSendMessage}
          loading={loading}
        >
          发送
        </Button>
      </InputContainer>
    </ChatContainer>
  );
};

5. 支持Markdown渲染

为了优雅地显示AI回复,我们添加了Markdown渲染支持:

// src/components/ChatMessage.tsx (部分代码)
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import rehypeHighlight from 'rehype-highlight';

const ChatMessage: React.FC<ChatMessageProps> = ({ message }) => {
  const isUser = message.sender === 'user';
  
  const handleCopy = () => {
    navigator.clipboard.writeText(message.content);
    message.antd.message.success('已复制到剪贴板');
  };
  
  return (
    <MessageContainer isUser={isUser}>
      <MessageContent isUser={isUser}>
        {!isUser && (
          <CopyButton onClick={handleCopy}>
            <CopyOutlined />
          </CopyButton>
        )}
        <MessageBubble isUser={isUser}>
          {isUser ? (
            message.content
          ) : (
            <MarkdownContent isUser={isUser}>
              <ReactMarkdown
                remarkPlugins={[remarkGfm]} 
                rehypePlugins={[rehypeHighlight]}
              >
                {message.content}
              </ReactMarkdown>
            </MarkdownContent>
          )}
        </MessageBubble>
      </MessageContent>
    </MessageContainer>
  );
};

运行项目

完成以上代码开发后,你可以按以下步骤运行项目:

  1. 启动后端服务

    cd DeepSeekExtProject
    mvn spring-boot:run
    

    后端服务将在8888端口启动。

  2. 启动前端应用

    cd DeepSeekExtWeb
    npm start
    

    前端应用将在8889端口启动。

  3. 开始对话

    • 在浏览器访问 http://localhost:8889
    • 在输入框中输入问题并发送
    • 等待DeepSeek AI的回复(支持Markdown格式展示)

项目运行效果

完成所有代码后,成功运行项目,下面是实际效果展示:

1. 初始界面展示

项目启动后的初始聊天界面,等待用户输入问题

图1:项目启动后的初始聊天界面,等待用户输入问题

2. 请求发送与等待响应

用户发送问题后,显示加载动画提示AI正在思考

图2:用户发送问题后,显示加载动画提示AI正在思考

3. AI响应后界面效果

DeepSeek AI回答完成后的界面效果

图3:DeepSeek AI回答完成后的界面效果

4. 长文本Markdown渲染展示

查询"Java垃圾回收"等专业问题后,长文本响应的Markdown渲染效果

图4:查询"Java垃圾回收"等专业问题后,长文本响应的Markdown渲染效果

5. 一键复制功能展示

用户可以通过点击复制按钮,一键复制AI回复内容,方便在其他地方使用

图5:用户可以通过点击复制按钮,一键复制AI回复内容,方便在其他地方使用

从上面的截图中可以看到,我们的聊天界面具有以下特点:

  • 美观的UI设计:采用简洁现代的卡片式设计,聊天气泡明确区分用户和AI
  • 加载状态提示:用户等待AI思考时有动态加载提示,增强交互体验
  • Markdown完美渲染:支持代码块、标题、列表、表格等Markdown元素的精确渲染
  • 左对齐文本展示:所有AI回复内容均左对齐,提高可读性,方便用户阅读长文本

这种设计不仅美观,还极大提高了用户体验,特别是对于长篇技术解答,格式化展示让内容更易理解。

项目优化

我们对项目进行了多项优化,提升用户体验:

  1. UI美化

    • 精心设计的聊天气泡
    • 加载状态动画
    • 响应式布局适配多种设备
  2. 功能增强

    • 支持Markdown格式渲染
    • 代码高亮显示
    • 一键复制AI回复内容:每条AI回复右上角配有复制按钮,方便用户快速复制所需内容
  3. 性能优化

    • 消息自动滚动到底部
    • 防抖处理避免重复请求
    • 错误处理与提示

踩坑与解决方案

在开发过程中,我们遇到的主要问题及解决方案:

  1. 跨域问题

    • 解决方案:在Spring Boot后端添加CORS配置
  2. Markdown渲染

    • 问题:AI返回的Markdown内容无法正常显示
    • 解决方案:引入react-markdown等库进行处理
  3. 响应内容居中问题

    • 问题:Markdown内容默认居中显示
    • 解决方案:添加text-align:left样式强制左对齐

项目拓展方向

这个基础项目可以进一步拓展为:

  1. 添加会话历史:保存对话历史,实现多轮对话
  2. 用户管理:添加登录注册功能
  3. 多模型支持:集成更多AI模型,如GPT系列
  4. 自定义参数:允许用户调整温度、最大长度等参数
  5. 语音交互:添加语音输入和输出功能

源码下载

为方便读者快速上手,我已将完整项目源码打包上传,包含以下内容:

  • DeepSeekExtProject(Java后端项目)

    • 完整的Spring Boot项目结构
    • DeepSeek API调用封装
    • 请求/响应处理逻辑
  • DeepSeekExtWeb(React前端项目)

    • 完整的React+TypeScript项目结构
    • 聊天界面组件
    • Markdown渲染功能
    • 一键复制实现

源码下载地址:DeepSeek AI对话系统完整源码

使用说明:

  1. 下载并解压源码包
  2. 按照上述运行步骤分别启动前后端项目
  3. 修改后端DeepSeekClient.java中的API_KEY为您自己的密钥

注意:使用前请确保已安装Java 8+、Maven、Node.js 14+环境。

写在最后

🎉 通过本文的指导,即使是编程萌新也能轻松搭建一个完整的DeepSeek AI对话系统。希望这个项目能帮助你开启AI开发之旅!

📚 推荐几篇很有趣的文章

  • DeepSeek详解:探索下一代语言模型
  • 算法模型从入门到起飞系列——递归(探索自我重复的奇妙之旅)

📚博主匠心之作,强推专栏

  • JAVA集合专栏 【夜话集】
  • JVM知识专栏
  • 数据库sql理论与实战【博主踩坑之道】
  • 小游戏开发【博主强推 匠心之作 拿来即用无门槛】

如果觉得有帮助的话,别忘了点个赞 👍 收藏 ⭐ 关注 🔖 哦!


🎯 我是果冻~,一个热爱技术、乐于分享的开发者
📚 更多精彩内容,请关注我的博客
🌟 我们下期再见!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2373971.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用C语言实现的——一个支持完整增删查改功能的二叉排序树BST管理系统,通过控制台实现用户与数据结构的交互操作。

一、知识回顾 二叉排序树&#xff08;Binary Search Tree&#xff0c;BST&#xff09;&#xff0c;又称二叉查找树或二叉搜索树&#xff0c;是一种特殊的二叉树数据结构。 基本性质&#xff1a; ①有序性 对于树中的每个节点&#xff0c;其左子树中所有节点的值都小于该节点的…

论文阅读笔记——ROBOGROUND: Robotic Manipulation with Grounded Vision-Language Priors

RoboGround 论文 一类中间表征是语言指令&#xff0c;但对于空间位置描述过于模糊&#xff08;“把杯子放桌上”但不知道放桌上哪里&#xff09;&#xff1b;另一类是目标图像或点流&#xff0c;但是开销大&#xff1b;由此 GeoDEX 提出一种兼具二者的掩码。 相比于 GR-1&#…

『 测试 』测试基础

文章目录 1. 调试与测试的区别2. 开发过程中的需求3. 开发模型3.1 软件的生命周期3.2 瀑布模型3.2.1 瀑布模型的特点/缺点 3.3 螺旋模型3.3.1 螺旋模型的特点/缺点 3.4 增量模型与迭代模型3.5 敏捷模型3.5.1 Scrum模型3.5.2 敏捷模型中的测试 4 测试模型4.1 V模型4.2 W模型(双V…

robomaster机甲大师--电调电机

文章目录 C620电调ID设置速率 电调发送报文电调接收报文cubemx程序初始化发送接收 C620电调 ID设置 速率 1Mbps 电调发送报文 发送的数据为控制电机的输出电流&#xff0c;需要将can数据帧的ID设置为0x200 电调接收报文 机械角度&#xff1a;电机的0到360度映射到0到几千转…

少儿编程机构用的教务系统

在编程教育行业快速发展的今天&#xff0c;培训机构面临着学员管理复杂、课程体系专业性强、教学效果难以量化等独特挑战。爱耕云教务系统针对编程培训机构的特殊需求&#xff0c;提供了一套全方位的数字化解决方案&#xff0c;帮助机构实现高效运营和教学质量提升。 为什么编…

基于VSCode+PlatformIO环境的ESP8266的HX1838红外模块

以下是针对ESP8266开发板的红外遥控解码系统开发教程&#xff0c;基于VSCodePlatformIO环境编写 一、概述 本实验通过ESP8266开发板实现&#xff1a; 红外遥控信号解码自定义按键功能映射串口监控输出基础设备控制&#xff08;LED&#xff09; 硬件组成&#xff1a; NodeMC…

Linux中的防火墙

什么是防火墙 windows防火墙的设置 linux防火墙设置命令 什么是防火墙&#xff1f; 防火墙是一种网络安全设备&#xff0c;它能够&#xff1a; 监控和过滤进出网络的流量 阻止不安全的连接 保护计算机和网络免受未授权访问 创建一个安全边界 简单来说&#xff0c;防火…

补补表面粗糙度的相关知识(一)

表面粗糙度&#xff0c;或简称粗糙度&#xff0c;是指表面不光滑的特性。这个在机械加工行业内可以说是绝绝的必备知识之一&#xff0c;但往往也是最容易被忽略的&#xff0c;因为往往天天接触的反而不怎么关心&#xff0c;或者没有真正的去认真学习掌握。对于像我一样&#xf…

力扣刷题Day 46:搜索二维矩阵 II(240)

1.题目描述 2.思路 方法1&#xff1a;分别找到搜索矩阵的右、下边界&#xff0c;然后从[0][0]位置开始遍历这部分矩阵搜索目标值。 方法2&#xff1a;学习Krahets佬的思路&#xff0c;从搜索矩阵的左下角开始遍历&#xff0c;matrix[i][j] > target时消去第i行&#xff0c…

Kubernetes 集群部署应用

部署 Nginx 应用 命令行的方式 1. 创建 deployment 控制器的 pod # --imagenginx&#xff1a;这个会从 docker.io 中拉取&#xff0c;这个网站拉不下来 # kubectl create deployment mynginx --imagenginx# 使用国内镜像源拉取 kubectl create deployment mynginx --imaged…

Unity3D仿星露谷物语开发42之粒子系统

1、目标 使用例子系统&#xff0c;实现割草后草掉落的特效。 通过PoolManager获取特效预制体&#xff0c;通过VFXManager来触发特效。 2、配置例子特效 在Hierarchy -> PersistentScene下创建新物体命名为Reaping。 给该物体添加Particle System组件。 配置例子系统参数…

python 上海新闻爬虫, 东方网 + 澎湃新闻

1. 起因&#xff0c; 目的: 继续做新闻爬虫。我之前写过。此文先记录2个新闻来源。后面打算进行过滤&#xff0c;比如只选出某一个类型新闻。 2. 先看效果 过滤出某种类型的新闻&#xff0c;然后生成 html 页面&#xff0c;而且&#xff0c;自动打开这个页面。 比如科技犯罪…

[Java实战]Spring Boot 整合 Freemarker (十一)

[Java实战]Spring Boot 整合 Freemarker (十一) 引言 Apache FreeMarker 作为一款高性能的模板引擎&#xff0c;凭借其简洁语法、卓越性能和灵活扩展性&#xff0c;在 Java Web 开发中占据重要地位。结合 Spring Boot 的自动化配置能力&#xff0c;开发者能快速构建动态页面、…

LeetCode 高频题实战:如何优雅地序列化和反序列化字符串数组?

文章目录 摘要描述题解答案题解代码分析编码方法解码方法 示例测试及结果时间复杂度空间复杂度总结 摘要 在分布式系统中&#xff0c;数据的序列化与反序列化是常见的需求&#xff0c;尤其是在网络传输、数据存储等场景中。LeetCode 第 271 题“字符串的编码与解码”要求我们设…

C#游戏开发中的注意事项

目录 一、性能优化:提升游戏运行效率 1. 避免不必要的循环和迭代 2. 减少字符串拼接 3. 利用Unity的生命周期函数 4. 使用对象池(Object Pooling) 二、内存管理:避免内存泄漏和资源浪费 1. 及时释放非托管资源 2. 避免空引用异常 3. 合理使用引用类型和值类型 4. …

Spring Boot项目(Vue3+ElementPlus+Axios+MyBatisPlus+Spring Boot前后端分离)

下载地址&#xff1a; 前端&#xff1a;https://download.csdn.net/download/2401_83418369/90811402 后端&#xff1a;https://download.csdn.net/download/2401_83418369/90811405 一、前端vue部分的搭建 这里直接看另一期刊的搭建Vue前端工程部分 前端vue后端ssm项目_v…

Spyglass:在batch/shell模式下运行目标的顶层是什么?

相关阅读 Spyglasshttps://blog.csdn.net/weixin_45791458/category_12828934.html?spm1001.2014.3001.5482 除了可以在图形用户界面(GUI)中运行目标外&#xff0c;使用Batch模式或Shell模式也可以运行目标&#xff0c;如下面的命令所示。 % spyglass -project test.prj -ba…

微服务架构中如何保证服务间通讯的安全

在微服务架构中,保证服务间通信的安全至关重要。服务间的通信通常是通过HTTP、gRPC、消息队列等方式实现的,而这些通信链路可能面临多种安全风险。为了应对这些风险,可以采取多种措施来保证通信安全。 常见的服务间通信风险 1.数据泄露:在服务间通信过程中,敏感数据可能会…

工具篇-Cherry Studio之MCP使用

一、添加MCP 打开Cherry Studio,如果没有可以到官网下载:Cherry Studio 官方网站 - 全能的AI助手 按上面步骤打开同步服务器 1、先去注册ModelScope,申请令牌 2、再打开MCP广场,找到高德MCP 选择工具测试,这里有个高德的api key需要申请 打开如下地址高德开放平…

Python 运维脚本

1、备份文件 import os import shutil# 定义配置文件目录和备份目录的路径 config_dir "/root/python/to/config/files/" backup_dir "/root/python/to/backup/"# 遍历配置文件目录中的所有文件 for filename in os.listdir(config_dir):# 如果文件名以…