Files
dreamweaver/.claude/specs/memory-intelligence/MEMORY-INTELLIGENCE-PRD.md
zhangtuo c82d408ea1 feat: add HA infrastructure, CI/CD pipeline, and Redis/Celery hardening
- Add docker-compose.ha.yml for PostgreSQL/Redis HA setup with Patroni and Sentinel
- Add docker-compose.prod.yml for production deployment
- Add GitHub Actions CI/CD workflow (build.yml)
- Add install.cmd for Windows one-click setup
- Harden Redis connection with retry logic and health checks
- Add Celery HA config with Redis Sentinel support
- Add HA operations runbook
- Update README with deployment and architecture docs
- Move landing page spec to .claude/specs/design/
- Update memory intelligence PRD
2026-02-28 14:57:02 +08:00

542 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 记忆智能系统 PRD
## 概述
**功能名称**: 记忆智能 (Memory Intelligence)
**版本**: v1.1
**优先级**: Phase 2.5 (体验增强后、社区化前)
**目标用户**: 家长 + 3-8 岁儿童
**更新记录**: 2025-01-22 合并 `backend/docs/memory_system_prd.md`
### 核心愿景
将当前的"数据存储"升级为有温度的**"情感连接系统"**。
我们不只是在记住数据,而是在**维护孩子与故事世界的关系**。让每一个故事不再是孤立的碎片,而是构建孩子专属"故事宇宙"的砖瓦。
### 核心价值
让 DreamWeaver 从"故事生成工具"进化为"懂孩子的故事伙伴"
- **记住孩子**: 偏好、成长阶段、兴趣变化
- **延续故事**: 角色、世界观跨故事延续
- **主动关怀**: 适时推送个性化故事建议
### 产品痛点与解决方案
| 用户角色 | 核心痛点 | 解决方案 | 预期价值 |
|---------|---------|---------|---------|
| **孩子** | "上次的小兔子怎么不认识我了?" 故事之间缺乏连续性。 | **角色一致性与记忆注入** 故事开头主动提及往事,角色性格延续。 | 建立情感依恋,提升沉浸感。 |
| **家长** | "这App除了生成故事还能干嘛" 无法感知产品的长期教育价值。 | **显性化成长轨迹** 词汇量统计、主题变化、成就徽章可视化。 | 提高付费意愿,提供社交货币。 |
| **平台** | 用户用完即走,缺乏留存壁垒。 | **沉没成本与情感资产** 积累的记忆越多,越舍不得离开。 | 提升长期留存率 (LTV)。 |
---
## 一、功能模块
### 1.0 记忆分层模型
#### 层级 1: 核心档案 (Identity Layer)
*性质:永久、静态、显性*
- **数据**: 姓名、年龄、性别
- **输入**: 家长在 Onboarding 阶段手动输入
- **作用**: 决定故事的基础适龄性和称呼
#### 层级 2: 故事宇宙 (Universe Layer)
*性质:长期、动态积累、半显性*
- **主角设定**: 姓名、性格特征(勇敢/害羞)、外貌特征(戴眼镜/卷发)
- **常驻配角**: 从随机故事中涌现出的固定伙伴(如"爱吃胡萝卜的松鼠奇奇"
- **世界观**: 故事发生的背景(魔法森林、未来城市、海底世界)
- **成就系统**: 孩子获得的虚拟奖励(勇气勋章、小小探险家)
#### 层级 3: 工作记忆 (Working Memory)
*性质:短期、自动衰减、隐性*
- **关键情节**: 最近 3 个故事的结局和核心冲突
- **情感标记**: 孩子对特定内容的反应(根据"重播"、"跳过"推断)
- **新学词汇**: 故事中出现的高级词汇
### 1.1 孩子档案系统 (Child Profile)
| 字段 | 类型 | 说明 |
|------|------|------|
| 基础信息 | 显式 | 姓名、年龄、性别 |
| 兴趣标签 | 显式+隐式 | 恐龙、公主、太空、动物等 |
| 成长主题 | 显式 | 当前关注:勇气/分享/独立等 |
| 阅读偏好 | 隐式 | 故事长度、风格、复杂度 |
| 互动历史 | 隐式 | 喜欢的故事、跳过的故事 |
**数据来源**:
- 显式: 家长主动填写
- 隐式: 系统从使用行为中学习
### 1.2 故事宇宙记忆 (Story Universe)
跨故事保持连续性的元素:
| 元素 | 说明 | 示例 |
|------|------|------|
| 主角设定 | 孩子的故事化身 | "小明是个爱冒险的男孩" |
| 常驻角色 | 反复出现的配角 | 魔法猫咪"星星"、智慧老树 |
| 世界观 | 故事发生的宇宙 | 梦幻森林、星际学院 |
| 成就系统 | 主角的成长轨迹 | "学会了勇敢"、"交到新朋友" |
**记忆结构字段**:
- `protagonist` / `recurring_characters` / `world_settings` / `achievements`JSON 结构)
- “延续上一个故事”默认选最近更新的宇宙(按 `updated_at` 倒序)
### 1.3 主动推送系统 (Proactive Push)
| 触发类型 | 条件 | 推送内容 |
|----------|------|----------|
| 时间触发 | 睡前时段 (19:00-21:00) | "今晚想听什么故事?" |
| 事件触发 | 节日/生日 | 主题故事推荐 |
| 行为触发 | 3天未使用 | 召回提醒 |
| 成长触发 | 年龄变化 | 难度升级建议 |
**优先级与抑制**:
- 优先级:事件 > 成长 > 行为 > 时间
- 抑制当天已推送不再触发静默时段21:00-09:00延迟用户关闭推送则不触发
---
## 二、用户故事
### US-1: 创建孩子档案
```
作为家长
我想要创建孩子的专属档案
以便系统生成更适合孩子的故事
```
**验收标准**:
- [ ] 可填写孩子基础信息(姓名、年龄、性别)
- [ ] 可选择兴趣标签(多选)
- [ ] 可设置当前成长主题
- [ ] 支持多个孩子档案切换
### US-2: 故事角色延续
```
作为家长
我想要故事中的角色能在新故事中再次出现
以便孩子感受到故事的连续性
```
**验收标准**:
- [ ] 生成故事时可选择"延续上一个故事"
- [ ] 系统自动带入主角设定和常驻角色
- [ ] 新故事引用之前的"成就"
### US-3: 睡前故事提醒
```
作为家长
我想要在睡前时段收到故事推荐
以便养成固定的亲子阅读习惯
```
**验收标准**:
- [ ] 可设置提醒时间
- [ ] 推送包含个性化故事建议
- [ ] 可一键进入故事生成
---
## 三、数据模型
### 3.1 孩子档案表 (child_profiles)
```sql
CREATE TABLE child_profiles (
id UUID PRIMARY KEY,
user_id UUID REFERENCES users(id),
name VARCHAR(50) NOT NULL,
birth_date DATE,
gender VARCHAR(10),
interests JSONB DEFAULT '[]',
growth_themes JSONB DEFAULT '[]',
reading_preferences JSONB DEFAULT '{}',
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
```
### 3.2 故事宇宙表 (story_universes)
```sql
CREATE TABLE story_universes (
id UUID PRIMARY KEY,
child_profile_id UUID REFERENCES child_profiles(id),
name VARCHAR(100) NOT NULL,
protagonist JSONB NOT NULL,
recurring_characters JSONB DEFAULT '[]',
world_settings JSONB DEFAULT '{}',
achievements JSONB DEFAULT '[]',
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
```
### 3.3 推送配置表 (push_configs)
```sql
CREATE TABLE push_configs (
id UUID PRIMARY KEY,
user_id UUID REFERENCES users(id),
child_profile_id UUID REFERENCES child_profiles(id),
push_time TIME,
push_days INTEGER[], -- 0-6 表示周日到周六
enabled BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW()
);
```
### 3.4 推送事件表 (push_events)
```sql
CREATE TABLE push_events (
id UUID PRIMARY KEY,
user_id UUID NOT NULL,
child_profile_id UUID NOT NULL,
trigger_type VARCHAR(20) NOT NULL, -- time/event/behavior/growth
sent_at TIMESTAMP NOT NULL,
status VARCHAR(20) NOT NULL, -- sent/failed/suppressed
reason TEXT
);
```
### 3.5 记忆条目表 (memory_items)
用于存储“可解释、可控”的记忆条目(兴趣偏好、成长主题、常驻角色、关键事件等),并支持时序衰减。
```sql
CREATE TABLE memory_items (
id UUID PRIMARY KEY,
child_profile_id UUID NOT NULL,
universe_id UUID,
type VARCHAR(50) NOT NULL, -- interest/growth/character/event等
value JSONB NOT NULL, -- 结构化内容
base_weight FLOAT DEFAULT 1.0, -- 初始权重
last_used_at TIMESTAMP, -- 最近使用时间
created_at TIMESTAMP DEFAULT NOW(),
ttl_days INTEGER -- 可选:过期天数
);
```
---
## 四、API 设计
### 4.1 孩子档案 API
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/profiles` | 获取当前用户的所有孩子档案 |
| POST | `/api/profiles` | 创建孩子档案 |
| GET | `/api/profiles/{id}` | 获取单个档案详情 |
| PUT | `/api/profiles/{id}` | 更新档案 |
| DELETE | `/api/profiles/{id}` | 删除档案 |
### 4.2 故事宇宙 API
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/profiles/{id}/universes` | 获取孩子的故事宇宙列表 |
| POST | `/api/profiles/{id}/universes` | 创建新宇宙 |
| GET | `/api/universes/{id}` | 获取宇宙详情 |
| PUT | `/api/universes/{id}` | 更新宇宙设定 |
| POST | `/api/universes/{id}/achievements` | 添加成就 |
### 4.3 推送配置 API
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/push-configs` | 获取推送配置 |
| PUT | `/api/push-configs` | 更新推送配置 |
---
## 五、Prompt 工程
### 5.1 带记忆的故事生成 Prompt
```
你是一个专业的儿童故事作家。请为以下孩子创作一个故事:
【孩子档案】
- 姓名: {child_name}
- 年龄: {age}岁
- 兴趣: {interests}
- 当前成长主题: {growth_theme}
【故事宇宙】
- 主角设定: {protagonist}
- 常驻角色: {recurring_characters}
- 世界观: {world_settings}
- 已获成就: {achievements}
【本次创作要求】
- 关键词: {keywords}
- 延续之前的故事世界观
- 让主角在故事中有新的成长
请创作一个适合{age}岁儿童的故事,约{word_count}字。
```
### 5.2 智能开场白 (Memory Injection)
在生成新故事时Prompt 必须包含一段"记忆唤醒"指令:
- **示例**: "小明,还记得上周我们帮小松鼠找回了松果吗?今天,小松鼠带来了一位新朋友..."
- **策略**: 提取权重最高的 Top 3 记忆注入 Prompt
### 5.3 成就提取 Prompt
```
请分析以下故事,提取主角获得的成长/成就:
【故事内容】
{story_content}
请以JSON格式返回
{
"achievements": [
{"type": "勇气", "description": "克服了对黑暗的恐惧"},
{"type": "友谊", "description": "帮助了迷路的小兔子"}
]
}
```
---
## 六、前端设计
### 6.1 孩子档案页面
```
┌─────────────────────────────────────┐
│ 我的宝贝 [+添加] │
├─────────────────────────────────────┤
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │ 👦 │ │ 👧 │ │ + │ │
│ │小明 │ │小红 │ │添加 │ │
│ │5岁 │ │3岁 │ │ │ │
│ └─────┘ └─────┘ └─────┘ │
└─────────────────────────────────────┘
```
### 6.2 档案详情页
```
┌─────────────────────────────────────┐
│ ← 小明的档案 [编辑] │
├─────────────────────────────────────┤
│ 基础信息 │
│ 姓名: 小明 年龄: 5岁 性别: 男 │
├─────────────────────────────────────┤
│ 兴趣爱好 │
│ [恐龙] [太空] [机器人] │
├─────────────────────────────────────┤
│ 成长主题 │
│ ○ 勇气 ● 分享 ○ 独立 ○ 友谊 │
├─────────────────────────────────────┤
│ 故事宇宙 │
│ ┌─────────────────────────────┐ │
│ │ 🌟 星际冒险 │ │
│ │ 主角: 小明船长 │ │
│ │ 伙伴: 机器人小七、外星猫咪 │ │
│ │ 成就: 3个 │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
```
### 6.3 故事生成时选择档案
```
┌─────────────────────────────────────┐
│ 为谁创作故事? │
├─────────────────────────────────────┤
│ ● 小明 (5岁) │
│ ○ 小红 (3岁) │
│ ○ 不使用档案 │
├─────────────────────────────────────┤
│ 选择故事宇宙 │
│ ● 星际冒险 (延续上次) │
│ ○ 创建新宇宙 │
├─────────────────────────────────────┤
│ [下一步: 输入关键词] │
└─────────────────────────────────────┘
```
---
## 七、技术实现要点
### 7.1 隐式偏好学习
```python
# 基于用户行为更新偏好
async def update_implicit_preferences(
child_id: UUID,
story: Story,
interaction: Interaction # 完整阅读/跳过/重复播放
):
profile = await get_child_profile(child_id)
if interaction == "completed":
# 增加相关标签权重
for tag in story.tags:
profile.reading_preferences[tag] = \
profile.reading_preferences.get(tag, 0) + 1
elif interaction == "skipped":
# 降低相关标签权重
for tag in story.tags:
profile.reading_preferences[tag] = \
profile.reading_preferences.get(tag, 0) - 0.5
```
### 7.2 成就自动提取
故事生成完成后,异步调用 LLM 提取成就(以 `type + description` 去重):
```python
@celery.task
async def extract_achievements(story_id: UUID, universe_id: UUID):
story = await get_story(story_id)
universe = await get_universe(universe_id)
achievements = await llm.extract_achievements(story.content)
universe.achievements.extend(achievements)
await save_universe(universe)
```
### 7.3 推送调度
使用 Celery Beat 定时检查推送:
```python
@celery.task
def check_push_notifications():
current_time = datetime.now().time()
current_day = datetime.now().weekday()
configs = PushConfig.query.filter(
PushConfig.enabled == True,
PushConfig.push_time <= current_time,
current_day.in_(PushConfig.push_days)
).all()
for config in configs:
send_push_notification.delay(config.user_id, config.child_profile_id)
```
**执行约束**:
- 同一孩子每天最多 1 次推送
- 推送前查询 `push_events` 去重,成功/抑制均需记录
### 7.4 时序衰减与记忆评分
**目标**:让“越新的记忆影响越大”,避免旧偏好长期干扰。
**默认实现(推荐)**:查询时动态计算分数,不直接修改数据库。
- 记忆分数:`score = base_weight × decay(Δt)`
- 衰减示例分段0-7 天 1.08-30 天 0.731-90 天 0.490 天后 0.2
- 读取时按 `score` 排序,选 Top N 进入 Prompt
**可选实现**:定期批处理降权
- 每日/每周批量更新 `base_weight`
- 适合数据量大、读多写少的场景
**RAG 场景的衰减用法**
- 语义相似度分数 × 时间衰减
- 可加时间窗口过滤(如仅取最近 90 天)
**删除策略(默认不删)**
- 默认只降权,不主动删除
- 可选:对低权重且 180 天未使用的条目执行 TTL 清理
---
## 八、关键功能特性
### 8.1 成长时间轴 (Growth Timeline)
一个可视化的 H5 页面或 App 模块,以时间轴形式展示里程碑:
- 🌟 **初次相遇**: 创建角色的第一天
- 📖 **阅读打卡**: 累计阅读 10/50/100 本
- 🏅 **获得成就**: 获得"诚实勋章"
- 🧠 **能力解锁**: 第一次阅读"科幻"题材
### 8.2 成就仪式感 (Achievement Ceremony)
- **触发**: 故事生成并分析后,如果获得新成就
- **表现**: 弹窗动画 + 音效 + "恭喜获得 [勇气] 徽章"
- **分享**: 允许生成带二维码的成就海报
---
## 九、记忆类型扩展
| 类型 Key | 描述 | 来源 | 过期策略 |
|---------|------|------|---------|
| `recent_story` | 最近读过的故事梗概 | 阅读事件 | 30天衰减 |
| `favorite_character` | 孩子喜欢的角色 | 重播/高评分 | 长期有效 |
| `scary_element` | 孩子害怕/不喜欢的元素 | 跳过/负反馈 | 长期有效 (避雷) |
| `vocabulary_growth` | 新掌握的词汇 | 故事分析 | 90天衰减 |
| `emotional_highlight` | 高光时刻 (如: 特别开心的情节) | 互动数据 | 60天衰减 |
---
## 十、里程碑
### Phase 1: 基础建设 (v0.3.0)
- [x] 数据库 `MemoryItem` 表 (已存在)
- [ ] 扩展 `MemoryItem` 类型字段,支持更多维度
- [ ] 优化 `_build_memory_context`,支持更自然的 Prompt 注入
- [ ] 前端:简单的"近期回忆"展示列表
### M1: 孩子档案基础
- [ ] 数据库模型
- [ ] CRUD API
- [ ] 前端档案管理页面
- [ ] 故事生成时选择档案
### M2: 故事宇宙
- [ ] 宇宙数据模型
- [ ] Prompt 集成
- [ ] 成就自动提取
- [ ] 前端宇宙管理
### M3: 主动推送
- [ ] 推送配置 API
- [ ] Celery Beat 调度
- [ ] 推送通知集成 (Web Push / 微信)
### M4: 隐式学习
- [ ] 行为埋点
- [ ] 偏好学习算法
- [ ] 推荐优化
### Phase 2: 可视化与成就 (v0.4.0)
- [ ] 实现"成就提取器" (Achievement Extractor) 的闭环通知
- [ ] 前端:开发"我的成就"和"成长时间轴"页面
- [ ] 增加故事开场白的动态生成逻辑
### Phase 3: 深度智能 (v0.5.0+)
- [ ] 引入向量数据库,实现基于语义的记忆检索 (不仅是时间最近)
- [ ] 情感分析模型:分析用户行为推断情感倾向
---
## 十一、风险与应对
| 风险 | 影响 | 应对 |
|------|------|------|
| 隐私合规 | 高 | 儿童数据加密存储,家长授权机制 |
| 推送骚扰 | 中 | 默认关闭,用户主动开启 |
| 记忆膨胀 | 低 | 定期清理旧数据,限制宇宙数量 |
---
## 十二、相关文档
- [孩子档案数据模型](./CHILD-PROFILE-MODEL.md)
- [故事宇宙记忆结构](./STORY-UNIVERSE-MODEL.md)
- [主动推送触发规则](./PUSH-TRIGGER-RULES.md)