一句话让deepseek实现基于Spring AI的AI chatbot

最近美国向全球加征关税,对全球经济贸易产生巨大影响,2025-04-07日,对全球来说都是黑色星期一,这两天相信大家都在刷各种金融资讯小作文。而AI作为本次技术革命先锋,最近各大金融公司也相继进行金融+AI的落地实践,积极拥抱新技术。我们也在积极探索尝试AI程序员、AI投资顾问落地应用。

一、前言背景

二、向deepseek明确具体需求

三、项目结构

四、配置参数启动

五、最终demo实例

六、总结和展望

七、项目源码

一、前言背景

最近AI程序员非常火热,在AI coding rank上,国际大模型排名靠前的是claude 3.7 sonnet、gemini-2.5、还有deepseek v3。在编程领域,国内的混元、通义、豆包背后的金主也在积极布局AI coding 助手。未来万物皆可AI的局面将百花齐放,大幅提升各行各业的效率。

IT人员已经开始尝试一键AI生成系统项目代码,或者对系统新功能直接一键生成。

今天通过一句话让deepseek生成基于Spring A+DeepseekI实现的在线AI chatbot助手。大模型给出的代码0修改,只修改了pom,就直接启动可用。最终效果界面:

二、向deepseek明确具体需求

Spring AI 1.0已经集成支持目前主流的各种大模型还有模型实践框架技术。我们熟悉的RAG、MCP、prompts、语音、图片、视频、向量数据库、AI大模型基本都及时集成支持,方便大家应用到系统实践。

今天我们就通过一小段话,明确实现一个Springboot项目,提供一个在线AI聊天助手。具体内容如下:

【你是一个java研发人员,现在有一个Springboot项目需要你去完整实现,主要通过集成Spring ai 和deepseek,提供一个在线可视化聊天机器人系统。最终提供一个界面支持用户输入聊天内容,并响应展示deepseek返回内容。】

deepseek强大的推理能力,在prompt及其简略的前提下,依然可以给出超出预期的满意答复。deepseek 直接给出项目源代码,并推荐使用Spring initialize去初始化项目。

三、项目结构

deepseek最终给出的项目架构是JDK17+Spring AI+thymeleaf+Spring web来实现。

具体项目源码内容有:

1、pom.xml详细配置(这里存在唯一一个bug)。deepseek 给的depenency用的是

spring-ai-ollama-spring-boot-starter,最后调整为spring-ai-bom才成功。

2、deepseek客户端,通过restClient调用deepseek api的bean,以及Service层的逻辑处理。

3、请求响应的model DeepSeekRequest.java+DeepSeekResponse.java+ChatMessage.java (模型)。

4、chat接口,支持前端界面录入聊天内容并返回。

5、前端界面实现templates/chat.html。

四、配置参数启动

在deepseek提供源码application.properties基础上,deepseek的答案也完整提示,在application继续新增与deepseek api相关的两个参数配置进去。

ini 复制代码
deepseek.api.key=your-deepseek-api-key
deepseek.api.url=https://api.deepseek.com/v1/chat/completions

然后 Spring Boot 应用程序,访问localhost:8080就可以访问。

五、最终demo实例

界面虽然很简陋,后端功能也没有实现没有上下文记忆能力。但是这种一键生成项目系统源码,0代码修改,只需要简单配置就可以直接运行的感觉,不得不佩服AI强大的能力。

六、总结和展望

除了尝试这种prompt方式去获得AI提供的系统源码能力,还尝试了其他几种agent方式。总体而言,针对一键生成UI设计、数据处理分析任务、完整系统项目源码生成、量化研究任务几个场景,陆续尝试过多个大模型,以及多个agent,但是目前总体感觉通用大模型还是不够智能,尤其是编程环境的复杂依赖、版本兼容冲突问题解决还不尽如意,然而智能IDE目前国内支持的还很少,值得期待。当然单纯的智能补齐、代码分析、单测编写已经非常成熟好用。

所以AI替换程序员的话题,个人觉得还有很大一段距离。而AI提升编程效率改变编程的时代,已经来临。

7.1 pom.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>ai-chatbot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>ai-chatbot</name>
    <description>Demo project for Spring Boot with DeepSeek AI</description>
    <properties>
        <java.version>17</java.version>
        <spring-ai.version>0.8.1</spring-ai.version>
    </properties>
    <dependencies>
        <!-- Spring Boot Starters -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!-- Other dependencies -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </repository>
        <repository>
            <name>Central Portal Snapshots</name>
            <id>central-portal-snapshots</id>
            <url>https://central.sonatype.com/repository/maven-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

7.2 application.properties

ini 复制代码
spring.application.name=ai-chatbot
# Server port
server.port=8080
# Spring AI - DeepSeek configuration
# Note: As of my knowledge cutoff, Spring AI doesn't have direct DeepSeek support
# We'll implement a custom client for DeepSeek API
# Thymeleaf configuration
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML
spring.thymeleaf.encoding=UTF-8
deepseek.api.key=你的deepseek api key替换
deepseek.api.url=https://api.deepseek.com/v1/chat/completions

