【AI应用开发捷径之路】第七课:实现多轮对话记忆功能
2025-12-30 09:53:47
文章摘要
模型的“记忆”并非像人类那样长期、连贯地存储经历,而是一种在交互过程中临时保存、提取和利用信息的能力。其核心目标是让模型在单次对话或任务中保持上下文连贯性。
前言
大模型的“记忆”并非像人类那样长期、连贯地存储经历,而是一种在交互过程中临时保存、提取和利用信息的能力。其核心目标是让模型在单次对话或任务中保持上下文连贯性。
大模型的记忆能力取决于大模型支持的token长度如果你发送过多聊天记录,可能就会导致token过长,更多的token也意味更多的费用,更久的解析时间。所以不建议太长(DEFAULT_MAX_MESSAGES默认20即10次对话),一旦超出DEFAULT_MAX_MESSAGES 只会存最后面N条(可以理解为先进先出)。

在springAi中,如果需要修改对话次数,可以通过如下配置:
@TestConfiguration
static class Config {
ChatMemory chatMemory(ChatMemoryRepository chatMemoryRepository){
return MessageWindowChatMemory.builder()
.maxMessages(10) // 最多保存10条对话记录,先进先出的机制
.chatMemoryRepository(chatMemoryRepository)
.build();
}
}
SpringAI中实现记忆的交互图

一、简单的实现记忆功能
package com.example.base;
import cn.myeasyai.FaceApplication;
import org.junit.jupiter.api.Test;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.SafeGuardAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.deepseek.DeepSeekChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest(classes = FaceApplication.class)
public class TestMemory {
@Autowired
DeepSeekChatModel deepSeekChatModel;
@Test
public void testMemory() {
MessageWindowChatMemory chatMemory = MessageWindowChatMemory.builder().build();
String conversationId ="s1";//当前对话唯一标识
//第一轮对话
UserMessage userMessage = new UserMessage("我叫发哥");
chatMemory.add(conversationId, userMessage);
ChatResponse response1 = deepSeekChatModel.call(new Prompt(chatMemory.get(conversationId)));
chatMemory.add(conversationId, response1.getResult().getOutput());
//第二轮对话
UserMessage userMessage2 = new UserMessage("我叫什么名字");
chatMemory.add(conversationId, userMessage2);
ChatResponse response2 = deepSeekChatModel.call(new Prompt(chatMemory.get(conversationId)));
chatMemory.add(conversationId, response2.getResult().getOutput());
//输出响应结果
System.out.println(response2.getResult().getOutput().getText());
}
}
二、通过拦截器实现多轮对话记忆功能
添加依赖
<dependency>
<groupid>org.springframework.ai</groupid>
<artifactid>spring-ai-autoconfigure-model-chat-memory</artifactid>
</dependency>
测试类
package com.example.base;
import cn.myeasyai.FaceApplication;
import org.junit.jupiter.api.Test;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SafeGuardAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.deepseek.DeepSeekChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest(classes = FaceApplication.class)
public class TestMemory {
@Autowired
DeepSeekChatModel deepSeekChatModel;
@Test
public void testMemoryAdvisor( @Autowired ChatMemory chatMemory) {
ChatClient.Builder builder = ChatClient.builder(deepSeekChatModel);
ChatClient chatClient = builder.defaultAdvisors(
PromptChatMemoryAdvisor.builder(chatMemory) //在拦截器中加入一个记忆拦截器
.build())
.build();
String content = chatClient.prompt().user("我叫发哥").call().content();
System.out.println(content);
System.out.println("--------------------------------------------------------");
content = chatClient.prompt().user("我叫什么名字").call().content();
System.out.println(content);
}
}
三、测试多轮对话输出
下面代码中设置了只记忆一轮对话,可以看到:第四轮的对话中,第一轮的对话已经被遗忘;第三轮对话还能回答职业,是因为第二轮对话中问到了职业的原因,所以还保留着职业。
package com.example.base;
import cn.myeasyai.FaceApplication;
import org.junit.jupiter.api.Test;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemoryRepository;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.ai.deepseek.DeepSeekChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest(classes = FaceApplication.class)
public class TestMemory {
@Autowired
DeepSeekChatModel deepSeekChatModel;
@Autowired
private ChatMemoryRepository chatMemoryRepository;
@Test
public void testCustomMemory() {
MessageWindowChatMemory build = MessageWindowChatMemory.builder()
.maxMessages(1) // 保存1条消息
.chatMemoryRepository(chatMemoryRepository)
.build();
ChatClient.Builder builder = ChatClient.builder(deepSeekChatModel);
ChatClient chatClient = builder
.defaultAdvisors(
PromptChatMemoryAdvisor.builder(build)
.build()
)
.build();
// 测试对话
String content = chatClient.prompt()
.user("我叫张三,今年25岁,是一名软件工程师")
.call()
.content();
System.out.println("第一轮:" + content);
//第一轮:好的,张三!很高兴认识你。25岁的软件工程师,正是充满活力和潜力的年纪呢。
/**---------------------
---------------------
MEMORY:
---------------------
*/
content = chatClient.prompt()
.user("我的职业是什么?")
.call()
.content();
System.out.println("第二轮:" + content);
//第二轮:根据我们的对话记录,你之前提到过你的职业是**软件工程师**。
/**---------------------
---------------------
MEMORY:
ASSISTANT:好的,张三!很高兴认识你。25岁的软件工程师,正是充满活力和潜力的年纪呢。
请问有什么我可以帮你的吗?无论是技术问题、职业发展,还是日常生活中的疑问,我都很乐意为你提供帮助。
---------------------
*/
content = chatClient.prompt()
.user("我的职业是什么?")
.call()
.content();
System.out.println("第三轮:" + content);
//第三轮:根据我们的对话记录,你的职业是**软件工程师**。
/**---------------------
---------------------
MEMORY:
ASSISTANT:根据我们的对话记录,你之前提到过你的职业是**软件工程师**。
---------------------
*/
content = chatClient.prompt()
.user("我的名字是什么?")
.call()
.content();
System.out.println("第四轮:" + content);
//第四轮:根据我们的对话记录,目前没有提到你的名字。如果你愿意告诉我,我可以记住它并在后续对话中使用。
}
}
大模型的记忆功能正从完全依赖有限上下文窗口,向 “大上下文窗口 + 外部记忆系统”相结合的方向快速发展。其目标是实现更个性化、更连贯、更知情的交互体验
声明:该内容由作者自行发布,观点内容仅供参考,不代表平台立场;如有侵权,请联系平台删除。
标签:



