# Jarvis Memory 升级执行清单

日期：2026-04-04
状态：执行清单
升级方向：拟人化记忆系统

---

## 使用说明

- 完成前使用 `- [ ]`
- 完成后改成 `- [x]`
- Day M.2 默认依赖 Day M.1 的重要性评分完成后再推进
- Day M.3 默认依赖 Day M.1 和 M.2 完成后再推进
- Day M.4 依赖 Day M.1，可与 M.2/M.3 并行推进
- Day M.5 依赖 Day M.1 和 M.4 完成后再推进

---

## Day M.1：重要性评分系统（4天）

Day M.1 目标：让 Jarvis 知道「什么对你重要」。

### Task M.1.1：实现 FrequencyTracker

- [x] 新增 `backend/app/services/memory/frequency_tracker.py`

- [x] 实现 `FrequencyTracker` 类

- [x] 实现 `increment()` 方法
  ```python
  def increment(self, memory: UserMemory) -> UserMemory:
      memory.frequency_count += 1
      memory.last_recalled_at = datetime.now()
      return memory
  ```

- [x] 实现 `get_time_decay()` 方法

### Task M.1.2：实现 EmotionAnalyzer

- [x] 新增 `backend/app/services/memory/emotion_analyzer.py`

- [x] 实现 `EmotionAnalyzer` 类

- [x] 定义 `EMOTION_KEYWORDS` 字典
  ```python
  EMOTION_KEYWORDS = {
      "急": 1.0,
      "很重要": 0.9,
      "困扰": 0.8,
      "担心": 0.7,
      "想解决": 0.6,
      "无所谓": 0.1,
  }
  ```

- [x] 实现 `extract()` 方法 - 从文本提取情绪关键词

- [x] 实现 `calculate_score()` 方法 - 计算情绪分数

### Task M.1.3：实现 ImpactEvaluator

- [x] 新增 `backend/app/services/memory/impact_evaluator.py`

- [x] 实现 `ImpactEvaluator` 类

- [x] 实现 `evaluate()` 方法
  ```python
  def evaluate(self, memory: UserMemory) -> float:
      # 关联话题越多，影响面越大
      return min(1.0, len(memory.associated_topics) / IMPACT_THRESHOLD)
  ```

### Task M.1.4：实现 ImportanceScorer

- [x] 新增 `backend/app/services/memory/importance_scorer.py`

- [x] 实现 `ImportanceScorer` 类

- [x] 实现 `calculate_score()` 综合评分方法
  ```python
  def calculate_score(self, memory: UserMemory) -> float:
      frequency = self.tracker.get_frequency_score(memory) * 0.35
      recency = self.tracker.get_recency_score(memory) * 0.20
      emotion = self.emotion_analyzer.calculate_score(memory) * 0.25
      impact = self.impact_evaluator.evaluate(memory) * 0.20
      return frequency + recency + emotion + impact
  ```

- [x] 实现 `get_importance_level()` 方法

- [x] 实现 `should_escalate()` 方法

### Task M.1.5：修改 UserMemory 模型

- [x] 修改 `backend/app/models/memory.py`

- [x] 增加字段：
  ```python
  frequency_count: int = 0
  last_recalled_at: DateTime = None
  emotion_tags: list[str] = []
  importance_score: float = 0.5
  importance_level: str = "medium"
  associated_topics: list[str] = []
  ```

### Task M.1.6：集成到 MemoryService

- [x] 修改 `backend/app/services/memory_service.py`

- [x] 集成 `ImportanceScorer`

- [x] 修改 `add_memory()` 方法计算重要性

- [x] 修改 `recall_memories()` 方法按重要性排序

### Task M.1.7：补测试

- [x] 新增 `backend/tests/services/test_importance_scorer.py`

- [x] 测试频率追踪

- [x] 测试情绪分析

- [x] 测试重要性评分

- [x] 测试重要性等级划分

### Day M.1 验收

