better:优化工作记忆处理器

This commit is contained in:
SengokuCola
2025-06-02 20:50:05 +08:00
parent 90b73acbe5
commit 476743427a
3 changed files with 54 additions and 186 deletions

View File

@@ -108,9 +108,7 @@ class WorkingMemoryProcessor(BaseProcessor):
memory_summary = memory.summary memory_summary = memory.summary
memory_id = memory.id memory_id = memory.id
memory_brief = memory_summary.get("brief") memory_brief = memory_summary.get("brief")
# memory_detailed = memory_summary.get("detailed") memory_keypoints = memory_summary.get("key_points", [])
memory_keypoints = memory_summary.get("keypoints")
memory_events = memory_summary.get("events")
memory_single_prompt = f"记忆id:{memory_id},记忆摘要:{memory_brief}\n" memory_single_prompt = f"记忆id:{memory_id},记忆摘要:{memory_brief}\n"
memory_prompts.append(memory_single_prompt) memory_prompts.append(memory_single_prompt)
@@ -165,15 +163,9 @@ class WorkingMemoryProcessor(BaseProcessor):
memory_summary = memory.summary memory_summary = memory.summary
memory_id = memory.id memory_id = memory.id
memory_brief = memory_summary.get("brief") memory_brief = memory_summary.get("brief")
# memory_detailed = memory_summary.get("detailed") memory_keypoints = memory_summary.get("key_points", [])
memory_keypoints = memory_summary.get("keypoints")
memory_events = memory_summary.get("events")
for keypoint in memory_keypoints: for keypoint in memory_keypoints:
memory_str += f"记忆要点:{keypoint}\n" memory_str += f"记忆要点:{keypoint}\n"
for event in memory_events:
memory_str += f"记忆事件:{event}\n"
# memory_str += f"记忆摘要:{memory_detailed}\n"
# memory_str += f"记忆主题:{memory_brief}\n"
working_memory_info = WorkingMemoryInfo() working_memory_info = WorkingMemoryInfo()
if memory_str: if memory_str:
@@ -225,7 +217,7 @@ class WorkingMemoryProcessor(BaseProcessor):
logger.debug(f"{self.log_prefix} 异步合并记忆成功: {memory_id1}{memory_id2}...") logger.debug(f"{self.log_prefix} 异步合并记忆成功: {memory_id1}{memory_id2}...")
logger.debug(f"{self.log_prefix} 合并后的记忆梗概: {merged_memory.summary.get('brief')}") logger.debug(f"{self.log_prefix} 合并后的记忆梗概: {merged_memory.summary.get('brief')}")
logger.debug(f"{self.log_prefix} 合并后的记忆详情: {merged_memory.summary.get('detailed')}") logger.debug(f"{self.log_prefix} 合并后的记忆详情: {merged_memory.summary.get('detailed')}")
logger.debug(f"{self.log_prefix} 合并后的记忆要点: {merged_memory.summary.get('keypoints')}") logger.debug(f"{self.log_prefix} 合并后的记忆要点: {merged_memory.summary.get('key_points')}")
logger.debug(f"{self.log_prefix} 合并后的记忆事件: {merged_memory.summary.get('events')}") logger.debug(f"{self.log_prefix} 合并后的记忆事件: {merged_memory.summary.get('events')}")
except Exception as e: except Exception as e:

View File

