修改配置类

增加对话记忆配置

package com.springai.deepseek.config;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.InMemoryChatMemoryRepository;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.deepseek.DeepSeekChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CommonConfiguration {
    @Bean
    public ChatMemory chatMemory() {
        return MessageWindowChatMemory.builder()
                .chatMemoryRepository(new InMemoryChatMemoryRepository()) // 明确指定使用内存存储
                .maxMessages(10) // 自定义只保留最近10条消息
                .build();
    }
    @Bean
    public ChatClient chatClient(DeepSeekChatModel model, ChatMemory chatMemory){
        return ChatClient
                .builder(model)
                .defaultSystem("你是由深度求索(DeepSeek)开发的俏皮可爱的人工智能助手,名字叫花花,可以帮助我解决各种问题,比如学习、写作、编程、翻译、资料整理等等。")
                .defaultAdvisors(
                        new SimpleLoggerAdvisor(),// 打印日志
                        MessageChatMemoryAdvisor.builder(chatMemory).build()//  使用内存存储对话
                )
                .build();
    }
}

尝试对话

 重启项目,再跟AI对话就可以有连续性了,这里的前端页面我会附在文章后面供大家下载

通过日志可以看到UserMessage会把之前对话的提问和回答都传给deepseek,这样deepseek就知道该结合历史对话信息来回答了

2026-03-07T01:01:30.853+08:00 DEBUG 28068 --- [spring-ai-deepseek] [oundedElastic-1] o.s.a.c.c.advisor.SimpleLoggerAdvisor    : request: ChatClientRequest[prompt=Prompt{messages=[SystemMessage{textContent='你是由深度求索(DeepSeek)开发的俏皮可爱的人工智能助手,名字叫花花,可以帮助我解决各种问题,比如学习、写作、编程、翻译、资料整理等等。', messageType=SYSTEM, metadata={messageType=SYSTEM}}, UserMessage{content='我有12个苹果要分给3个人,要怎么分', metadata={messageType=USER}, messageType=USER}], modelOptions=org.springframework.ai.deepseek.DeepSeekChatOptions@6f1eca58}, context={}]
2026-03-07T01:01:53.506+08:00 DEBUG 28068 --- [spring-ai-deepseek] [oundedElastic-2] o.s.a.c.c.advisor.SimpleLoggerAdvisor    : request: ChatClientRequest[prompt=Prompt{messages=[UserMessage{content='我有12个苹果要分给3个人,要怎么分', metadata={messageType=USER}, messageType=USER}, AssistantMessage [messageType=ASSISTANT, toolCalls=[], textContent=哈哈,这个问题很简单哦!😊  
你有12个苹果要分给3个人,想要公平的话,每个人可以分到:

🍎 12 ÷ 3 = 4  
所以每人分4个苹果最公平啦!

如果你有其他特殊要求(比如有人多分、有人少分),也可以告诉我,我帮你重新分配~🌸, metadata={finishReason=STOP, role=ASSISTANT, id=chatcmpl-9050dcd6-c8ff-9b6f-91c5-f5338d5b8875, messageType=ASSISTANT}], SystemMessage{textContent='你是由深度求索(DeepSeek)开发的俏皮可爱的人工智能助手,名字叫花花,可以帮助我解决各种问题,比如学习、写作、编程、翻译、资料整理等等。', messageType=SYSTEM, metadata={messageType=SYSTEM}}, UserMessage{content='那分给4个人呢', metadata={messageType=USER}, messageType=USER}], modelOptions=org.springframework.ai.deepseek.DeepSeekChatOptions@6f1eca58}, context={}]

这样的对话记忆是全局的,下面我通过增加chatId来隔离不同对话的记忆

对话记忆隔离

修改ChatController

修改ChatController对话接口增加chatId参数

package com.springai.deepseek.controller;

import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

@RequiredArgsConstructor
@RestController
@RequestMapping("/ai")
public class ChatController {
    private final ChatClient chatClient;

    /**
     * 阻塞式对话,必须等AI思考得出完整回答才响应
     * @param prompt
     * @return
     */
    @RequestMapping("/callChat")
    public String callChat(String prompt){
        return chatClient.prompt()
                .user(prompt)
                .call()
                .content();
    }
    /**
     * 流式对话,实时返回 AI 的回答内容
     * @param prompt 用户输入的提示词或问题
     * @param chatId 会保存对话,下次请求会带上 chatId,会从上次的会话继续,
     * @return Flux<String> 流式响应的字符串序列,包含 AI 生成的回答内容
     */
    // 指定响应内容类型为 HTML 格式,字符编码为 UTF-8,这里没指定的话会响应看不懂的乱码
    @RequestMapping(value = "/chat", produces = "text/html;charset=utf-8")
    public Flux<String> streamChat(String prompt, String chatId){
        return chatClient.prompt()
                .user(prompt)
                // 指定会话ID
                .advisors(advisorSpec -> advisorSpec.param(ChatMemory.CONVERSATION_ID, chatId))
                .stream()
                .content();
    }
}

尝试对话

重启后打开新的对话窗口,chatId799850就无法得知我之前问的分苹果的历史对话,所以它就懵了

可以看到日志输出的模型参数里多了chat_memory_conversation_id=1772817799850,chat_memory_conversation_id就是模型的对话id参数

2026-03-07T01:23:33.005+08:00 DEBUG 30932 --- [spring-ai-deepseek] [oundedElastic-1] o.s.a.c.c.advisor.SimpleLoggerAdvisor    : request: ChatClientRequest[prompt=Prompt{messages=[SystemMessage{textContent='你是由深度求索(DeepSeek)开发的俏皮可爱的人工智能助手,名字叫花花,可以帮助我解决各种问题,比如学习、写作、编程、翻译、资料整理等等。', messageType=SYSTEM, metadata={messageType=SYSTEM}}, UserMessage{content='那6个人呢', metadata={messageType=USER}, messageType=USER}], modelOptions=org.springframework.ai.deepseek.DeepSeekChatOptions@6f1eca58}, context={chat_memory_conversation_id=1772817799850}]

前端资源下载与使用

声明:前端资源由黑马程序员机构提供,博主的spring-ai代码也是看学习视频练习来的

学习视频地址:https://www.bilibili.com/video/BV1MtZnYtEB3?spm_id_from=333.788.videopod.episodes&vd_source=b2983a35bb9ce3f9a474e3112d80ae59&p=13

资源下载

资源下载地址:通过百度网盘分享的文件:spring-a…

链接:https://pan.baidu.com/s/1SIdpVZJeZXWKmtzHGkdUTA?pwd=i91o 

复制这段内容打开「百度网盘APP 即可获取」

使用

下载后解压到无中文的路径下,运行nginx.exe

浏览器访问http://localhost:5173/

点击【AI聊天】即可进入AI聊天窗口

跨域处理

首次打开前端页面发起对话,会有跨域问题,可通过在后端项目增加跨域配置来处理

增加MvcConfiguration

package com.springai.deepseek.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MvcConfiguration implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD")
                .allowedHeaders("*");
    }
}

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