AI大模型进阶系列(02)基于Spring AI实现AI chatbot助理|一句话让deepseek实现

本文涉及的产品
多模态交互后付费免费试用,全链路、全Agent
简介: 本文介绍了通过DeepSeek生成一个基于Spring AI的在线AI聊天助手项目的全过程。项目采用JDK17+Spring AI+Thymeleaf+Spring Web技术栈,实现了一个简单的聊天界面,用户可输入内容并获得DeepSeek返回的结果。文章详细描述了从需求明确、项目结构设计到配置参数启动的步骤,并展示了核心代码片段如pom.xml、application.properties及主要Java类文件。尽管功能简单,但体现了AI在编程领域的高效应用,未来有望进一步优化上下文记忆等功能,提升开发体验与效率。

最近美国向全球加征关税,对全球经济贸易产生巨大影响,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已经集成支持目前主流的各种大模型还有AI实践框架技术。我们熟悉的RAG、MCP、prompts、语音、图片、视频、向量数据库、AI大模型基本都及时集成支持,方便大家应用到系统实践。

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

【你是一个java研发人员,现在有一个Springboot项目需要你去完整实现,主要通过集成Spring ai 和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相关的两个参数配置进去。

      deepseek.api.key=your-deepseek-api-key

      deepseek.api.url=https://api.deepseek.com/v1/chat/completions

然后启动 Springboot 应用程序,访问localhost:8080就可以访问。

五、最终demo实例

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

六、总结和展望

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

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

七、项目源码

7.1 pom.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

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

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

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


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


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


<!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/bootstrap@5.3.0/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/bootstrap@5.3.0/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>
相关文章
|
8天前
|
人工智能 IDE 开发工具
CodeGPT AI代码狂潮来袭!个人完全免费使用谷歌Gemini大模型 超越DeepSeek几乎是地表最强
CodeGPT是一款基于AI的编程辅助插件,支持代码生成、优化、错误分析和单元测试,兼容多种大模型如Gemini 2.0和Qwen2.5 Coder。免费开放,适配PyCharm等IDE,助力开发者提升效率,新手友好,老手提效利器。(238字)
95 1
CodeGPT AI代码狂潮来袭!个人完全免费使用谷歌Gemini大模型 超越DeepSeek几乎是地表最强
|
11天前
|
人工智能 Java 机器人
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
Spring AI Alibaba集成Ollama,基于Java构建本地大模型应用,支持流式对话、knife4j接口可视化,实现高隐私、免API密钥的离线AI服务。
245 1
基于Spring AI Alibaba + Spring Boot + Ollama搭建本地AI对话机器人API
|
11天前
|
人工智能 Java 数据库
Spring AI
Spring AI 为 Java 生态注入智能,提供统一抽象接口,简化大模型集成,助力开发者高效构建 AI 应用,推动企业智能化转型。
|
11天前
|
人工智能 安全
用DeepSeek当工作伙伴:解决文案卡壳、问题拆解,让AI帮你省时间
本文介绍了如何利用DeepSeek提升工作效率。重点分享了5个高频工作场景的应用:1)快速处理文档提炼;2)突破创意卡壳;3)拆解复杂问题;4)快速学习专业知识;5)优化商务表达。同时提供了3个实用技巧:整理实际信息、优化提示词、学会追问补充。最后强调DeepSeek的核心价值在于解放精力,让用户专注于更具创造性和判断力的工作。通过合理使用,可显著提升工作效率和思维质量。
49 0
|
29天前
|
JSON 人工智能 Java
基于Spring AI构建智能Text-to-SQL转换器:一个完整的MCP
Spring AI 更新结构化输出转换器,弃用旧版 Parser 类,引入与 Spring 框架对齐的 Converter 体系,提升命名规范与功能兼容性。新版本支持 JSON、XML 及 Java 对象转换,确保 LLM 输出结构化,便于下游应用处理。
|
1月前
|
人工智能 自然语言处理 Java
从青铜到王者,DeepSeek+Spring AI 搭建 RAG 知识库
本文介绍了基于RAG(检索增强生成)技术构建知识库的原理与实现方法。RAG通过结合检索与生成模型,提升大语言模型在问答任务中的准确性与相关性,有效缓解“幻觉”问题。文章还详细讲解了如何利用DeepSeek与SpringAI搭建高效RAG系统,并提供了完整的Java代码示例,帮助开发者快速实现文档处理、向量存储与智能问答功能。适用于智能客服、内容生成、辅助决策等多个场景。
413 2
|
1月前
|
人工智能 Java 开发者
邀您参与 “直通乌镇” Spring AI Alibaba 开源竞技挑战赛!
邀您参与 “直通乌镇” Spring AI Alibaba 开源竞技挑战赛!
|
5天前
|
边缘计算 人工智能 算法
AI在智慧能源管理中的边缘计算应用
AI在智慧能源管理中的边缘计算应用
58 13
|
5天前
|
人工智能 Cloud Native 中间件
划重点|云栖大会「AI 原生应用架构论坛」看点梳理
本场论坛将系统性阐述 AI 原生应用架构的新范式、演进趋势与技术突破,并分享来自真实生产环境下的一线实践经验与思考。