- [x] 频率追踪正常（recall_count 每次 +1）
- [x] 情绪识别准确（「急」「很重要」等能识别）
- [x] 重要性分数正确（高频+情绪 = importance >= 0.8）
- [x] 评分影响排序（高重要性记忆排在前面）
- [x] 单元测试覆盖率 > 80%

---

## Day M.2：遗忘曲线系统（3天）

Day M.2 目标：让 Jarvis 知道「什么可以忘记」。

### Task M.2.1：实现 ForgettingCurve

- [x] 新增 `backend/app/services/memory/forgetting_curve.py`

- [x] 实现 `ForgettingCurve` 类

- [x] 实现 `calculate_decay()` 方法
  ```python
  def calculate_decay(self, memory: UserMemory) -> float:
      half_life = self.get_half_life(memory)
      days = (datetime.now() - memory.last_accessed_at).days
      return exp(-days / half_life)
  ```

- [x] 实现 `get_half_life()` 方法（重要性影响半衰期）

### Task M.2.2：实现 MemoryDecay

- [x] 新增 `backend/app/services/memory/memory_decay.py`

- [x] 实现 `MemoryDecay` 类

- [x] 实现 `should_archive()` 方法（decay < 0.2）

- [x] 实现 `should_deprioritize()` 方法（decay < 0.5）

- [x] 实现 `archive_memory()` 方法

- [x] 实现 `restore_from_archive()` 方法

### Task M.2.3：实现 MemoryReinforcement

- [x] 新增 `backend/app/services/memory/reinforcement.py`

- [x] 实现 `MemoryReinforcement` 类

- [x] 实现 `trigger()` 方法（召回时强化）

- [x] 实现 `auto_reinforce()` 方法（定期强化 high 级别）

### Task M.2.4：修改 UserMemory 模型

- [x] 修改 `backend/app/models/memory.py`

- [x] 增加字段：
  ```python
  decay_score: float = 1.0
  is_archived: bool = False
  last_accessed_at: DateTime = None
  archive_at: DateTime = None
  ```

### Task M.2.5：集成到 MemoryService

- [x] 修改 `backend/app/services/memory_service.py`

- [x] 集成 ForgettingCurve

- [x] 修改 recall_memories() 更新 last_accessed_at

- [x] 集成 MemoryReinforcement

### Task M.2.6：添加调度任务

- [x] 修改 `backend/app/services/scheduler_service.py`

- [x] 添加每日遗忘检查（cron: 03:00）

- [x] 添加每周强化任务（cron: 周一 04:00）

### Task M.2.7：补测试

- [x] 新增 `backend/tests/services/test_forgetting_curve.py`

- [x] 测试遗忘曲线计算

- [x] 测试高重要性记忆衰减慢

- [x] 测试归档/恢复

### Day M.2 验收

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

---

## Day M.3：主动提醒系统（6天）

Day M.3 目标：让 Jarvis 从「等用户问」变成「主动关心」。

### Task M.3.1：实现 DailyDigestGenerator

- [x] 新增 `backend/app/services/memory/daily_digest.py`

- [x] 实现 `DailyDigestGenerator` 类

- [x] 定义 `DailyDigest` 数据类

- [x] 实现 `generate()` 方法
  ```python
  async def generate(self, user_id: int, date: date = None) -> DailyDigest:
      # 1. 获取今日对话摘要
      # 2. 获取高重要性记忆
      # 3. 获取待解答问题
      # 4. 生成建议
  ```

- [x] 实现 `get_recent_digests()` 方法

### Task M.3.2：实现 ReminderScheduler

- [x] 新增 `backend/app/services/memory/reminder_scheduler.py`

- [x] 定义 `Reminder` 数据类

- [x] 实现 `ReminderScheduler` 类

- [x] 实现 `create_reminder()` 方法

- [x] 实现 `get_due_reminders()` 方法

- [x] 实现 `snooze()` 方法

- [x] 实现 `dismiss()` 方法

### Task M.3.3：实现 ProactiveInformer

- [x] 新增 `backend/app/services/memory/proactive_informer.py`

- [x] 实现 `ProactiveInformer` 类

