# Phase M.2：遗忘曲线系统

日期：2026-04-04
状态：规划中
依赖：M.1 (重要性评分)
工作量：3 天

---

## 1. 本阶段目的

实现「选择性遗忘」机制，让 Jarvis 知道「什么可以忘记」。

核心问题：
- 冷门知识不应该一直占存储
- 但不能直接删，要有归档机制
- 重要记忆应该被强化，不容易忘

---

## 2. 核心架构

```
┌─────────────────────────────────────────────────────────────┐
│                  ForgettingCurve                           │
├─────────────────────────────────────────────────────────────┤
│  decay_score = exp(-time_since_access / half_life)        │
│                                                             │
│  遗忘策略:                                                  │
│  - decay_score < 0.2 → 归档到 cold_storage                │
│  - decay_score < 0.5 → 降权，不参与主动提醒                 │
│  - importance_level=high → 半衰期延长 3x                    │
└─────────────────────────────────────────────────────────────┘
```

---

## 3. 艾宾浩斯遗忘曲线模型

### 3.1 基础遗忘曲线

```
保留率
  100% |████████████
   80% |██████████
   60% |███████
   40% |█████
   20% |██
    0% |________________________ 时间
         1天  7天  30天  90天
```

### 3.2 Jarvis 遗忘策略

```python
# 基础半衰期：30 天
BASE_HALF_LIFE_DAYS = 30

# 重要性影响半衰期
if importance_level == "high":
    half_life = BASE_HALF_LIFE_DAYS * 3  # 90 天
elif importance_level == "medium":
    half_life = BASE_HALF_LIFE_DAYS * 1  # 30 天
else:
    half_life = BASE_HALF_LIFE_DAYS * 0.5  # 15 天

# 遗忘分数
decay_score = exp(-days_since_access / half_life)
```

---

## 4. 核心文件

### 4.1 新增文件

| 文件 | 职责 |
|------|------|
| `services/memory/forgetting_curve.py` | 遗忘曲线计算 |
| `services/memory/memory_decay.py` | 记忆衰减处理 |
| `services/memory/reinforcement.py` | 记忆强化触发 |

### 4.2 修改文件

| 文件 | 修改内容 |
|------|---------|
| `models/memory.py` | 增加 decay_score, is_archived, last_accessed_at 字段 |
| `services/memory_service.py` | 集成遗忘逻辑 |

---

## 5. API 设计

### 5.1 ForgettingCurve

```python
class ForgettingCurve:
    def calculate_decay(self, memory: UserMemory) -> float:
        """返回 0.0-1.0 的保留分数"""
        
    def should_archive(self, memory: UserMemory) -> bool:
        """是否应该归档"""
        
    def should_deprioritize(self, memory: UserMemory) -> bool:
        """是否应该降权（不参与主动提醒）"""
```

### 5.2 Reinforcement

```python
class MemoryReinforcement:
    def trigger(self, memory_id: int) -> None:
        """被召回时触发强化"""
        # 频率 +1
        # decay_score 重置
        
    def auto_reinforce(self, user_id: int) -> None:
        """定期自动强化高重要性记忆"""
        # 每周检查，对 high 级别记忆做轻量强化
```

---

## 6. 归档机制

### 6.1 热/冷存储分离

```python
# 热存储：活跃记忆，参与检索和主动提醒
HOT_MEMORIES = []

# 冷存储：归档记忆，不参与主动提醒，按需恢复
COLD_MEMORIES = []
```

### 6.2 归档恢复

```python
async def restore_from_archive(self, memory_id: int) -> UserMemory:
    """从归档恢复记忆"""
    # 恢复后 decay_score 重置为 0.8
    # 重新加入热存储
```

---

## 7. 调度任务

### 7.1 每日遗忘检查

```python
# 每天凌晨执行
@scheduler.scheduled_task("cron", hour=3)
async def daily_forgetting_check():
    """每日遗忘检查"""
    # 1. 计算所有记忆的 decay_score
    # 2. 归档 decay < 0.2 的记忆
    # 3. 降权 decay < 0.5 的记忆
    # 4. 强化被召回的记忆
```

### 7.2 每周自动强化

```python
@scheduler.scheduled_task("cron", day_of_week="mon", hour=4)
async def weekly_reinforcement():
    """每周自动强化"""
    # 对 high 重要性记忆做轻量强化
    # frequency_count *= 1.1 (上限 10)
```

---

## 8. 测试设计

### 8.1 遗忘曲线测试

```python
def test_decay_after_30_days():
    memory = create_memory(last_accessed_at=days_ago(30))
    decay = curve.calculate_decay(memory)
    assert 0.4 < decay < 0.6  # 约 50% 保留

def test_high_importance_slower_decay():
    high = create_memory(importance_level="high", last_accessed_at=days_ago(30))
    low = create_memory(importance_level="low", last_accessed_at=days_ago(30))
    assert curve.calculate_decay(high) > curve.calculate_decay(low)
```

### 8.2 归档测试

```python
def test_archive_low_decay():
    memory = create_memory(decay_score=0.15)
    assert curve.should_archive(memory) == True

def test_restore_from_archive():
    memory = service.restore_from_archive(memory_id)
    assert memory.is_archived == False
    assert memory.decay_score > 0.5
```

---

## 9. 验收标准

| 标准 | 说明 |
|------|------|
| 遗忘曲线正确 | 30 天后 decay ≈ 0.5 |
| 高重要性记忆衰减慢 | high 级别衰减速度是 low 的 1/6 |
| 归档正常 | decay < 0.2 自动归档 |
| 恢复正常 | 归档记忆可以恢复 |
| 调度任务正常 | 每日检查、周强化执行 |
| 单元测试覆盖率 | > 80% |

---

## 10. 工作量估算

| 任务 | 工作量 |
|------|--------|
| ForgettingCurve | 0.5 天 |
| MemoryDecay | 0.5 天 |
| Reinforcement | 0.5 天 |
| 归档机制 | 0.5 天 |
| 调度任务 | 0.5 天 |
| 测试 | 0.5 天 |
| **合计** | **3 天** |
