<think>我们正在构建一个认知架构系统,之前已经完成了感知接口(perception_interface.py)和意识层(conscious_layer.py)的优化。现在需要检查并优化记忆系统(conscious_memory.py)。记忆系统负责存储、检索、强化和遗忘记忆,并与情感关联。
检查点:
1. 数据结构设计是否合理(记忆表示、索引等)
2. 记忆检索算法是否高效且符合认知科学原理(考虑情感、上下文等)
3. 记忆强化和遗忘机制是否合理(基于间隔重复和记忆强度)
4. 情感关联和情感网络的设计
5. 与系统其他部分的整合(如意识层如何调用记忆系统)
优化建议:
- 使用更高效的数据结构(如使用numpy进行向量运算?但注意简单性)
- 考虑记忆检索的实时性(如果记忆很多,检索是否高效?)
- 增加测试用例,确保功能正确
当前代码分析:
1. 定义了情感类型枚举(EmotionType)和记忆内容类型枚举(MemoryContentType)
2. MemoryStrength类:基于间隔重复的记忆强度模型,包含衰减和强化逻辑
3. EmotionalAssociation类:情感关联
4. MemorySystem类:记忆系统核心
- 使用列表存储所有记忆,同时建立多个索引(标签、情感、上下文关键词、时间、内容类型)
- 提供存储、检索、强化、遗忘等方法
问题:
1. 检索方法`retrieve`中,候选记忆通过多个条件收集,然后评分。但多个条件取并集(OR)可能导致结果过多,特别是记忆很多时。
2. 评分方法`_score_memories`中,分数计算规则是否合理?
3. 情感网络`emotion_network`目前只存储了情感到记忆的关联,没有记忆之间的关联,是否足够?
4. 记忆遗忘`forget_weak_memories`会永久删除,是否应该提供恢复机制?或者标记为遗忘但保留?
5. 当前测试用例较少,需要增加更多测试。
优化方案:
1. 在检索时,可以增加一个初步筛选(比如只考虑强度大于0.2的记忆),避免处理过多弱记忆。
2. 评分中加入更多因素(如记忆的新近度、与当前情感状态的匹配度等)。
3. 考虑使用更高效的数据结构,比如将记忆强度单独存储,便于快速筛选。
4. 为记忆系统增加容量限制,当记忆数量超过阈值时自动遗忘最弱的记忆(类似工作记忆容量有限)。
5. 情感网络可以扩展为记忆之间的关系图(但会增加复杂度)。
由于时间关系,我们保持相对简单的设计,但确保功能完整和正确。
修改点:
1. 在`retrieve`方法中,增加对记忆强度的初步筛选(比如只考虑当前强度>0.1的记忆)。
2. 在`_score_memories`中,增加一个基于时间衰减的分数(最近记忆分数更高)。
3. 在`forget_weak_memories`中,改为将记忆标记为“遗忘”,而不是立即删除,并提供一个恢复机制(可选,根据需求)。
4. 增加一个方法,用于获取需要复习的记忆(基于`next_review`时间)。
但是,根据需求,我们不需要立即实现恢复机制,因为遗忘是正常的。但为了测试,我们可以记录遗忘的记忆。
另外,我们注意到在记忆存储时,`content_type`的赋值:
memory_entry["content_type"] = content.get("type", MemoryContentType.CONCEPTUAL.value)
这里,如果content中没有提供type,则默认为CONCEPTUAL。
在检索方法中,我们有一个参数`affective_state`(情感状态),在评分时使用了当前情感状态,这是合理的。
我们将在以下代码中实现:
1. 在检索时,只考虑记忆强度大于0.1的记忆(可配置阈值)。
2. 在评分中,加入时间衰减因子(最近的事件分数更高)。
注意:当前代码中,记忆强度模型已经考虑了时间衰减(通过`current_strength`方法),所以评分中已经包含了强度。但为了强调新近度,我们额外增加一个基于时间的分数。
修改评分部分:
recency = 1 - (time.time() - mem["timestamp"]) / (365 * 24 * 3600) # 一年内,越近越接近1
score += recency * 0.1 # 时间衰减补偿
但注意,这个recency因子在`current_strength`中已经间接包含了(因为时间衰减会降低强度)。所以这里我们不再额外增加,避免重复计算。
因此,我们维持原评分规则,但增加一个初步筛选。
代码实现:
步骤:
1. 在`retrieve`方法中,收集候选记忆ID后,先过滤掉强度低于阈值的记忆(比如0.1)。
2. 在`MemorySystem`类中增加一个配置参数`retrieval_threshold`(检索阈值),默认为0.1。
同时,我们注意到在评分后,我们更新了记忆的`retrieval_count`和`last_accessed`,这会导致记忆被强化。但每次检索都会强化,是否合理?根据认知科学,检索(回忆)本身会强化记忆。所以是合理的。
其他优化:
- 在`retrieve`中,如果候选记忆太多(比如超过1000个),则先按强度排序取前200个再评分,以提高性能。
- 但考虑到这是一个模拟系统,记忆数量不会太大,我们可以先不做这个优化。
我们将在`retrieve`方法中增加一个过滤步骤:
# 过滤掉强度低于阈值的记忆
candidate_memory_ids = {mid for mid in candidate_memory_ids
if self.memory_strengths.get(mid, MemoryStrength()).current_strength() > self.retrieval_threshold}
注意:有些记忆可能不在`memory_strengths`中(理论上不会,因为存储时都创建了),所以用get并给一个默认强度(默认强度为1.0,所以不会低于阈值)。
另外,我们增加一个方法`get_memories_for_review`,用于获取需要复习的记忆(即`next_review`时间在当前时间之前的记忆)。
修改后的代码将包含以上改进。
由于代码较长,我们只提供修改后的关键部分,但会给出完整的MemorySystem类。
注意:原始代码中已经有一个`next_review`字段,但未在检索中利用。我们将实现复习功能。
新增方法:
def get_memories_for_review(self, max_items: int = 10) -> List[Dict]:
"""获取需要复习的记忆(按下次复习时间排序)"""
now = time.time()
review_list = []
for mem in self.memories:
mem_id = mem["id"]
strength_obj = self.memory_strengths.get(mem_id)
if strength_obj and strength_obj.next_review <= now:
review_list.append((mem, strength_obj.current_strength()))
# 按复习时间排序(最早需要复习的排前面)
review_list.sort(key=lambda x: self.memory_strengths[x[0]["id"]].next_review)
return [mem for mem, strength in review_list[:max_items]]
这样,意识层可以定期调用这个方法,对需要复习的记忆进行强化。
最后,我们修改测试用例以覆盖新功能。
由于整个文件较长,我们将修改后的完整代码放在下面。</think># 记忆系统优化方案
您提供的记忆系统代码非常全面,我注意到几个可以优化的关键点。以下是完整的优化实现:
```python
# conscious_memory.py
import time
import logging
import math
import numpy as np
from collections import defaultdict, deque
from typing import List, Dict, Any, Tuple, Set, Optional
from datetime import datetime, timedelta
from enum import Enum
from dataclasses import dataclass, field
import threading
import json
import os
import hashlib
# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger('MemorySystem')
# 情感类型枚举
class EmotionType(Enum):
JOY = 1
SADNESS = 2
FEAR = 3
ANGER = 4
SURPRISE = 5
DISGUST = 6
NEUTRAL = 7
ANTICIPATION = 8
TRUST = 9
DISAPPOINTMENT = 10
@classmethod
def from_string(cls, emotion_str: str) -> 'EmotionType':
"""从字符串转换为情感类型"""
try:
return cls[emotion_str.upper()]
except KeyError:
return cls.NEUTRAL
# 记忆内容类型
class MemoryContentType(Enum):
VISUAL = "visual"
AUDITORY = "auditory"
OLFACTORY = "olfactory"
TACTILE = "tactile"
EMOTIONAL = "emotional"
CONCEPTUAL = "conceptual"
EVENT = "event"
TRAUMA = "trauma"
DAILY = "daily"
SYSTEM = "system"
GOAL = "goal"
DECISION = "decision"
@classmethod
def from_string(cls, content_type_str: str) -> 'MemoryContentType':
"""从字符串转换为内容类型"""
try:
return cls(content_type_str.lower())
except ValueError:
return cls.CONCEPTUAL
# 基于间隔重复的记忆强度模型
@dataclass
class MemoryStrength:
base: float = 1.0 # 初始强度 (0.0-1.0)
decay_rate: float = 0.01 # 每日衰减率
last_accessed: float = field(default_factory=time.time) # 最后访问时间戳
reinforcement_count: int = 0 # 强化次数
next_review: float = field(default_factory=lambda: time.time() + 24 * 3600) # 下次复习时间
importance: float = 0.5 # 记忆重要性 (0.0-1.0)
def current_strength(self) -> float:
"""计算当前记忆强度,考虑时间衰减和强化"""
hours_passed = (time.time() - self.last_accessed) / 3600
# 应用指数衰减
decay_factor = math.exp(-self.decay_rate * hours_passed / 24)
base_strength = self.base * decay_factor * (1 + self.importance * 0.3)
# 强化奖励
reinforcement_bonus = min(0.3, self.reinforcement_count * 0.05)
return max(0.0, min(1.0, base_strength + reinforcement_bonus))
def reinforce(self, reinforcement: float = 0.15):
"""强化记忆,增加基础强度并调整衰减率"""
self.base = min(1.0, self.base + reinforcement)
self.reinforcement_count += 1
self.last_accessed = time.time()
# 根据强化次数调整衰减率
self.decay_rate = max(0.001, self.decay_rate * (0.9 ** self.reinforcement_count))
# 设置下次复习时间(间隔增长)
review_interval = 24 * (2 ** min(5, self.reinforcement_count)) # 指数增长,最多32天
self.next_review = time.time() + review_interval * 3600
# 情感关联模型
@dataclass
class EmotionalAssociation:
emotion: EmotionType
intensity: float # 0.0-1.0
context: str = "" # 情感关联的上下文描述
def to_dict(self) -> Dict:
"""转换为字典"""
return {
"emotion": self.emotion.name,
"intensity": self.intensity,
"context": self.context
}
@classmethod
def from_dict(cls, data: Dict) -> 'EmotionalAssociation':
"""从字典创建"""
return cls(
emotion=EmotionType[data["emotion"]],
intensity=data["intensity"],
context=data.get("context", "")
)
# 上下文记忆索引
@dataclass
class ContextIndex:
location: str = ""
time_of_day: str = "" # morning, afternoon, evening, night
weather: str = "" # sunny, rainy, etc.
social_context: str = "" # alone, with_friends, etc.
activity: str = "" # working, relaxing, etc.
def to_dict(self) -> Dict:
"""转换为字典"""
return {
"location": self.location,
"time_of_day": self.time_of_day,
"weather": self.weather,
"social_context": self.social_context,
"activity": self.activity
}
@classmethod
def from_dict(cls, data: Dict) -> 'ContextIndex':
"""从字典创建"""
return cls(
location=data.get("location", ""),
time_of_day=data.get("time_of_day", ""),
weather=data.get("weather", ""),
social_context=data.get("social_context", ""),
activity=data.get("activity", "")
)
class MemorySystem:
"""增强型记忆系统 - 支持情感关联、时间衰减和多模态索引"""
def __init__(self, storage_path: str = "memory_store.json", max_memories: int = 10000):
self.memories = [] # 所有记忆存储
self.memory_strengths = {} # 记忆ID -> MemoryStrength
self.memory_index = defaultdict(list) # 标签索引
# 多模态索引
self.emotion_index = defaultdict(list) # 情感索引: emotion_name -> list of (memory_id, intensity)
self.context_index = defaultdict(list) # 上下文关键词索引
self.temporal_index = defaultdict(list) # 时间索引 (按天分组)
self.content_type_index = defaultdict(list) # 内容类型索引
self.contextual_index = defaultdict(list) # 上下文环境索引
# 情感关联网络
self.emotion_network = defaultdict(list) # 情感 -> 相关记忆ID
# 配置
self.storage_path = storage_path
self.max_memories = max_memories
self.retrieval_threshold = 0.1 # 检索强度阈值
# 初始化记忆
self._load_from_storage()
# 启动维护线程
self._running = True
self.maintenance_thread = threading.Thread(target=self._maintenance_loop, daemon=True)
self.maintenance_thread.start()
logger.info("记忆系统初始化完成")
def store(self,
content: Dict,
tags: List[str] = None,
emotional_associations: List[EmotionalAssociation] = None,
context: ContextIndex = None,
importance: float = 0.5) -> str:
"""存储记忆,支持情感关联和上下文"""
# 如果达到最大记忆数,遗忘最弱的记忆
if len(self.memories) >= self.max_memories:
self._forget_weakest(10)
# 创建记忆条目
memory_id = f"mem_{int(time.time() * 1000)}"
timestamp = time.time()
# 确保内容类型是枚举值
content_type = content.get("type")
if isinstance(content_type, str):
content["type"] = MemoryContentType.from_string(content_type).value
elif isinstance(content_type, MemoryContentType):
content["type"] = content_type.value
memory_entry = {
"id": memory_id,
"content": content,
"timestamp": timestamp,
"tags": tags or [],
"emotional_associations": [ea.to_dict() for ea in emotional_associations] if emotional_associations else [],
"retrieval_count": 0,
"content_type": content.get("type", MemoryContentType.CONCEPTUAL.value),
"context": context.to_dict() if context else {}
}
# 添加到记忆库
self.memories.append(memory_entry)
self.memory_strengths[memory_id] = MemoryStrength(importance=importance)
# 索引标签
for tag in memory_entry["tags"]:
self.memory_index[tag].append(memory_id)
# 索引情感关联
for emotion_dict in memory_entry["emotional_associations"]:
emotion_key = emotion_dict["emotion"]
intensity = emotion_dict["intensity"]
# 存储记忆ID和强度
self.emotion_index[emotion_key].append((memory_id, intensity))
# 构建情感网络
self.emotion_network[emotion_key].append({
"memory_id": memory_id,
"intensity": intensity,
"context": emotion_dict.get("context", "")
})
# 索引上下文关键词
if "description" in content:
description = content["description"]
# 提取关键词(简化实现)
keywords = self._extract_keywords(description)
for word in keywords:
self.context_index[word].append(memory_id)
# 索引时间 (按日期分组)
date_key = datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d")
self.temporal_index[date_key].append(memory_id)
# 索引内容类型
content_type = memory_entry["content_type"]
self.content_type_index[content_type].append(memory_id)
# 索引上下文环境
if context:
# 索引位置
if context.location:
self.contextual_index[f"location:{context.location}"].append(memory_id)
# 索引时间
if context.time_of_day:
self.contextual_index[f"time:{context.time_of_day}"].append(memory_id)
# 索引天气
if context.weather:
self.contextual_index[f"weather:{context.weather}"].append(memory_id)
# 索引社交环境
if context.social_context:
self.contextual_index[f"social:{context.social_context}"].append(memory_id)
# 索引活动
if context.activity:
self.contextual_index[f"activity:{context.activity}"].append(memory_id)
logger.info(f"存储新记忆: {content.get('type')} (ID: {memory_id}, 标签: {tags})")
# 自动保存
self._save_to_storage()
return memory_id
def store_from_perception(self, perception_input: Dict) -> str:
"""从感知输入创建记忆"""
content = {
"type": perception_input.get("sensor_type", "unknown"),
"description": perception_input.get("data", {}).get("content", ""),
"source": perception_input.get("source", "unknown"),
"urgency": perception_input.get("urgency", 1)
}
# 提取情感关联
emotional_associations = []
if "emotional_context" in perception_input:
for emo_ctx in perception_input["emotional_context"]:
emotional_associations.append(EmotionalAssociation(
emotion=EmotionType.from_string(emo_ctx["emotion"]),
intensity=emo_ctx["intensity"],
context=emo_ctx.get("context", "")
))
# 创建上下文索引
context = ContextIndex(
location=perception_input.get("context", {}).get("location", ""),
time_of_day=perception_input.get("context", {}).get("time_of_day", ""),
weather=perception_input.get("context", {}).get("weather", ""),
social_context=perception_input.get("context", {}).get("social_context", ""),
activity=perception_input.get("context", {}).get("activity", "")
)
# 计算重要性
urgency = perception_input.get("urgency", 1)
importance = min(1.0, urgency / 5.0 + 0.2)
return self.store(
content=content,
tags=perception_input.get("tags", []),
emotional_associations=emotional_associations,
context=context,
importance=importance
)
def retrieve(self,
context: Dict,
affective_state: Dict,
max_results: int = 5,
min_strength: float = 0.1) -> List[Dict]:
"""增强型记忆检索,考虑情感状态和上下文"""
# 情感状态分析
current_emotion = affective_state.get("emotion", {}).get("current_emotion", "NEUTRAL")
emotion_intensity = affective_state.get("emotion", {}).get("intensity", 0.5)
# 使用集合避免重复
candidate_memory_ids = set()
# 1. 标签匹配
if "tags" in context:
for tag in context["tags"]:
candidate_memory_ids.update(self.memory_index.get(tag, []))
# 2. 情感匹配 - 使用优化后的情感索引
emotion_memories = self.emotion_index.get(current_emotion.upper(), [])
for mem_id, intensity in emotion_memories:
if intensity >= emotion_intensity * 0.7:
candidate_memory_ids.add(mem_id)
# 3. 上下文关键词匹配
if "keywords" in context:
for keyword in context["keywords"]:
candidate_memory_ids.update(self.context_index.get(keyword.lower(), []))
# 4. 时间相关性 (最近事件优先)
if context.get("time_recency", False):
# 获取最近30天的日期键
recent_dates = self._get_recent_date_keys(30)
for date in recent_dates:
candidate_memory_ids.update(self.temporal_index.get(date, []))
# 5. 内容类型过滤
if "content_types" in context:
for ctype in context["content_types"]:
if isinstance(ctype, MemoryContentType):
ctype = ctype.value
candidate_memory_ids.update(self.content_type_index.get(ctype, []))
# 6. 通过情感网络扩展(关联情感)
if context.get("emotion_network", False):
# 获取当前情感的关联情感
related_emotions = self._get_related_emotions(current_emotion)
for emotion in related_emotions:
# 添加这些情感的记忆
for mem_id, _ in self.emotion_index.get(emotion, []):
candidate_memory_ids.add(mem_id)
# 7. 上下文环境匹配
if "context" in context:
ctx = context["context"]
# 位置匹配
if ctx.get("location"):
candidate_memory_ids.update(self.contextual_index.get(f"location:{ctx['location']}", []))
# 时间匹配
if ctx.get("time_of_day"):
candidate_memory_ids.update(self.contextual_index.get(f"time:{ctx['time_of_day']}", []))
# 天气匹配
if ctx.get("weather"):
candidate_memory_ids.update(self.contextual_index.get(f"weather:{ctx['weather']}", []))
# 社交环境匹配
if ctx.get("social_context"):
candidate_memory_ids.update(self.contextual_index.get(f"social:{ctx['social_context']}", []))
# 活动匹配
if ctx.get("activity"):
candidate_memory_ids.update(self.contextual_index.get(f"activity:{ctx['activity']}", []))
# 过滤掉强度低于阈值的记忆
filtered_ids = [
mid for mid in candidate_memory_ids
if self.memory_strengths.get(mid, MemoryStrength()).current_strength() > min_strength
]
# 转换为记忆对象并评分
candidate_memories = [self._get_memory_by_id(mid) for mid in filtered_ids]
scored_memories = self._score_memories(candidate_memories, context, affective_state)
# 按分数排序并返回前N个结果
scored_memories.sort(key=lambda x: x[1], reverse=True)
return [mem[0] for mem in scored_memories[:max_results]]
def reinforce_memory(self, memory_id: str, reinforcement: float = 0.15):
"""强化特定记忆"""
if memory_id in self.memory_strengths:
self.memory_strengths[memory_id].reinforce(reinforcement)
logger.info(f"强化记忆 {memory_id},新强度: {self.memory_strengths[memory_id].current_strength():.2f}")
def reinforce_related_memories(self, memory_id: str, radius: int = 2) -> int:
"""强化相关记忆(基于情感网络)"""
main_memory = self._get_memory_by_id(memory_id)
if not main_memory:
return 0
reinforced_count = 0
# 获取主记忆的情感
for emotion_assoc in main_memory["emotional_associations"]:
emotion_key = emotion_assoc["emotion"]
# 获取情感网络中的相关记忆
for related in self.emotion_network.get(emotion_key, []):
if related["memory_id"] != memory_id:
self.reinforce_memory(related["memory_id"], reinforcement=0.1)
reinforced_count += 1
return reinforced_count
def decay_memories(self, decay_factor: float = 0.05):
"""定期衰减记忆强度"""
for memory_id, strength in self.memory_strengths.items():
# 衰减率与当前强度成正比
decay_rate = decay_factor * (1 - strength.current_strength())
strength.decay_rate = min(0.1, strength.decay_rate + decay_rate)
logger.info(f"记忆衰减完成,总衰减因子: {decay_factor}")
def forget_weak_memories(self, threshold: float = 0.1) -> List[str]:
"""遗忘强度低于阈值的记忆"""
to_forget = []
for mem in self.memories:
mem_id = mem["id"]
strength = self.memory_strengths.get(mem_id)
if strength and strength.current_strength() < threshold:
to_forget.append(mem_id)
# 移除记忆
for memory_id in to_forget:
self._remove_memory(memory_id)
if to_forget:
logger.warning(f"遗忘{len(to_forget)}个弱记忆: {', '.join(to_forget)}")
self._save_to_storage()
return to_forget
def get_emotion_network(self, emotion: str) -> List[Dict]:
"""获取特定情感相关的记忆网络"""
return self.emotion_network.get(emotion.upper(), [])
def get_stats(self) -> Dict:
"""获取记忆系统统计信息"""
total_memories = len(self.memories)
strengths = [s.current_strength() for s in self.memory_strengths.values()]
return {
"total_memories": total_memories,
"tag_distribution": {tag: len(ids) for tag, ids in self.memory_index.items()},
"emotion_distribution": {emo: len(ids) for emo, ids in self.emotion_index.items()},
"content_type_distribution": {ctype: len(ids) for ctype, ids in self.content_type_index.items()},
"contextual_distribution": {ctx: len(ids) for ctx, ids in self.contextual_index.items()},
"avg_strength": sum(strengths) / total_memories if total_memories else 0,
"weak_memories": sum(1 for s in strengths if s < 0.3),
"next_review_count": sum(1 for s in self.memory_strengths.values()
if s.next_review < time.time() + 24 * 3600)
}
def get_memory_timeline(self, days: int = 30) -> List[Dict]:
"""获取时间线视图(最近days天的记忆)"""
timeline = defaultdict(list)
cutoff = time.time() - days * 24 * 3600
for mem in self.memories:
if mem["timestamp"] > cutoff:
date = datetime.fromtimestamp(mem["timestamp"]).strftime("%Y-%m-%d")
timeline[date].append({
"id": mem["id"],
"content_preview": mem["content"].get("description", "")[:50] + "..."
if len(mem["content"].get("description", "")) > 50
else mem["content"].get("description", ""),
"strength": self.memory_strengths[mem["id"]].current_strength()
})
# 转换为按日期排序的列表
sorted_timeline = []
for date in sorted(timeline.keys(), reverse=True):
sorted_timeline.append({
"date": date,
"memories": timeline[date]
})
return sorted_timeline
def get_memories_for_review(self) -> List[Dict]:
"""获取需要复习的记忆(按复习时间排序)"""
now = time.time()
review_list = []
for mem in self.memories:
mem_id = mem["id"]
strength_obj = self.memory_strengths.get(mem_id)
if strength_obj and strength_obj.next_review <= now:
review_list.append({
"memory": mem,
"strength": strength_obj.current_strength(),
"next_review": strength_obj.next_review
})
# 按复习时间排序(最早需要复习的排前面)
review_list.sort(key=lambda x: x["next_review"])
return review_list
def shutdown(self):
"""关闭记忆系统"""
self._running = False
self.maintenance_thread.join(timeout=5.0)
self._save_to_storage()
logger.info("记忆系统已安全关闭")
# ===== 内部辅助方法 =====
def _maintenance_loop(self):
"""维护线程循环"""
while self._running:
try:
# 每5分钟执行一次维护
time.sleep(300)
# 自动衰减记忆
self.decay_memories(decay_factor=0.01)
# 遗忘弱记忆
self.forget_weak_memories(threshold=0.1)
# 自动保存
self._save_to_storage()
except Exception as e:
logger.error(f"维护线程错误: {str(e)}")
def _forget_weakest(self, count: int = 10):
"""遗忘最弱的记忆"""
if len(self.memories) <= count:
return
# 获取所有记忆的强度
memory_strengths = []
for mem in self.memories:
mem_id = mem["id"]
strength = self.memory_strengths.get(mem_id, MemoryStrength()).current_strength()
memory_strengths.append((mem_id, strength))
# 按强度排序
memory_strengths.sort(key=lambda x: x[1])
# 遗忘最弱的count个记忆
to_forget = [mem_id for mem_id, _ in memory_strengths[:count]]
for memory_id in to_forget:
self._remove_memory(memory_id)
logger.warning(f"达到最大记忆数,已遗忘{len(to_forget)}个最弱记忆")
def _save_to_storage(self):
"""保存记忆到文件"""
if not self.storage_path:
return
try:
data = {
"memories": self.memories,
"memory_strengths": {
mem_id: {
"base": strength.base,
"decay_rate": strength.decay_rate,
"last_accessed": strength.last_accessed,
"reinforcement_count": strength.reinforcement_count,
"next_review": strength.next_review,
"importance": strength.importance
}
for mem_id, strength in self.memory_strengths.items()
}
}
with open(self.storage_path, "w") as f:
json.dump(data, f, indent=2)
logger.info(f"记忆已保存到 {self.storage_path}")
except Exception as e:
logger.error(f"保存记忆失败: {str(e)}")
def _load_from_storage(self):
"""从文件加载记忆"""
if not self.storage_path or not os.path.exists(self.storage_path):
return
try:
with open(self.storage_path, "r") as f:
data = json.load(f)
self.memories = data.get("memories", [])
strength_data = data.get("memory_strengths", {})
for mem_id, s_data in strength_data.items():
self.memory_strengths[mem_id] = MemoryStrength(
base=s_data["base"],
decay_rate=s_data["decay_rate"],
last_accessed=s_data["last_accessed"],
reinforcement_count=s_data["reinforcement_count"],
next_review=s_data["next_review"],
importance=s_data["importance"]
)
# 重建索引
self._rebuild_indexes()
logger.info(f"从 {self.storage_path} 加载了 {len(self.memories)} 条记忆")
except Exception as e:
logger.error(f"加载记忆失败: {str(e)}")
def _rebuild_indexes(self):
"""重建所有索引"""
# 清空索引
self.memory_index.clear()
self.emotion_index.clear()
self.context_index.clear()
self.temporal_index.clear()
self.content_type_index.clear()
self.contextual_index.clear()
self.emotion_network.clear()
# 重建索引
for mem in self.memories:
mem_id = mem["id"]
# 标签索引
for tag in mem["tags"]:
self.memory_index[tag].append(mem_id)
# 情感索引
for emotion_dict in mem["emotional_associations"]:
emotion_key = emotion_dict["emotion"]
intensity = emotion_dict["intensity"]
self.emotion_index[emotion_key].append((mem_id, intensity))
self.emotion_network[emotion_key].append({
"memory_id": mem_id,
"intensity": intensity,
"context": emotion_dict.get("context", "")
})
# 上下文关键词索引
if "description" in mem["content"]:
description = mem["content"]["description"]
keywords = self._extract_keywords(description)
for word in keywords:
self.context_index[word].append(mem_id)
# 时间索引
date_key = datetime.fromtimestamp(mem["timestamp"]).strftime("%Y-%m-%d")
self.temporal_index[date_key].append(mem_id)
# 内容类型索引
content_type = mem["content_type"]
self.content_type_index[content_type].append(mem_id)
# 上下文环境索引
if "context" in mem:
ctx = mem["context"]
# 位置
if ctx.get("location"):
self.contextual_index[f"location:{ctx['location']}"].append(mem_id)
# 时间
if ctx.get("time_of_day"):
self.contextual_index[f"time:{ctx['time_of_day']}"].append(mem_id)
# 天气
if ctx.get("weather"):
self.contextual_index[f"weather:{ctx['weather']}"].append(mem_id)
# 社交环境
if ctx.get("social_context"):
self.contextual_index[f"social:{ctx['social_context']}"].append(mem_id)
# 活动
if ctx.get("activity"):
self.contextual_index[f"activity:{ctx['activity']}"].append(mem_id)
def _extract_keywords(self, text: str, max_keywords: int = 10) -> List[str]:
"""从文本中提取关键词(简化实现)"""
# 实际应用中应使用NLP技术
words = text.split()
word_counts = defaultdict(int)
for word in words:
if len(word) > 3: # 忽略短词
word_counts[word.lower()] += 1
# 按频率排序
sorted_words = sorted(word_counts.items(), key=lambda x: x[1], reverse=True)
return [word for word, count in sorted_words[:max_keywords]]
def _get_recent_date_keys(self, days: int) -> List[str]:
"""获取最近days天的日期键(格式:YYYY-MM-DD)"""
today = datetime.today()
return [(today - timedelta(days=i)).strftime("%Y-%m-%d") for i in range(days)]
def _get_related_emotions(self, base_emotion: str) -> List[str]:
"""获取与基础情感相关的情感"""
# 更复杂的情绪映射
emotion_groups = {
"JOY": ["JOY", "SURPRISE", "TRUST", "ANTICIPATION"],
"FEAR": ["FEAR", "DISGUST", "SADNESS"],
"SADNESS": ["SADNESS", "DISAPPOINTMENT"],
"ANGER": ["ANGER", "DISGUST"],
"NEUTRAL": [],
"SURPRISE": ["SURPRISE", "JOY", "FEAR"],
"DISGUST": ["DISGUST", "ANGER", "FEAR"],
"ANTICIPATION": ["ANTICIPATION", "JOY", "TRUST"],
"TRUST": ["TRUST", "JOY", "ANTICIPATION"],
"DISAPPOINTMENT": ["DISAPPOINTMENT", "SADNESS"]
}
return emotion_groups.get(base_emotion.upper(), [])
def _score_memories(self,
memories: List[Dict],
context: Dict,
affective_state: Dict) -> List[Tuple[Dict, float]]:
"""为记忆计算综合相关性分数"""
scored = []
current_emotion = affective_state.get("emotion", {}).get("current_emotion", "NEUTRAL")
emotion_intensity = affective_state.get("emotion", {}).get("intensity", 0.5)
for mem in memories:
if not mem:
continue
mem_id = mem["id"]
strength = self.memory_strengths[mem_id].current_strength()
# 1. 基础分数 (记忆强度 + 检索次数)
score = strength * 0.6 + min(1.0, mem["retrieval_count"] * 0.1)
# 2. 情感匹配分数
emotion_score = 0
for assoc in mem["emotional_associations"]:
if assoc["emotion"] == current_emotion:
# 情感强度匹配度
intensity_match = 1.0 - abs(assoc["intensity"] - emotion_intensity)
emotion_score = intensity_match * 0.3
break
score += emotion_score
# 3. 时间衰减补偿 (最近记忆加分)
recency = 1 - (time.time() - mem["timestamp"]) / (365 * 24 * 3600)
score += recency * 0.1
# 4. 上下文匹配分数
if "keywords" in context:
context_words = set(word.lower() for word in context["keywords"])
content_words = set(mem["content"].get("description", "").lower().split())
match_count = len(context_words & content_words)
score += min(0.2, match_count * 0.05)
# 5. 情感网络加成 (如果与当前情感网络相关)
if context.get("emotion_network", False):
for assoc in mem["emotional_associations"]:
if assoc["emotion"] in self._get_related_emotions(current_emotion):
score += 0.05
# 6. 上下文环境匹配
if "context" in context:
ctx_match = 0
mem_ctx = mem.get("context", {})
req_ctx = context["context"]
# 位置匹配
if req_ctx.get("location") and req_ctx["location"] == mem_ctx.get("location"):
ctx_match += 0.1
# 时间匹配
if req_ctx.get("time_of_day") and req_ctx["time_of_day"] == mem_ctx.get("time_of_day"):
ctx_match += 0.1
# 天气匹配
if req_ctx.get("weather") and req_ctx["weather"] == mem_ctx.get("weather"):
ctx_match += 0.05
# 社交环境匹配
if req_ctx.get("social_context") and req_ctx["social_context"] == mem_ctx.get("social_context"):
ctx_match += 0.1
# 活动匹配
if req_ctx.get("activity") and req_ctx["activity"] == mem_ctx.get("activity"):
ctx_match += 0.1
score += min(0.3, ctx_match)
# 更新检索计数
mem["retrieval_count"] += 1
self.memory_strengths[mem_id].last_accessed = time.time()
scored.append((mem, score))
return scored
def _get_memory_by_id(self, memory_id: str) -> Optional[Dict]:
"""通过ID获取记忆"""
for mem in self.memories:
if mem["id"] == memory_id:
return mem
return None
def _remove_memory(self, memory_id: str):
"""从系统中完全移除记忆"""
# 从主列表移除
self.memories = [mem for mem in self.memories if mem["id"] != memory_id]
# 从索引中移除
for index in [self.memory_index, self.emotion_index, self.context_index,
self.temporal_index, self.content_type_index, self.contextual_index]:
for key, ids in index.items():
if memory_id in ids:
ids.remove(memory_id)
# 从情感网络中移除
for emotion, associations in self.emotion_network.items():
self.emotion_network[emotion] = [a for a in associations if a["memory_id"] != memory_id]
# 移除强度记录
if memory_id in self.memory_strengths:
del self.memory_strengths[memory_id]
logger.info(f"完全移除记忆: {memory_id}")
# ===== 测试用例 =====
if __name__ == "__main__":
print("=== 增强型记忆系统测试 ===")
# 初始化记忆系统
memory_system = MemorySystem("test_memory.json", max_memories=100)
# 创建上下文环境
morning_context = ContextIndex(
time_of_day="morning",
location="home",
weather="sunny",
social_context="alone",
activity="breakfast"
)
party_context = ContextIndex(
time_of_day="evening",
location="club",
weather="clear",
social_context="with_friends",
activity="dancing"
)
# 添加记忆
memory_system.store(
content={"type": "event", "description": "我的10岁生日派对", "location": "家里后院"},
tags=["childhood", "celebration"],
emotional_associations=[EmotionalAssociation(EmotionType.JOY, 0.9, "生日派对")],
context=party_context
)
memory_system.store(
content={"type": "event", "description": "高中毕业典礼", "location": "学校礼堂"},
tags=["education", "achievement"],
emotional_associations=[EmotionalAssociation(EmotionType.JOY, 0.8)],
context=ContextIndex(location="school")
)
memory_system.store(
content={"type": "trauma", "description": "目睹严重车祸", "location": "市中心"},
tags=["accident", "trauma"],
emotional_associations=[EmotionalAssociation(EmotionType.FEAR, 0.85)],
context=ContextIndex(location="downtown")
)
# 添加感知输入记忆
perception_input = {
"sensor_type": "textual",
"data": {"content": "早晨喝咖啡阅读新闻", "source": "user"},
"context": {
"location": "kitchen",
"time_of_day": "morning",
"weather": "sunny",
"social_context": "alone",
"activity": "breakfast"
},
"emotional_context": [
{"emotion": "JOY", "intensity": 0.6, "context": "享受咖啡"}
],
"tags": ["routine", "morning"],
"urgency": 2
}
recent_memory_id = memory_system.store_from_perception(perception_input)
# 模拟检索上下文
context = {
"tags": ["celebration"],
"keywords": ["生日"],
"time_recency": True,
"emotion_network": True,
"context": {
"time_of_day": "evening",
"social_context": "with_friends"
}
}
# 模拟情感状态
affective_state = {
"emotion": {
"current_emotion": "JOY",
"intensity": 0.7
}
}
# 检索记忆
print("\n检索与'庆祝'相关的记忆:")
results = memory_system.retrieve(context, affective_state)
for mem in results:
strength = memory_system.memory_strengths[mem['id']].current_strength()
print(f" - {mem['content']['description']} (强度: {strength:.2f})")
# 测试复习功能
print("\n需要复习的记忆:")
review_memories = memory_system.get_memories_for_review()
for mem in review_memories:
print(f" - {mem['memory']['content']['description']} (强度: {mem['strength']:.2f})")
# 强化特定记忆
print("\n强化近期记忆:")
memory_system.reinforce_memory(recent_memory_id)
# 获取系统统计
stats = memory_system.get_stats()
print("\n系统统计:")
print(f"总记忆数: {stats['total_memories']}")
print(f"平均强度: {stats['avg_strength']:.2f}")
print(f"弱记忆数: {stats['weak_memories']}")
print(f"需要复习的记忆数: {stats['next_review_count']}")
# 获取时间线视图
print("\n最近7天记忆时间线:")
timeline = memory_system.get_memory_timeline(days=7)
for day in timeline:
print(f"\n{day['date']}:")
for mem in day["memories"]:
print(f" - {mem['content_preview']} (强度: {mem['strength']:.2f})")
# 安全关闭
memory_system.shutdown()
```
## 主要优化点
### 1. 记忆持久化
```python
def _save_to_storage(self):
"""保存记忆到文件"""
data = {
"memories": self.memories,
"memory_strengths": {
mem_id: {
"base": strength.base,
"decay_rate": strength.decay_rate,
...
}
for mem_id, strength in self.memory_strengths.items()
}
}
with open(self.storage_path, "w") as f:
json.dump(data, f, indent=2)
```
- 添加了JSON文件存储/加载功能
- 自动保存机制确保数据不丢失
- 启动时自动加载历史记忆
### 2. 上下文环境索引
```python
class ContextIndex:
location: str = ""
time_of_day: str = ""
weather: str = ""
social_context: str = ""
activity: str = ""
# 在MemorySystem中
self.contextual_index = defaultdict(list) # 上下文环境索引
# 索引上下文环境
if context:
if context.location:
self.contextual_index[f"location:{context.location}"].append(memory_id)
if context.time_of_day:
self.contextual_index[f"time:{context.time_of_day}"].append(memory_id)
# ...
```
- 新增`ContextIndex`类记录环境上下文
- 支持位置、时间、天气、社交环境和活动索引
- 显著提升记忆检索的相关性
### 3. 自动维护系统
```python
def _maintenance_loop(self):
"""维护线程循环"""
while self._running:
time.sleep(300)
self.decay_memories(decay_factor=0.01)
self.forget_weak_memories(threshold=0.1)
self._save_to_storage()
```
- 后台线程自动执行记忆衰减和清理
- 定期保存记忆状态
- 确保系统长期稳定运行
### 4. 感知输入集成
```python
def store_from_perception(self, perception_input: Dict) -> str:
"""从感知输入创建记忆"""
content = {
"type": perception_input.get("sensor_type", "unknown"),
"description": perception_input.get("data", {}).get("content", ""),
...
}
# 提取情感关联
emotional_associations = []
if "emotional_context" in perception_input:
for emo_ctx in perception_input["emotional_context"]:
emotional_associations.append(...)
# 创建上下文索引
context = ContextIndex(...)
return self.store(...)
```
- 专为感知输入设计的记忆存储方法
- 自动提取情感关联和环境上下文
- 无缝集成到认知架构中
### 5. 记忆容量管理
```python
def _forget_weakest(self, count: int = 10):
"""遗忘最弱的记忆"""
if len(self.memories) <= count:
return
# 获取所有记忆的强度
memory_strengths = []
for mem in self.memories:
strength = self.memory_strengths[mem["id"]].current_strength()
memory_strengths.append((mem["id"], strength))
# 按强度排序并遗忘最弱的
memory_strengths.sort(key=lambda x: x[1])
to_forget = [mem_id for mem_id, _ in memory_strengths[:count]]
...
```
- 自动管理记忆容量
- 当达到最大记忆数时遗忘最弱记忆
- 防止系统资源耗尽
### 6. 情感网络增强
```python
def _get_related_emotions(self, base_emotion: str) -> List[str]:
"""获取与基础情感相关的情感"""
emotion_groups = {
"JOY": ["JOY", "SURPRISE", "TRUST", "ANTICIPATION"],
"FEAR": ["FEAR", "DISGUST", "SADNESS"],
...
}
return emotion_groups.get(base_emotion.upper(), [])
```
- 扩展情感类型(新增ANTICIPATION, TRUST等)
- 更复杂的情感关联网络
- 提升情感相关记忆的检索准确性
## 系统整合建议
### 1. 与意识层整合
```python
# 在conscious_layer.py中
from conscious_memory import MemorySystem
class ConsciousLayer:
def __init__(self):
self.memory_system = MemorySystem()
def process_input(self, stimulus):
# 存储到记忆系统
memory_id = self.memory_system.store_from_perception(stimulus)
# 检索相关记忆
context = {"tags": ["important"]}
related_memories = self.memory_system.retrieve(context, self.current_affective_state)
```
### 2. 定期复习机制
```python
def review_memories(self):
"""定期复习记忆"""
memories_to_review = self.memory_system.get_memories_for_review()
for mem in memories_to_review:
# 显示记忆内容
self.display_memory(mem["memory"])
# 强化记忆
self.memory_system.reinforce_memory(mem["memory"]["id"])
# 强化相关记忆
self.memory_system.reinforce_related_memories(mem["memory"]["id"])
```
## 优化后优势
1. **持久化存储**:记忆不会因系统重启而丢失
2. **上下文感知**:基于环境因素提升记忆检索准确性
3. **自维护系统**:后台自动管理记忆强度和容量
4. **无缝集成**:专为感知输入设计的记忆存储方法
5. **情感智能**:增强的情感网络提升关联记忆检索
6. **容量管理**:智能遗忘机制防止资源耗尽
7. **复习系统**:基于间隔重复的记忆强化机制
这个优化版本显著提升了记忆系统的实用性、稳定性和集成能力,为认知架构提供了可靠的长期记忆支持。