- [x] 定义 `TRIGGERS` 配置

- [x] 定义 `INFORM_PROBABILITY` 配置

- [x] 实现 `should_inform()` 方法

- [x] 实现 `get_inform_message()` 方法

- [x] 实现 `check_and_inform()` 方法

### Task M.3.4：创建提醒数据模型

- [x] 修改数据库支持 `reminders` 表

- [x] 新增 `backend/app/models/reminder.py`

- [x] 或在现有模型文件中增加 Reminder 类

### Task M.3.5：集成到 MemoryService

- [x] 修改 `backend/app/services/memory_service.py`

- [x] 集成 DailyDigestGenerator

- [x] 集成 ProactiveInformer

- [x] 修改 recall_memories() 触发主动告知检查

### Task M.3.6：集成到 SchedulerService

- [x] 修改 `backend/app/services/scheduler_service.py`

- [x] 添加每日摘要生成（cron: 22:00）

- [x] 添加提醒检查任务（cron: 每 15 分钟）

### Task M.3.7：前端 - 每日摘要展示

- [x] 修改前端对话页面

- [x] 新增每日摘要卡片组件

- [x] 获取和展示今日摘要

### Task M.3.8：前端 - 主动提醒推送

- [x] 新增主动提醒 Toast 组件

- [x] 实现稍后/知道了按钮

- [x] 推送 WebSocket 集成

### Task M.3.9：补测试

- [x] 新增 `backend/tests/services/test_proactive_reminder.py`

- [x] 测试每日摘要生成

- [x] 测试提醒创建和调度

- [x] 测试主动告知概率

### Day M.3 验收

- [x] 每日摘要生成正常（22:00 自动生成）
- [x] 提醒创建正常（用户可创建提醒）
- [x] 提醒到期触发（定时推送）
- [x] 主动告知概率正确（按配置的概率触发）
- [x] 告知消息自然（像人说话，不生硬）
- [x] 用户可控制（可以关闭主动提醒）
- [x] 单元测试覆盖率 > 80%

---

## Day M.4：对话自动学习（3天）

Day M.4 目标：让记忆库自动从对话中积累内容，不需要用户手动触发。

### Task M.4.1：实现 MemoryExtractor

- [x] 新增 `backend/app/services/memory/memory_extractor.py`

- [x] 实现 `MemoryExtractor` 类

- [x] 实现 `extract_from_conversation()` 方法
  ```python
  async def extract_from_conversation(
      self, user_id: str, messages: list[Message]
  ) -> list[ExtractedMemory]:
  ```

- [x] 定义 LLM 提取 Prompt（结构化输出 JSON）
  - 提取类型：fact / preference / goal / pain_point / event
  - 只提取明确信息，不猜测

- [x] 实现 `deduplicate()` 方法
  - 相似度 > 0.85 视为重复，调用 `reinforce()` 而非新建

### Task M.4.2：集成触发点

- [x] 修改 `backend/app/routers/conversation.py`
  - 对话结束端点添加 `background_tasks.add_task(memory_extractor.extract_from_conversation, ...)`

- [x] 修改 `backend/app/services/scheduler_service.py`
  - 添加 30 分钟闲置对话检查任务

### Task M.4.3：补测试

- [x] 新增 `backend/tests/services/test_memory_extractor.py`
- [x] 测试提取准确性（fact/goal/pain_point 识别）
- [x] 测试去重逻辑（重复内容不新建）
- [x] 测试后台触发不阻塞响应

### Day M.4 验收

- [x] 对话结束后 30 秒内自动完成提取
- [x] fact/goal/pain_point 类型识别准确
- [x] 重复内容不新建，只强化原记忆
- [x] 提取为后台任务，不影响响应速度
- [x] 单元测试覆盖率 > 80%

---

## Day M.5：记忆召回注入（2天）

Day M.5 目标：让 LLM 在生成回答时真正「看到」用户的记忆，实现对话个性化。

### Task M.5.1：实现 MemoryRecallInjector

- [x] 新增 `backend/app/services/memory/recall_injector.py`