7.3 DeepSeekConfig.java

kotlin 复制代码
package com.example.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestClient;
@Configuration
public class DeepSeekConfig {
    @Value("${deepseek.api.key}")
    private String apiKey;
    @Value("${deepseek.api.url}")
    private String apiUrl;
    @Bean
    public RestClient deepSeekRestClient() {
        return RestClient.builder()
                .baseUrl(apiUrl)
                .defaultHeader("Authorization", "Bearer " + apiKey)
                .defaultHeader("Content-Type", "application/json")
                .build();
    }
}

7.4 model 模型

ChatMessage.java、DeepSeekRequest.java 、DeepSeekResponse.java

typescript 复制代码
package com.example.model;
import java.util.List;
public class DeepSeekResponse {
    private String id;
    private String object;
    private long created;
    private String model;
    private List<Choice> choices;
    private Usage usage;
    // Getters and setters
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getObject() {
        return object;
    }
    public void setObject(String object) {
        this.object = object;
    }
    public long getCreated() {
        return created;
    }
    public void setCreated(long created) {
        this.created = created;
    }
    public String getModel() {
        return model;
    }
    public void setModel(String model) {
        this.model = model;
    }
    public List<Choice> getChoices() {
        return choices;
    }
    public void setChoices(List<Choice> choices) {
        this.choices = choices;
    }
    public Usage getUsage() {
        return usage;
    }
    public void setUsage(Usage usage) {
        this.usage = usage;
    }
    public static class Choice {
        private int index;
        private Message message;
        private String finish_reason;
        // Getters and setters
        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 getFinish_reason() {
            return finish_reason;
        }
        public void setFinish_reason(String finish_reason) {
            this.finish_reason = finish_reason;
        }
    }
    public static class Message {
        private String role;
        private String content;
        // Getters and setters
        public String getRole() {
            return role;
        }
        public void setRole(String role) {
            this.role = role;
        }
        public String getContent() {
            return content;
        }
        public void setContent(String content) {
            this.content = content;
        }
    }
    public static class Usage {
        private int prompt_tokens;
        private int completion_tokens;
        private int total_tokens;
        // Getters and setters
        public int getPrompt_tokens() {
            return prompt_tokens;
        }
        public void setPrompt_tokens(int prompt_tokens) {
            this.prompt_tokens = prompt_tokens;
        }
        public int getCompletion_tokens() {
            return completion_tokens;
        }
        public void setCompletion_tokens(int completion_tokens) {
            this.completion_tokens = completion_tokens;
        }
        public int getTotal_tokens() {
            return total_tokens;
        }
        public void setTotal_tokens(int total_tokens) {
            this.total_tokens = total_tokens;
        }
    }
}





package com.example.model;
import java.util.ArrayList;
import java.util.List;
public class DeepSeekRequest {
    private String model = "deepseek-chat";
    private List<Message> messages;
    private double temperature = 0.7;
    private int max_tokens = 2000;
    public DeepSeekRequest(String prompt) {
        this.messages = new ArrayList<>();
        this.messages.add(new Message("user", prompt));
    }
    // Getters and setters
    public String getModel() {
        return model;
    }
    public void setModel(String model) {
        this.model = model;
    }
    public List<Message> getMessages() {
        return messages;
    }
    public void setMessages(List<Message> messages) {
        this.messages = messages;
    }
    public double getTemperature() {
        return temperature;
    }
    public void setTemperature(double temperature) {
        this.temperature = temperature;
    }
    public int getMax_tokens() {
        return max_tokens;
    }
    public void setMax_tokens(int max_tokens) {
        this.max_tokens = max_tokens;
    }
    public static class Message {
        private String role;
        private String content;
        public Message(String role, String content) {
            this.role = role;
            this.content = content;
        }
        // Getters and setters
        public String getRole() {
            return role;
        }
        public void setRole(String role) {
            this.role = role;
        }
        public String getContent() {
            return content;
        }
        public void setContent(String content) {
            this.content = content;
        }
    }
}