@@ -224,39 +224,27 @@ class MemoryManager:
Returns: Returns:
包含总结、概括、关键概念和事件的字典 包含总结、概括、关键概念和事件的字典
""" """
prompt = f"""请对以下内容进行总结,总结成记忆,输出部分: prompt = f"""请对以下内容进行总结,总结成记忆,输出部分:
1. 记忆内容主题精简20字以内让用户可以一眼看出记忆内容是什么 1. 记忆内容主题精简20字以内让用户可以一眼看出记忆内容是什么
2. 记忆内容概括200字以内让用户可以了解记忆内容的大致内容 2. key_points多条包含关键的概念、事件每条都要包含解释或描述谁在什么时候干了什么
3. 关键概念和知识keypoints多条提取关键的概念、知识点和关键词要包含对概念的解释
4. 事件描述events多条描述谁人物在什么时候时间做了什么事件
内容: 内容:
{content} {content}
请按以下JSON格式输出 请按以下JSON格式输出
```json
{{ {{
"brief": "记忆内容主题20字以内", "brief": "记忆内容主题20字以内",
"detailed": "记忆内容概括200字以内", "key_points": [
"keypoints": [ "要点1解释或描述",
"概念1解释", "要点2解释或描述",
"概念2解释",
...
],
"events": [
"事件1谁在什么时候做了什么",
"事件2谁在什么时候做了什么",
... ...
] ]
}} }}
```
请确保输出是有效的JSON格式不要添加任何额外的说明或解释。 请确保输出是有效的JSON格式不要添加任何额外的说明或解释。
""" """
default_summary = { default_summary = {
"brief": "主题未知的记忆", "brief": "主题未知的记忆",
"detailed": "大致内容未知的记忆", "key_points": ["未知的要点"],
"keypoints": ["未知的概念"],
"events": ["未知的事件"],
} }
try: try:
@@ -288,29 +276,14 @@ class MemoryManager:
if "brief" not in json_result or not isinstance(json_result["brief"], str): if "brief" not in json_result or not isinstance(json_result["brief"], str):
json_result["brief"] = "主题未知的记忆" json_result["brief"] = "主题未知的记忆"
if "detailed" not in json_result or not isinstance(json_result["detailed"], str): # 处理关键要点
json_result["detailed"] = "大致内容未知的记忆" if "key_points" not in json_result or not isinstance(json_result["key_points"], list):
json_result["key_points"] = ["未知的要点"]
# 处理关键概念
if "keypoints" not in json_result or not isinstance(json_result["keypoints"], list):
json_result["keypoints"] = ["未知的概念"]
else: else:
# 确保keypoints中的每个项目都是字符串 # 确保key_points中的每个项目都是字符串
json_result["keypoints"] = [str(point) for point in json_result["keypoints"] if point is not None] json_result["key_points"] = [str(point) for point in json_result["key_points"] if point is not None]
if not json_result["keypoints"]: if not json_result["key_points"]:
json_result["keypoints"] = ["未知的概念"] json_result["key_points"] = ["未知的要点"]
# 处理事件
if "events" not in json_result or not isinstance(json_result["events"], list):
json_result["events"] = ["未知的事件"]
else:
# 确保events中的每个项目都是字符串
json_result["events"] = [str(event) for event in json_result["events"] if event is not None]
if not json_result["events"]:
json_result["events"] = ["未知的事件"]
# 兼容旧版将keypoints和events合并到key_points中
json_result["key_points"] = json_result["keypoints"] + json_result["events"]
return json_result return json_result
@@ -348,52 +321,31 @@ class MemoryManager:
# 使用LLM根据要求对总结、概括和要点进行精简修改 # 使用LLM根据要求对总结、概括和要点进行精简修改
prompt = f""" prompt = f"""
请根据以下要求,对记忆内容的主题、概括、关键概念和事件进行精简,模拟记忆的遗忘过程: 请根据以下要求,对记忆内容的主题和关键要点进行精简,模拟记忆的遗忘过程:
要求:{requirements} 要求:{requirements}
你可以随机对关键概念和事件进行压缩,模糊或者丢弃,修改后,同样修改主题和概括 你可以随机对关键要点进行压缩,模糊或者丢弃,修改后,同样修改主题
目前主题:{summary["brief"]} 目前主题:{summary["brief"]}
目前概括:{summary["detailed"]} 目前关键要点:
{chr(10).join([f"- {point}" for point in summary.get("key_points", [])])}
目前关键概念 请生成修改后的主题和关键要点,遵循以下格式
{chr(10).join([f"- {point}" for point in summary.get("keypoints", [])])}
目前事件:
{chr(10).join([f"- {point}" for point in summary.get("events", [])])}
请生成修改后的主题、概括、关键概念和事件,遵循以下格式:
```json ```json
{{ {{
"brief": "修改后的主题20字以内", "brief": "修改后的主题20字以内",
"detailed": "修改后的概括200字以内", "key_points": [
"keypoints": [ "修改后的要点1解释或描述",
"修改后的概念1解释", "修改后的要点2解释或描述"
"修改后的概念2解释"
],
"events": [
"修改后的事件1谁在什么时候做了什么",
"修改后的事件2谁在什么时候做了什么"
] ]
}} }}
``` ```
请确保输出是有效的JSON格式不要添加任何额外的说明或解释。 请确保输出是有效的JSON格式不要添加任何额外的说明或解释。
""" """
# 检查summary中是否有旧版结构转换为新版结构
if "keypoints" not in summary and "events" not in summary and "key_points" in summary:
# 尝试区分key_points中的keypoints和events
# 简单地将前半部分视为keypoints后半部分视为events
key_points = summary.get("key_points", [])
halfway = len(key_points) // 2
summary["keypoints"] = key_points[:halfway] or ["未知的概念"]
summary["events"] = key_points[halfway:] or ["未知的事件"]
# 定义默认的精简结果 # 定义默认的精简结果
default_refined = { default_refined = {
"brief": summary["brief"], "brief": summary["brief"],
"detailed": summary["detailed"], "key_points": summary.get("key_points", ["未知的要点"])[:1], # 默认只保留第一个要点
"keypoints": summary.get("keypoints", ["未知的概念"])[:1], # 默认只保留第一个关键概念
"events": summary.get("events", ["未知的事件"])[:1], # 默认只保留第一个事件
} }
try: try:
@@ -421,30 +373,17 @@ class MemoryManager:
logger.error(f"修复后的JSON不是字典类型: {type(refined_data)}") logger.error(f"修复后的JSON不是字典类型: {type(refined_data)}")
refined_data = default_refined refined_data = default_refined
# 更新总结、概括 # 更新总结
summary["brief"] = refined_data.get("brief", "主题未知的记忆") summary["brief"] = refined_data.get("brief", "主题未知的记忆")
summary["detailed"] = refined_data.get("detailed", "大致内容未知的记忆")
# 更新关键概念 # 更新关键要点
keypoints = refined_data.get("keypoints", []) key_points = refined_data.get("key_points", [])
if isinstance(keypoints, list) and keypoints: if isinstance(key_points, list) and key_points:
# 确保所有关键概念都是字符串 # 确保所有要点都是字符串
summary["keypoints"] = [str(point) for point in keypoints if point is not None] summary["key_points"] = [str(point) for point in key_points if point is not None]
else: else:
# 如果keypoints不是列表或为空使用默认值 # 如果key_points不是列表或为空使用默认值
summary["keypoints"] = ["主要概念已遗忘"] summary["key_points"] = ["主要要点已遗忘"]
# 更新事件
events = refined_data.get("events", [])
if isinstance(events, list) and events:
# 确保所有事件都是字符串
summary["events"] = [str(event) for event in events if event is not None]
else:
# 如果events不是列表或为空使用默认值
summary["events"] = ["事件细节已遗忘"]
# 兼容旧版维护key_points
summary["key_points"] = summary["keypoints"] + summary["events"]
except Exception as e: except Exception as e:
logger.error(f"精简记忆出错: {str(e)}") logger.error(f"精简记忆出错: {str(e)}")
@@ -452,9 +391,7 @@ class MemoryManager:
# 出错时使用简化的默认精简 # 出错时使用简化的默认精简
summary["brief"] = summary["brief"] + " (已简化)" summary["brief"] = summary["brief"] + " (已简化)"
summary["keypoints"] = summary.get("keypoints", ["未知的概念"])[:1] summary["key_points"] = summary.get("key_points", ["未知的要点"])[:1]
summary["events"] = summary.get("events", ["未知的事件"])[:1]
summary["key_points"] = summary["keypoints"] + summary["events"]
except Exception as e: except Exception as e:
logger.error(f"精简记忆调用LLM出错: {str(e)}") logger.error(f"精简记忆调用LLM出错: {str(e)}")
@@ -573,27 +510,11 @@ class MemoryManager:
# 如果有摘要信息,添加到提示中 # 如果有摘要信息,添加到提示中
if summary1: if summary1:
prompt += f"记忆1主题{summary1['brief']}\n" prompt += f"记忆1主题{summary1['brief']}\n"
prompt += f"记忆1概括:{summary1['detailed']}\n" prompt += "记忆1关键要点:\n" + "\n".join([f"- {point}" for point in summary1.get("key_points", [])]) + "\n\n"
if "keypoints" in summary1:
prompt += "记忆1关键概念\n" + "\n".join([f"- {point}" for point in summary1["keypoints"]]) + "\n\n"
if "events" in summary1:
prompt += "记忆1事件\n" + "\n".join([f"- {point}" for point in summary1["events"]]) + "\n\n"
elif "key_points" in summary1:
prompt += "记忆1要点\n" + "\n".join([f"- {point}" for point in summary1["key_points"]]) + "\n\n"
if summary2: if summary2:
prompt += f"记忆2主题{summary2['brief']}\n" prompt += f"记忆2主题{summary2['brief']}\n"
prompt += f"记忆2概括:{summary2['detailed']}\n" prompt += "记忆2关键要点:\n" + "\n".join([f"- {point}" for point in summary2.get("key_points", [])]) + "\n\n"
if "keypoints" in summary2:
prompt += "记忆2关键概念\n" + "\n".join([f"- {point}" for point in summary2["keypoints"]]) + "\n\n"
if "events" in summary2:
prompt += "记忆2事件\n" + "\n".join([f"- {point}" for point in summary2["events"]]) + "\n\n"
elif "key_points" in summary2:
prompt += "记忆2要点\n" + "\n".join([f"- {point}" for point in summary2["key_points"]]) + "\n\n"
# 添加记忆原始内容 # 添加记忆原始内容
prompt += f""" prompt += f"""
@@ -608,15 +529,10 @@ class MemoryManager:
{{ {{
"content": "合并后的记忆内容文本(尽可能保留原信息,但去除重复)", "content": "合并后的记忆内容文本(尽可能保留原信息,但去除重复)",
"brief": "合并后的主题20字以内", "brief": "合并后的主题20字以内",
"detailed": "合并后的概括200字以内", "key_points": [
"keypoints": [ "合并后的要点1解释或描述",
"合并后的概念1解释", "合并后的要点2解释或描述",
"合并后的概念2解释", "合并后的要点3解释或描述"
"合并后的概念3解释"
],
"events": [
"合并后的事件1谁在什么时候做了什么",
"合并后的事件2谁在什么时候做了什么"
] ]
}} }}
``` ```
@@ -627,40 +543,18 @@ class MemoryManager:
default_merged = { default_merged = {
"content": f"{content1}\n\n{content2}", "content": f"{content1}\n\n{content2}",
"brief": f"合并:{summary1['brief']} + {summary2['brief']}", "brief": f"合并:{summary1['brief']} + {summary2['brief']}",
"detailed": f"合并了两个记忆:{summary1['detailed']} 以及 {summary2['detailed']}", "key_points": [],
"keypoints": [],
"events": [],
} }
# 合并旧版key_points # 合并key_points
if "key_points" in summary1: if "key_points" in summary1:
default_merged["keypoints"].extend(summary1.get("keypoints", [])) default_merged["key_points"].extend(summary1["key_points"])
default_merged["events"].extend(summary1.get("events", []))
# 如果没有新的结构,尝试从旧结构分离
if not default_merged["keypoints"] and not default_merged["events"] and "key_points" in summary1:
key_points = summary1["key_points"]
halfway = len(key_points) // 2
default_merged["keypoints"].extend(key_points[:halfway])
default_merged["events"].extend(key_points[halfway:])
if "key_points" in summary2: if "key_points" in summary2:
default_merged["keypoints"].extend(summary2.get("keypoints", [])) default_merged["key_points"].extend(summary2["key_points"])
default_merged["events"].extend(summary2.get("events", []))
# 如果没有新的结构,尝试从旧结构分离
if not default_merged["keypoints"] and not default_merged["events"] and "key_points" in summary2:
key_points = summary2["key_points"]
halfway = len(key_points) // 2
default_merged["keypoints"].extend(key_points[:halfway])
default_merged["events"].extend(key_points[halfway:])
# 确保列表不为空 # 确保列表不为空
if not default_merged["keypoints"]: if not default_merged["key_points"]:
default_merged["keypoints"] = ["合并的关键概念"] default_merged["key_points"] = ["合并的要点"]
if not default_merged["events"]:
default_merged["events"] = ["合并的事件"]
# 添加key_points兼容
default_merged["key_points"] = default_merged["keypoints"] + default_merged["events"]
try: try:
# 调用LLM合并记忆 # 调用LLM合并记忆
@@ -694,29 +588,14 @@ class MemoryManager:
if "brief" not in merged_data or not isinstance(merged_data["brief"], str): if "brief" not in merged_data or not isinstance(merged_data["brief"], str):
merged_data["brief"] = default_merged["brief"] merged_data["brief"] = default_merged["brief"]
if "detailed" not in merged_data or not isinstance(merged_data["detailed"], str): # 处理关键要点
merged_data["detailed"] = default_merged["detailed"] if "key_points" not in merged_data or not isinstance(merged_data["key_points"], list):
merged_data["key_points"] = default_merged["key_points"]
# 处理关键概念
if "keypoints" not in merged_data or not isinstance(merged_data["keypoints"], list):
merged_data["keypoints"] = default_merged["keypoints"]
else: else:
# 确保keypoints中的每个项目都是字符串 # 确保key_points中的每个项目都是字符串
merged_data["keypoints"] = [str(point) for point in merged_data["keypoints"] if point is not None] merged_data["key_points"] = [str(point) for point in merged_data["key_points"] if point is not None]
if not merged_data["keypoints"]: if not merged_data["key_points"]:
merged_data["keypoints"] = ["合并的关键概念"] merged_data["key_points"] = ["合并的要点"]
# 处理事件
if "events" not in merged_data or not isinstance(merged_data["events"], list):
merged_data["events"] = default_merged["events"]
else:
# 确保events中的每个项目都是字符串
merged_data["events"] = [str(event) for event in merged_data["events"] if event is not None]
if not merged_data["events"]:
merged_data["events"] = ["合并的事件"]
# 添加key_points兼容
merged_data["key_points"] = merged_data["keypoints"] + merged_data["events"]
except Exception as e: except Exception as e:
logger.error(f"合并记忆时处理JSON出错: {str(e)}") logger.error(f"合并记忆时处理JSON出错: {str(e)}")
@@ -744,9 +623,6 @@ class MemoryManager:
# 设置合并后的摘要 # 设置合并后的摘要
summary = { summary = {
"brief": merged_data["brief"], "brief": merged_data["brief"],
"detailed": merged_data["detailed"],
"keypoints": merged_data["keypoints"],
"events": merged_data["events"],
"key_points": merged_data["key_points"], "key_points": merged_data["key_points"],
} }
merged_memory.set_summary(summary) merged_memory.set_summary(summary)

View File

@@ -98,7 +98,7 @@ parallel_processing = true # 是否并行处理回忆和处理器阶段,可以
processor_max_time = 25 # 处理器最大时间,单位秒,如果超过这个时间,处理器会自动停止 processor_max_time = 25 # 处理器最大时间,单位秒,如果超过这个时间,处理器会自动停止
observation_context_size = 16 # 观察到的最长上下文大小 observation_context_size = 20 # 观察到的最长上下文大小
compressed_length = 8 # 不能大于observation_context_size,心流上下文压缩的最短压缩长度超过心流观察到的上下文长度会压缩最短压缩长度为5 compressed_length = 8 # 不能大于observation_context_size,心流上下文压缩的最短压缩长度超过心流观察到的上下文长度会压缩最短压缩长度为5
compress_length_limit = 4 #最多压缩份数,超过该数值的压缩上下文会被删除 compress_length_limit = 4 #最多压缩份数,超过该数值的压缩上下文会被删除