进行第一阶段的调试修复

- 修复了记忆系统中的空指针问题,原因:更新对话缓存计数时使用的经过裁剪的主题路径。
- 修复了切片评估无法正常执行的问题,原因:切片不存在前后序引用时,也试图获取前后序切片的摘要,此时应当抛出空指针异常,但由于任务以Callable<Void>提交,且未处于try-catch代码块内部,导致异常被“吞掉”
- 更新激活切片时将根据id获取到切片对应的消息列表
- 调整了README文件中的不准确描述
This commit is contained in:
2025-05-12 20:29:43 +08:00
parent f220854fd6
commit 68a38e9b51
3 changed files with 32 additions and 123 deletions

116
README.md
View File

@@ -6,7 +6,7 @@
### 结构化记忆系统 ### 结构化记忆系统
> 构建以**主题树+记忆切片**为基础的记忆图谱。 > 构建以**主题树+记忆切片**为基础的记忆图谱。
单个主题节点下存在多级子主题。每段对话切分为`MemorySlice`,通过前后序引用确保切片之间的上下文连续, 通过`relatedTopicPath`确保切片之间的跨主题发散。同一天的所有切片将聚合为`MemoryNode`(记忆节点)的形式挂载到主题节点。除此之外,每个记忆节点还将按照日期进行索引。 单个主题节点下存在多级子主题。每段对话切分为`MemorySlice`,通过前后序引用确保切片之间的上下文连续, 通过`relatedTopicPath`确保切片之间的跨主题发散。切片将聚合为`MemoryNode`(记忆节点)的形式挂载到主题节点。除此之外,每个记忆节点还将按照日期进行索引。
### 多用户会话管理 ### 多用户会话管理
> 构建区分用户的单上下文窗口、多用户会话的管理机制 > 构建区分用户的单上下文窗口、多用户会话的管理机制
@@ -42,117 +42,3 @@
### 长期规划 ### 长期规划
- [ ] 实现角色演进机制 - [ ] 实现角色演进机制
- [ ] 实现任务调度模块(主动调度、意图推断、定时调度) - [ ] 实现任务调度模块(主动调度、意图推断、定时调度)
## 目录结构
```
main
├── java
│ └── work
│ └── slhaf
│ ├── agent
│ │ ├── Agent.java
│ │ ├── common
│ │ │ ├── chat
│ │ │ │ ├── ChatClient.java
│ │ │ │ ├── constant
│ │ │ │ │ └── ChatConstant.java
│ │ │ │ └── pojo
│ │ │ │ ├── ChatBody.java
│ │ │ │ ├── ChatResponse.java
│ │ │ │ ├── Message.java
│ │ │ │ ├── MetaMessage.java
│ │ │ │ └── PrimaryChatResponse.java
│ │ │ ├── config
│ │ │ │ ├── Config.java
│ │ │ │ ├── ModelConfig.java
│ │ │ │ ├── ModuleConfig.java
│ │ │ │ └── WebSocketConfig.java
│ │ │ ├── model
│ │ │ │ ├── ModelConstant.java
│ │ │ │ └── Model.java
│ │ │ ├── monitor
│ │ │ │ └── DebugMonitor.java
│ │ │ ├── pojo
│ │ │ │ └── PersistableObject.java
│ │ │ └── util
│ │ │ └── ExtractUtil.java
│ │ ├── core
│ │ │ ├── interaction
│ │ │ │ ├── data
│ │ │ │ │ ├── InteractionContext.java
│ │ │ │ │ ├── InteractionInputData.java
│ │ │ │ │ └── InteractionOutputData.java
│ │ │ │ ├── InputReceiver.java
│ │ │ │ ├── InteractionModule.java
│ │ │ │ ├── InteractionModulesLoader.java
│ │ │ │ ├── InteractionThreadPoolExecutor.java
│ │ │ │ └── TaskCallback.java
│ │ │ ├── InteractionHub.java
│ │ │ ├── memory
│ │ │ │ ├── exception
│ │ │ │ │ ├── NullSliceListException.java
│ │ │ │ │ ├── UnExistedDateIndexException.java
│ │ │ │ │ └── UnExistedTopicException.java
│ │ │ │ ├── MemoryGraph.java
│ │ │ │ ├── MemoryManager.java
│ │ │ │ ├── node
│ │ │ │ │ ├── MemoryNode.java
│ │ │ │ │ └── TopicNode.java
│ │ │ │ └── pojo
│ │ │ │ ├── MemoryResult.java
│ │ │ │ ├── MemorySlice.java
│ │ │ │ ├── MemorySliceResult.java
│ │ │ │ └── User.java
│ │ │ ├── module
│ │ │ │ └── CoreModel.java
│ │ │ └── session
│ │ │ └── SessionManager.java
│ │ ├── gateway
│ │ │ ├── AgentWebSocketServer.java
│ │ │ └── MessageSender.java
│ │ ├── modules
│ │ │ ├── memory
│ │ │ │ ├── selector
│ │ │ │ │ ├── evaluator
│ │ │ │ │ │ ├── data
│ │ │ │ │ │ │ ├── EvaluatorBatchInput.java
│ │ │ │ │ │ │ ├── EvaluatorInput.java
│ │ │ │ │ │ │ ├── EvaluatorResult.java
│ │ │ │ │ │ │ └── SliceSummary.java
│ │ │ │ │ │ └── SliceSelectEvaluator.java
│ │ │ │ │ ├── extractor
│ │ │ │ │ │ ├── data
│ │ │ │ │ │ │ ├── ExtractorInput.java
│ │ │ │ │ │ │ ├── ExtractorMatchData.java
│ │ │ │ │ │ │ └── ExtractorResult.java
│ │ │ │ │ │ └── MemorySelectExtractor.java
│ │ │ │ │ └── MemorySelector.java
│ │ │ │ └── updater
│ │ │ │ ├── MemoryUpdater.java
│ │ │ │ ├── static_extractor
│ │ │ │ │ ├── data
│ │ │ │ │ │ └── StaticMemoryExtractInput.java
│ │ │ │ │ └── StaticMemoryExtractor.java
│ │ │ │ └── summarizer
│ │ │ │ ├── data
│ │ │ │ │ ├── SummarizeInput.java
│ │ │ │ │ └── SummarizeResult.java
│ │ │ │ └── MemorySummarizer.java
│ │ │ ├── preprocess
│ │ │ │ └── PreprocessExecutor.java
│ │ │ ├── task
│ │ │ │ ├── data
│ │ │ │ │ └── TaskData.java
│ │ │ │ ├── TaskEvaluator.java
│ │ │ │ ├── TaskExecutor.java
│ │ │ │ └── TaskScheduler.java
│ │ │ └── topic
│ │ └── shared
│ │ └── memory
│ │ └── EvaluatedSlice.java
│ └── Main.java
└── resources
└── logback.xml
```