package com.example.model;
public class ChatMessage {
    private String role; // "user" or "ai"
    private String content;
    public ChatMessage() {
    }
    public ChatMessage(String role, String content) {
        this.role = role;
        this.content = content;
    }
    // Getters and setters
    public String getRole() {
        return role;
    }
    public void setRole(String role) {
        this.role = role;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
}

7.5 DeepSeekService.java

kotlin 复制代码
package com.example.service;
import com.example.model.DeepSeekRequest;
import com.example.model.DeepSeekResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;
@Service
public class DeepSeekService {
    private final RestClient deepSeekRestClient;
    @Autowired
    public DeepSeekService(RestClient deepSeekRestClient) {
        this.deepSeekRestClient = deepSeekRestClient;
    }
    public String generateResponse(String prompt) {
        DeepSeekRequest request = new DeepSeekRequest(prompt);
        DeepSeekResponse response = deepSeekRestClient.post()
                .body(request)
                .retrieve()
                .body(DeepSeekResponse.class);
        return response != null ? response.getChoices().get(0).getMessage().getContent() : "No response from DeepSeek";
    }
}

7.6 ChatController.java

java 复制代码
package com.example.controller;
import com.example.model.ChatMessage;
import com.example.service.DeepSeekService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.ArrayList;
import java.util.List;
@Controller
public class ChatController {
    private final DeepSeekService deepSeekService;
    private List<ChatMessage> chatHistory = new ArrayList<>();
    public ChatController(DeepSeekService deepSeekService) {
        this.deepSeekService = deepSeekService;
    }
    @GetMapping("/")
    public String chat(Model model) {
        model.addAttribute("chatMessage", new ChatMessage());
        model.addAttribute("chatHistory", chatHistory);
        return "chat";
    }
    @PostMapping("/send")
    public String sendMessage(@ModelAttribute ChatMessage chatMessage, Model model) {
        // Add user message to chat history
        chatHistory.add(new ChatMessage("user", chatMessage.getContent()));
        // Get response from DeepSeek
        String response = deepSeekService.generateResponse(chatMessage.getContent());
        // Add AI response to chat history
        chatHistory.add(new ChatMessage("ai", response));
        model.addAttribute("chatMessage", new ChatMessage());
        model.addAttribute("chatHistory", chatHistory);
        return "chat";
    }
}

7.7 前端实现templates/chat.html

xml 复制代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DeepSeek Chatbot</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .chat-container {
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            border: 1px solid #ddd;
            border-radius: 10px;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }
        .chat-history {
            height: 500px;
            overflow-y: auto;
            margin-bottom: 20px;
            padding: 10px;
            border: 1px solid #eee;
            border-radius: 5px;
        }
        .user-message {
            background-color: #e3f2fd;
            padding: 10px;
            border-radius: 10px;
            margin-bottom: 10px;
            max-width: 80%;
            margin-left: auto;
        }
        .ai-message {
            background-color: #f5f5f5;
            padding: 10px;
            border-radius: 10px;
            margin-bottom: 10px;
            max-width: 80%;
        }
        .message-time {
            font-size: 0.8em;
            color: #666;
            margin-top: 5px;
        }
    </style>
</head>
<body>
<div class="container mt-5">
    <div class="chat-container">
        <h2 class="text-center mb-4">DeepSeek Chatbot</h2>
        <div class="chat-history" id="chatHistory">
            <div th:each="message : ${chatHistory}">
                <div th:class="${message.role == 'user' ? 'user-message' : 'ai-message'}">
                    <strong th:text="${message.role == 'user' ? 'You:' : 'AI:'}"></strong>
                    <div th:text="${message.content}"></div>
                    <div class="message-time" th:text="${#temporals.format(#temporals.createNow(), 'HH:mm')}"></div>
                </div>
            </div>
        </div>
        <form th:action="@{/send}" th:object="${chatMessage}" method="post">
            <div class="input-group mb-3">
                <input type="text" class="form-control" th:field="*{content}"
                       placeholder="Type your message here..." autocomplete="off">
                <button class="btn btn-primary" type="submit">Send</button>
            </div>
        </form>
    </div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script>
    // Scroll to bottom of chat history
    window.onload = function() {
        var chatHistory = document.getElementById('chatHistory');
        chatHistory.scrollTop = chatHistory.scrollHeight;
    };
</script>
</body>
</html>
相关推荐
赞奇科技Xsuperzone3 分钟前
NVIDIA RTX™ GPU 低成本启动零售 AI 场景开发
人工智能·gpu算力·零售
无限大65 分钟前
数据结构与算法入门 Day 0:程序世界的基石与密码
后端·算法·程序员
程序猿DD24 分钟前
什么是A2A,什么是MCP?
人工智能·mcp
果冻人工智能27 分钟前
AI 技术栈不复杂:四个层级讲明白,我选了最香的一层
人工智能
追逐☞35 分钟前
机器学习(2)——逻辑回归
人工智能·机器学习·逻辑回归
zhongqu_3dnest37 分钟前
众趣科技上线 AI 户型图功能,开启房产领域数字化大模型效率革命
人工智能·科技
中钧科技43 分钟前
智能系统:中钧科技的秘密武器
大数据·人工智能·科技·ai·数字化转型
King.6241 小时前
SQL2API 核心理念:如何重构数据服务交付范式
大数据·开发语言·数据库·人工智能·sql·lua
孤蓬&听雨1 小时前
Axure高保真AI算法训练平台
人工智能·算法·ai·产品经理·axure·原型设计
Mechanotrooper1 小时前
Day08 【基于jieba分词实现词嵌入的文本多分类】
人工智能·自然语言处理·分类