- [x] 实现 `MemoryRecallInjector` 类

- [x] 实现 `build_context()` 方法
  ```python
  async def build_context(
      self, user_id: str, current_message: str, token_budget: int = 800
  ) -> str:
  ```

- [x] 实现 `_rank()` 方法（语义相关性 × 重要性评分综合排序）

- [x] 实现 `_budget_select()` 方法（Token 预算控制）

- [x] 实现 `_format()` 方法（格式化为 system prompt 片段）

- [x] 记忆类型优先级配置
  - pain_point > goal > preference > fact > event

### Task M.5.2：集成到对话路由

- [x] 修改 `backend/app/routers/conversation.py`
  - 发消息时调用 `memory_injector.build_context()`
  - 将返回的 context 追加到 system prompt
  - 发送完成后后台触发记忆强化（frequency_count +1）

- [x] 修改 `backend/app/services/memory_service.py`
  - `recall_memories()` 返回时携带相似度分数（`similarity_score` 字段）

### Task M.5.3：补测试

- [x] 新增 `backend/tests/services/test_recall_injector.py`
- [x] 测试 Token 预算不超限
- [x] 测试已归档记忆不注入
- [x] 测试高优先级类型优先注入
- [x] 测试注入耗时 < 100ms

### Day M.5 验收

- [x] LLM 回答中能体现用户个人信息
- [x] 注入内容 ≤ 800 token
- [x] goal/pain_point 比 fact 更早注入
- [x] decay < 0.2 的已归档记忆不出现在 context 中
- [x] 注入耗时 < 100ms
- [x] 被召回的记忆 frequency_count +1
- [x] 单元测试覆盖率 > 80%

---

## 总验收清单

### Phase M.1-M.5 必须完成

- [x] 重要性评分系统正常工作
- [x] 遗忘曲线系统正常工作
- [x] 主动提醒系统正常工作
- [x] 对话自动学习正常工作（M.4）
- [x] 记忆召回注入正常工作（M.5）
- [x] 单元测试覆盖率 > 80%
- [x] 集成测试通过
- [x] 原有记忆功能无回退

---

## 总工作量估算

| Phase | 工作量 |
|-------|--------|
| M.1 重要性评分 | 4 天 |
| M.2 遗忘曲线 | 3 天 |
| M.3 主动提醒 | 6 天 |
| M.4 对话自动学习 | 3 天 |
| M.5 记忆召回注入 | 2 天 |
| **合计** | **18 天** |

---

## 产出清单

| 产出 | 对应 Phase |
|------|-----------|
| `services/memory/frequency_tracker.py` | M.1 |
| `services/memory/emotion_analyzer.py` | M.1 |
| `services/memory/impact_evaluator.py` | M.1 |
| `services/memory/importance_scorer.py` | M.1 |
| `services/memory/forgetting_curve.py` | M.2 |
| `services/memory/memory_decay.py` | M.2 |
| `services/memory/reinforcement.py` | M.2 |
| `services/memory/daily_digest.py` | M.3 |
| `services/memory/reminder_scheduler.py` | M.3 |
| `services/memory/proactive_informer.py` | M.3 |
| `services/memory/memory_extractor.py` | M.4 |
| `services/memory/recall_injector.py` | M.5 |
| `models/memory.py` 更新 | M.1, M.2 |
| `models/reminder.py` 新增 | M.3 |
| 前端摘要卡片 | M.3 |
| 前端提醒 Toast | M.3 |
| 单元测试 > 80% | M.1–M.5 |
| 集成测试通过 | M.1–M.5 |

---

## 与 Agent Phase 关系

| Agent Phase | Memory 协作内容 |
|-------------|----------------|
| Phase 1 | Memory 追踪用户交互频率 |
| Phase 2 | Memory 服务被 Librarian Agent 调用 |
| Phase 3 | 支持动态协作时的记忆共享 |
| Phase 4 | Memory 重要性可视化 |
| Phase 5 | 高级记忆关联分析 |

**Phase M 可与 Agent Phase 1-5 并行推进。**
