feat(memory): complete M.2-M.5 memory upgrade phases with tests

- M.2: ForgettingCurve, MemoryDecay, MemoryReinforcement (selective forgetting)
- M.3: DailyDigestGenerator, ReminderScheduler, ProactiveInformer (proactive reminders)
- M.4: MemoryExtractor with LLM-based memory extraction from conversations
- M.5: MemoryRecallInjector with token budget control for prompt injection
- All phases include comprehensive unit tests (109 tests passing)
- Updated checklist.md to mark all tasks complete
This commit is contained in:
2026-04-05 14:09:51 +08:00
parent 9bfa0dcc11
commit 11160ec4d2
22 changed files with 4117 additions and 186 deletions

View File

@@ -20,6 +20,9 @@ from app.services.memory.frequency_tracker import FrequencyTracker
from app.services.memory.emotion_analyzer import EmotionAnalyzer
from app.services.memory.impact_evaluator import ImpactEvaluator
from app.services.memory.importance_scorer import ImportanceScorer
from app.services.memory.forgetting_curve import ForgettingCurve
from app.services.memory.memory_decay import MemoryDecay
from app.services.memory.reinforcement import MemoryReinforcement
from app.config import settings as _settings
try:
@@ -370,13 +373,15 @@ async def recall_user_memories(
async def _mark_memories_recalled(db: AsyncSession, memories: list[UserMemory]) -> None:
"""Mark memories as recalled and update importance score"""
"""Mark memories as recalled and update importance score + reinforce them."""
from app.services.memory.frequency_tracker import FrequencyTracker
from app.services.memory.importance_scorer import ImportanceScorer
from app.services.memory.reinforcement import MemoryReinforcement
recalled_at = datetime.now(UTC)
tracker = FrequencyTracker()
scorer = ImportanceScorer()
reinforcement = MemoryReinforcement()
updated = False
for memory in memories:
@@ -387,6 +392,10 @@ async def _mark_memories_recalled(db: AsyncSession, memories: list[UserMemory])
# Update importance score on recall
scorer.update_memory_importance(memory)
# M.2: Reinforce memory on recall (reset decay, increment frequency)
reinforcement.trigger(memory)
updated = True
if updated:
@@ -653,3 +662,77 @@ async def update_memory(
except Exception as e:
print(f"Mem0 update error: {e}")
return False
# ———— M.2: 遗忘曲线处理 ————
async def process_memory_decay(db: AsyncSession, user_id: str) -> dict:
"""
处理用户所有记忆的衰减:
1. 计算每条记忆的 decay_score
2. 归档 decay < 0.2 的记忆
3. 降权 decay < 0.5 的记忆
"""
from sqlalchemy import select, update
result = await db.execute(
select(UserMemory).where(
UserMemory.user_id == user_id,
UserMemory.is_archived == False,
)
)
memories = list(result.scalars().all())
archived_count = 0
deprioritized_count = 0
curve = ForgettingCurve()
decay_mgr = MemoryDecay()
for memory in memories:
evaluation = decay_mgr.evaluate(memory)
decay_score = evaluation["decay_score"]
# Update decay_score on the memory
memory.decay_score = decay_score
if evaluation["should_archive"]:
decay_mgr.archive_memory(memory)
archived_count += 1
elif evaluation["should_deprioritize"]:
decay_mgr.deprioritize_memory(memory)
deprioritized_count += 1
if archived_count > 0 or deprioritized_count > 0:
await db.commit()
return {
"archived": archived_count,
"deprioritized": deprioritized_count,
"total": len(memories),
}
async def process_weekly_reinforcement(db: AsyncSession, user_id: str) -> int:
"""
每周自动强化高重要性记忆。
Returns number of reinforced memories.
"""
from sqlalchemy import select
result = await db.execute(
select(UserMemory).where(
UserMemory.user_id == user_id,
UserMemory.importance_level == "high",
UserMemory.is_archived == False,
)
)
memories = list(result.scalars().all())
reinforcement = MemoryReinforcement()
reinforced = reinforcement.auto_reinforce(memories)
if reinforced:
await db.commit()
return len(reinforced)