View File

@@ -353,7 +353,7 @@ public class MemoryGraph extends PersistableObject {
//每日刷新缓存 //每日刷新缓存
checkCacheDate(); checkCacheDate();
//检测缓存并更新计数, 查看是否需要放入缓存 //检测缓存并更新计数, 查看是否需要放入缓存
updateCacheCounter(path); updateCacheCounter(topicPath);
//查看是否存在缓存,如果存在,则直接返回 //查看是否存在缓存,如果存在,则直接返回
if (memorySliceCache.containsKey(path)) { if (memorySliceCache.containsKey(path)) {
return memorySliceCache.get(path); return memorySliceCache.get(path);

View File

@@ -71,8 +71,8 @@ public class SliceSelectEvaluator extends Model {
List<SliceSummary> sliceSummaryList = new ArrayList<>(); List<SliceSummary> sliceSummaryList = new ArrayList<>();
//映射查找键值 //映射查找键值
Map<Long, SliceSummary> map = new HashMap<>(); Map<Long, SliceSummary> map = new HashMap<>();
setSliceSummaryList(memoryResult, sliceSummaryList, map);
try { try {
setSliceSummaryList(memoryResult, sliceSummaryList, map);
EvaluatorBatchInput batchInput = EvaluatorBatchInput.builder() EvaluatorBatchInput batchInput = EvaluatorBatchInput.builder()
.text(evaluatorInput.getInput()) .text(evaluatorInput.getInput())
.memory_slices(sliceSummaryList) .memory_slices(sliceSummaryList)
@@ -87,6 +87,7 @@ public class SliceSelectEvaluator extends Model {
.summary(sliceSummary.getSummary()) .summary(sliceSummary.getSummary())
.date(sliceSummary.getDate()) .date(sliceSummary.getDate())
.build(); .build();
setEvaluatedSliceMessages(evaluatedSlice, memoryResult, sliceSummary.getId());
queue.offer(evaluatedSlice); queue.offer(evaluatedSlice);
} }
} catch (Exception e) { } catch (Exception e) {
@@ -101,17 +102,39 @@ public class SliceSelectEvaluator extends Model {
return queue.stream().toList(); return queue.stream().toList();
} }
private void setEvaluatedSliceMessages(EvaluatedSlice evaluatedSlice, MemoryResult memoryResult, Long id) {
//补充消息列表
for (MemorySliceResult memorySliceResult : memoryResult.getMemorySliceResult()) {
if (memorySliceResult.getMemorySlice().getTimestamp().equals(id)) {
evaluatedSlice.setChatMessages(memorySliceResult.getMemorySlice().getChatMessages());
return;
}
}
for (MemorySlice memorySlice : memoryResult.getRelatedMemorySliceResult()) {
if (memorySlice.getTimestamp().equals(id)) {
evaluatedSlice.setChatMessages(memorySlice.getChatMessages());
return;
}
}
}
private void setSliceSummaryList(MemoryResult memoryResult, List<SliceSummary> sliceSummaryList, Map<Long, SliceSummary> map) { private void setSliceSummaryList(MemoryResult memoryResult, List<SliceSummary> sliceSummaryList, Map<Long, SliceSummary> map) {
for (MemorySliceResult memorySliceResult : memoryResult.getMemorySliceResult()) { for (MemorySliceResult memorySliceResult : memoryResult.getMemorySliceResult()) {
SliceSummary sliceSummary = new SliceSummary(); SliceSummary sliceSummary = new SliceSummary();
sliceSummary.setId(memorySliceResult.getMemorySlice().getTimestamp()); sliceSummary.setId(memorySliceResult.getMemorySlice().getTimestamp());
String stringBuilder = memorySliceResult.getSliceBefore().getSummary() + StringBuilder stringBuilder = new StringBuilder();
"\r\n" + if (memorySliceResult.getSliceBefore() != null) {
memorySliceResult.getMemorySlice().getSummary() + stringBuilder.append(memorySliceResult.getSliceBefore().getSummary())
"\r\n" + .append("\r\n");
memorySliceResult.getSliceAfter().getSummary(); }
sliceSummary.setSummary(stringBuilder); stringBuilder.append(memorySliceResult.getMemorySlice().getSummary());
if (memorySliceResult.getSliceAfter() != null) {
stringBuilder.append("\r\n")
.append(memorySliceResult.getSliceAfter().getSummary())
.append("\r\n");
}
sliceSummary.setSummary(stringBuilder.toString());
Long timestamp = memorySliceResult.getMemorySlice().getTimestamp(); Long timestamp = memorySliceResult.getMemorySlice().getTimestamp();
sliceSummary.setDate(DateUtil.date(timestamp).toLocalDateTime().toLocalDate()); sliceSummary.setDate(DateUtil.date(timestamp).toLocalDateTime().toLocalDate());