mirror of
https://github.com/slhaf/Partner.git
synced 2026-05-12 08:43:02 +08:00
完善全局异常处理,在必要处将进行快照保存。后续建议通过readExceptionState读取保存的异常快照
This commit is contained in:
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
## 规划
|
## 规划
|
||||||
|
|
||||||
- [ ] 实现全局异常捕获,并对异常发生时的状态(主要是流转上下文`InteractionContext`、`SessionManager`、`MemoryGraph`)进行快照保存,方便后续问题排查。
|
- [ ] 抽取提示词到resources文件夹中
|
||||||
- [ ] 发现通过用户引导可以使得LLM展现出一定的“自我认知”,尽管仍是语义推理,但对于Partner应当足够,这一点尽量应用到各个模块中。
|
- [ ] 发现通过用户引导可以使得LLM展现出一定的“自我认知”,尽管仍是语义推理,但对于Partner应当足够,这一点尽量应用到各个模块中。
|
||||||
- [ ] 当前主模型对于对话缓存中的记忆有些‘过度回应’,`MemorySelector`处的动态提示词或需要进一步调整。
|
- [ ] 当前主模型对于对话缓存中的记忆有些‘过度回应’,`MemorySelector`处的动态提示词或需要进一步调整。
|
||||||
- [ ] 实现身份感知模块(用户识别、熟悉度判断、记忆片段检索、人物画像、对话口吻调整)。
|
- [ ] 实现身份感知模块(用户识别、熟悉度判断、记忆片段检索、人物画像、对话口吻调整)。
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
package work.slhaf.agent.common.exception_handler;
|
package work.slhaf.agent.common.exception_handler;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import work.slhaf.agent.common.exception_handler.pojo.GlobalException;
|
||||||
import work.slhaf.agent.common.exception_handler.pojo.GlobalExceptionData;
|
import work.slhaf.agent.common.exception_handler.pojo.GlobalExceptionData;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.*;
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.ObjectOutputStream;
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
@@ -15,7 +13,8 @@ public class GlobalExceptionHandler {
|
|||||||
|
|
||||||
private static final String EXCEPTION_STATIC_PATH = "./data/exception_snapshot/";
|
private static final String EXCEPTION_STATIC_PATH = "./data/exception_snapshot/";
|
||||||
|
|
||||||
public static void writeExceptionState(GlobalExceptionData exceptionData) {
|
public static void writeExceptionState(GlobalException exception) {
|
||||||
|
GlobalExceptionData exceptionData = exception.getData();
|
||||||
Path filePath = Paths.get(EXCEPTION_STATIC_PATH, String.valueOf(exceptionData.getExceptionTime()), ".dat");
|
Path filePath = Paths.get(EXCEPTION_STATIC_PATH, String.valueOf(exceptionData.getExceptionTime()), ".dat");
|
||||||
try {
|
try {
|
||||||
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath.toFile()));
|
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath.toFile()));
|
||||||
@@ -26,4 +25,17 @@ public class GlobalExceptionHandler {
|
|||||||
log.error("[GlobalExceptionHandler] 捕获异常, 保存失败: ", e);
|
log.error("[GlobalExceptionHandler] 捕获异常, 保存失败: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static GlobalExceptionData readExceptionState(String filePath) {
|
||||||
|
try {
|
||||||
|
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
|
||||||
|
GlobalExceptionData exceptionData = (GlobalExceptionData) ois.readObject();
|
||||||
|
ois.close();
|
||||||
|
log.info("[GlobalExceptionHandler] 已从: {} 读取异常快照", filePath);
|
||||||
|
return exceptionData;
|
||||||
|
} catch (IOException | ClassNotFoundException e) {
|
||||||
|
log.error("[GlobalExceptionHandler] 读取异常, 读取失败: ", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class InteractionHub {
|
|||||||
interactionModule.execute(interactionContext);
|
interactionModule.execute(interactionContext);
|
||||||
}
|
}
|
||||||
} catch (GlobalException e) {
|
} catch (GlobalException e) {
|
||||||
GlobalExceptionHandler.writeExceptionState(e.getData());
|
GlobalExceptionHandler.writeExceptionState(e);
|
||||||
interactionContext.getCoreResponse().put("text", "[ERROR] " + e.getMessage());
|
interactionContext.getCoreResponse().put("text", "[ERROR] " + e.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
callback.onTaskFinished(interactionContext.getUserInfo(), interactionContext.getCoreResponse().getString("text"));
|
callback.onTaskFinished(interactionContext.getUserInfo(), interactionContext.getCoreResponse().getString("text"));
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import lombok.EqualsAndHashCode;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import work.slhaf.agent.common.chat.pojo.Message;
|
import work.slhaf.agent.common.chat.pojo.Message;
|
||||||
|
import work.slhaf.agent.common.exception_handler.GlobalExceptionHandler;
|
||||||
import work.slhaf.agent.common.exception_handler.pojo.GlobalException;
|
import work.slhaf.agent.common.exception_handler.pojo.GlobalException;
|
||||||
import work.slhaf.agent.common.pojo.PersistableObject;
|
import work.slhaf.agent.common.pojo.PersistableObject;
|
||||||
import work.slhaf.agent.core.memory.exception.UnExistedDateIndexException;
|
import work.slhaf.agent.core.memory.exception.UnExistedDateIndexException;
|
||||||
@@ -198,18 +199,17 @@ public class MemoryGraph extends PersistableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void insertMemory(List<String> topicPath, MemorySlice slice) throws IOException, ClassNotFoundException {
|
public void insertMemory(List<String> topicPath, MemorySlice slice) throws IOException, ClassNotFoundException {
|
||||||
|
|
||||||
|
try {
|
||||||
//检查是否存在当天对应的memorySlice并确定是否插入
|
//检查是否存在当天对应的memorySlice并确定是否插入
|
||||||
LocalDate now = LocalDate.now();
|
LocalDate now = LocalDate.now();
|
||||||
boolean hasSlice = false;
|
boolean hasSlice = false;
|
||||||
MemoryNode node = null;
|
MemoryNode node = null;
|
||||||
TopicNode lastTopicNode;
|
|
||||||
try {
|
|
||||||
//每日刷新缓存
|
//每日刷新缓存
|
||||||
checkCacheDate();
|
checkCacheDate();
|
||||||
//如果topicPath在memorySliceCache中存在对应缓存,由于进行的插入操作,则需要移除该缓存,但不清除相关计数
|
//如果topicPath在memorySliceCache中存在对应缓存,由于进行的插入操作,则需要移除该缓存,但不清除相关计数
|
||||||
memorySliceCache.remove(topicPath);
|
memorySliceCache.remove(topicPath);
|
||||||
lastTopicNode = generateTopicPath(topicPath);
|
TopicNode lastTopicNode = generateTopicPath(topicPath);
|
||||||
|
|
||||||
for (MemoryNode memoryNode : lastTopicNode.getMemoryNodes()) {
|
for (MemoryNode memoryNode : lastTopicNode.getMemoryNodes()) {
|
||||||
if (now.equals(memoryNode.getLocalDate())) {
|
if (now.equals(memoryNode.getLocalDate())) {
|
||||||
hasSlice = true;
|
hasSlice = true;
|
||||||
@@ -217,10 +217,6 @@ public class MemoryGraph extends PersistableObject {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("插入记忆时出错: ", e);
|
|
||||||
throw new GlobalException(e.getLocalizedMessage());
|
|
||||||
}
|
|
||||||
if (!hasSlice) {
|
if (!hasSlice) {
|
||||||
node = new MemoryNode();
|
node = new MemoryNode();
|
||||||
node.setLocalDate(now);
|
node.setLocalDate(now);
|
||||||
@@ -243,6 +239,10 @@ public class MemoryGraph extends PersistableObject {
|
|||||||
updateUserDialogMap(slice);
|
updateUserDialogMap(slice);
|
||||||
}
|
}
|
||||||
node.saveMemorySliceList();
|
node.saveMemorySliceList();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("插入记忆时出错: ", e);
|
||||||
|
GlobalExceptionHandler.writeExceptionState(new GlobalException("插入记忆时出错: " + e.getLocalizedMessage()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateDateIndex(MemorySlice slice) {
|
private void updateDateIndex(MemorySlice slice) {
|
||||||
@@ -407,6 +407,7 @@ public class MemoryGraph extends PersistableObject {
|
|||||||
memoryResult = new MemoryResult();
|
memoryResult = new MemoryResult();
|
||||||
memoryResult.setRelatedMemorySliceResult(new ArrayList<>());
|
memoryResult.setRelatedMemorySliceResult(new ArrayList<>());
|
||||||
memoryResult.setMemorySliceResult(new CopyOnWriteArrayList<>());
|
memoryResult.setMemorySliceResult(new CopyOnWriteArrayList<>());
|
||||||
|
GlobalExceptionHandler.writeExceptionState(new GlobalException(e.getLocalizedMessage()));
|
||||||
}
|
}
|
||||||
return memoryResult;
|
return memoryResult;
|
||||||
}
|
}
|
||||||
@@ -532,7 +533,6 @@ public class MemoryGraph extends PersistableObject {
|
|||||||
|
|
||||||
public void updateDialogMap(LocalDateTime dateTime, String newDialogCache) {
|
public void updateDialogMap(LocalDateTime dateTime, String newDialogCache) {
|
||||||
List<LocalDateTime> keysToRemove = new ArrayList<>();
|
List<LocalDateTime> keysToRemove = new ArrayList<>();
|
||||||
|
|
||||||
dialogMap.forEach((k, v) -> {
|
dialogMap.forEach((k, v) -> {
|
||||||
if (dateTime.minusDays(2).isAfter(k)) {
|
if (dateTime.minusDays(2).isAfter(k)) {
|
||||||
keysToRemove.add(k);
|
keysToRemove.add(k);
|
||||||
@@ -544,7 +544,6 @@ public class MemoryGraph extends PersistableObject {
|
|||||||
keysToRemove.clear();
|
keysToRemove.clear();
|
||||||
//放入新缓存
|
//放入新缓存
|
||||||
dialogMap.put(dateTime, newDialogCache);
|
dialogMap.put(dateTime, newDialogCache);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package work.slhaf.agent.modules.memory.selector;
|
|||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import work.slhaf.agent.common.exception_handler.GlobalExceptionHandler;
|
||||||
|
import work.slhaf.agent.common.exception_handler.pojo.GlobalException;
|
||||||
import work.slhaf.agent.core.interaction.InteractionModule;
|
import work.slhaf.agent.core.interaction.InteractionModule;
|
||||||
import work.slhaf.agent.core.interaction.data.InteractionContext;
|
import work.slhaf.agent.core.interaction.data.InteractionContext;
|
||||||
import work.slhaf.agent.core.memory.MemoryManager;
|
import work.slhaf.agent.core.memory.MemoryManager;
|
||||||
@@ -131,7 +133,8 @@ public class MemorySelector implements InteractionModule {
|
|||||||
if (memoryResult == null) continue;
|
if (memoryResult == null) continue;
|
||||||
memoryResultList.add(memoryResult);
|
memoryResultList.add(memoryResult);
|
||||||
} catch (UnExistedDateIndexException | UnExistedTopicException e) {
|
} catch (UnExistedDateIndexException | UnExistedTopicException e) {
|
||||||
log.error("[MemorySelector] 不存在的记忆索引! 请尝试更换更合适的主题提取LLM!");
|
log.error("[MemorySelector] 不存在的记忆索引! 请尝试更换更合适的主题提取LLM!", e);
|
||||||
|
GlobalExceptionHandler.writeExceptionState(new GlobalException(e.getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//清理切片记录
|
//清理切片记录
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import work.slhaf.agent.common.chat.pojo.Message;
|
import work.slhaf.agent.common.chat.pojo.Message;
|
||||||
import work.slhaf.agent.common.chat.pojo.MetaMessage;
|
import work.slhaf.agent.common.chat.pojo.MetaMessage;
|
||||||
import work.slhaf.agent.common.config.Config;
|
import work.slhaf.agent.common.config.Config;
|
||||||
|
import work.slhaf.agent.common.exception_handler.GlobalExceptionHandler;
|
||||||
|
import work.slhaf.agent.common.exception_handler.pojo.GlobalException;
|
||||||
import work.slhaf.agent.common.model.Model;
|
import work.slhaf.agent.common.model.Model;
|
||||||
import work.slhaf.agent.common.model.ModelConstant;
|
import work.slhaf.agent.common.model.ModelConstant;
|
||||||
import work.slhaf.agent.core.interaction.data.InteractionContext;
|
import work.slhaf.agent.core.interaction.data.InteractionContext;
|
||||||
@@ -77,7 +79,8 @@ public class MemorySelectExtractor extends Model {
|
|||||||
extractorResult = JSONObject.parseObject(responseStr, ExtractorResult.class);
|
extractorResult = JSONObject.parseObject(responseStr, ExtractorResult.class);
|
||||||
log.debug("[MemorySelectExtractor] 主题提取结果: {}",extractorResult);
|
log.debug("[MemorySelectExtractor] 主题提取结果: {}",extractorResult);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("[MemorySelectExtractor] 主题提取出错: {}", e.getLocalizedMessage());
|
log.error("[MemorySelectExtractor] 主题提取出错: ", e);
|
||||||
|
GlobalExceptionHandler.writeExceptionState(new GlobalException(e.getLocalizedMessage()));
|
||||||
extractorResult = new ExtractorResult();
|
extractorResult = new ExtractorResult();
|
||||||
extractorResult.setRecall(false);
|
extractorResult.setRecall(false);
|
||||||
extractorResult.setMatches(List.of());
|
extractorResult.setMatches(List.of());
|
||||||
@@ -85,10 +88,4 @@ public class MemorySelectExtractor extends Model {
|
|||||||
return extractorResult;
|
return extractorResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Constant {
|
|
||||||
public static final String NONE = "none";
|
|
||||||
public static final String DATE = "date";
|
|
||||||
public static final String TOPIC = "topic";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ public class MemoryUpdater implements InteractionModule {
|
|||||||
log.debug("[MemoryUpdater] 记忆切片数量 [{}]",recallCount);
|
log.debug("[MemoryUpdater] 记忆切片数量 [{}]",recallCount);
|
||||||
tokenLimit += recallCount * TOKEN_PER_RECALL;
|
tokenLimit += recallCount * TOKEN_PER_RECALL;
|
||||||
}
|
}
|
||||||
|
//TODO 调整为根据轮次触发记忆插入
|
||||||
if (moduleContext.getIntValue("total_token") > tokenLimit) {
|
if (moduleContext.getIntValue("total_token") > tokenLimit) {
|
||||||
try {
|
try {
|
||||||
log.debug("[MemoryUpdater] 记忆更新: token超限");
|
log.debug("[MemoryUpdater] 记忆更新: token超限");
|
||||||
@@ -161,7 +162,7 @@ public class MemoryUpdater implements InteractionModule {
|
|||||||
log.debug("[MemoryUpdater] 对话缓存更新完毕");
|
log.debug("[MemoryUpdater] 对话缓存更新完毕");
|
||||||
log.debug("[MemoryUpdater] 多人聊天记忆更新流程结束...");
|
log.debug("[MemoryUpdater] 多人聊天记忆更新流程结束...");
|
||||||
} catch (IOException | ClassNotFoundException | InterruptedException e) {
|
} catch (IOException | ClassNotFoundException | InterruptedException e) {
|
||||||
log.error("[MemoryUpdater] 多人场景记忆更新失败: {}", e.getLocalizedMessage());
|
log.error("[MemoryUpdater] 多人场景记忆更新失败: ", e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user