OperableChatMemoryProvider.java
3.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package com.xly.config;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.data.message.ChatMessage;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
/**
* 可操作的ChatMemoryProvider:获取消息对象+清除记忆(指定/全量)+删除单条消息
* 实现框架原生接口,无缝对接AiServices,线程安全适配生产环境
*/
@Component
public class OperableChatMemoryProvider implements ChatMemoryProvider {
// 核心缓存:memoryId -> ChatMemory,保证一个会话/用户对应唯一记忆实例
private final Map<Object, ChatMemory> memoryCache = new ConcurrentHashMap<>();
// 记忆最大消息数,根据业务需求调整(原配置为10)
private static final int MAX_MESSAGE_SIZE = 100;
/**
* 框架原生方法:获取【当前memoryId对应的ChatMemory实例(含消息对象)】
* AiServices自动调用,也是手动操作记忆/消息的唯一入口
*/
@Override
public ChatMemory get(Object memoryId) {
// 空memoryId兜底,避免空指针
Object finalMemId = Objects.isNull(memoryId) ? "default_erp_chat_memory" : memoryId;
// 不存在则创建MessageWindowChatMemory,存在则复用
return memoryCache.computeIfAbsent(finalMemId, k -> MessageWindowChatMemory.withMaxMessages(MAX_MESSAGE_SIZE));
}
// ===================== 1. 获取消息对象(当前memoryId) =====================
/**
* 获取当前会话/用户的全部消息列表(含用户消息、AI消息,按对话顺序)
*/
public List<ChatMessage> getCurrentChatMessages(Object memoryId) {
if (Objects.isNull(memoryId)) {
return List.of();
}
// 从ChatMemory中获取原生消息列表
return this.get(memoryId).messages();
}
// ===================== 2. 清除记忆(核心需求) =====================
/**
* 清空【指定memoryId】的全部记忆(最常用,如前端「清空对话」)
*/
public void clearSpecifiedMemory(Object memoryId) {
if (Objects.nonNull(memoryId)) {
// 调用ChatMemory原生clear(),清空该实例所有消息
this.get(memoryId).clear();
}
}
/**
* 全量清除【所有memoryId】的记忆(系统级清理,如定时任务/后台操作)
*/
public void clearAllMemory() {
// 遍历所有记忆实例,逐个调用原生clear()清空
memoryCache.values().forEach(ChatMemory::clear);
// 可选:彻底清空缓存,销毁所有实例(释放内存,后续会重新创建)
// memoryCache.clear();
}
// ===================== 3. 精准操作:删除单条消息 =====================
/**
* 删除当前memoryId的指定单条消息(如删除错误消息)
* @param message 要删除的消息对象(从getCurrentChatMessages中获取)
*/
public void deleteSingleMessage(Object memoryId, ChatMessage message) {
if (Objects.nonNull(memoryId) && Objects.nonNull(message)) {
ChatMemory currentMemory = this.get(memoryId);
// 删除指定消息
currentMemory.messages().remove(message);
// 刷新记忆,保证MessageWindowChatMemory的最大消息数限制生效
// currentMemory.update(currentMemory.messages());
}
}
/**
* 移除并清除指定记忆(清空消息+从缓存删除实例,彻底释放资源,适用于过期会话)
*/
public void removeAndClearMemory(Object memoryId) {
if (Objects.nonNull(memoryId)) {
ChatMemory chatMemory = memoryCache.remove(memoryId);
if (Objects.nonNull(chatMemory)) {
chatMemory.clear();
}
}
}
}