- Backend: FastAPI + SQLAlchemy + Celery (Python 3.11+) - Frontend: Vue 3 + TypeScript + Pinia + Tailwind - Admin Frontend: separate Vue 3 app for management - Docker Compose: 9 services orchestration - Specs: design prototypes, memory system PRD, product roadmap Cleanup performed: - Removed temporary debug scripts from backend root - Removed deprecated admin_app.py (embedded UI) - Removed duplicate docs from admin-frontend - Updated .gitignore for Vite cache and egg-info
4.8 KiB
4.8 KiB
记忆系统开发指南 (Development Guide)
本文档详细说明了 PRD 中定义的记忆系统的技术实现细节。
1. 数据库架构变更 (Schema Changes)
目前的 MemoryItem 表结构尚可,但需要增强字段以支持丰富的情感和元数据。
1.1 MemoryItem 表优化
建议使用 Alembic 进行迁移,增加以下字段或在 value JSON 中规范化以下结构:
# 建议在 models.py 中明确这些字段,或者严格定义 value 字段的 Schema
class MemoryItem(Base):
# ... 现有字段 ...
# 新增/规范化字段建议
# value 字段的 JSON 结构规范:
# {
# "content": "小兔子战胜了大灰狼", # 记忆的核心文本
# "keywords": ["勇敢", "森林"], # 用于检索的关键词
# "emotion": "positive", # 情感倾向: positive/negative/neutral
# "source_story_id": 123, # 来源故事 ID
# "confidence": 0.85 # 记忆置信度 (如果是 AI 自动提取)
# }
1.2 StoryUniverse 表优化 (成就系统)
目前的成就存储在 achievements JSON 字段中。为了支持更复杂的查询(如"获得勇气勋章的所有用户"),建议将其重构为独立关联表,或保持 JSON 但规范化结构。
当前 JSON 结构规范:
[
{
"id": "badge_courage_01",
"type": "勇气",
"name": "小小勇士",
"description": "第一次在故事中独自面对困难",
"icon_url": "badges/courage.png",
"obtained_at": "2023-10-27T10:00:00Z",
"source_story_id": 45
}
]
2. 核心逻辑实现
2.1 记忆注入逻辑 (Prompt Engineering)
修改 backend/app/api/stories.py 中的 _build_memory_context 函数。
目标: 生成一段自然的、不仅是罗列数据的 Prompt。
伪代码逻辑:
def format_memory_for_prompt(memories: list[MemoryItem]) -> str:
"""
将记忆项转换为自然语言 Prompt 片段。
"""
context_parts = []
# 1. 角色记忆
chars = [m for m in memories if m.type == 'favorite_character']
if chars:
names = ", ".join([c.value['name'] for c in chars])
context_parts.append(f"孩子特别喜欢的角色有:{names}。请尝试让他们客串出场。")
# 2. 近期情节
recent_stories = [m for m in memories if m.type == 'recent_story'][:2]
if recent_stories:
for story in recent_stories:
context_parts.append(f"最近发生过:{story.value['summary']}。可以在对话中不经意地提及此事。")
# 3. 避雷区 (负面记忆)
scary = [m for m in memories if m.type == 'scary_element']
if scary:
items = ", ".join([s.value['keyword'] for s in scary])
context_parts.append(f"【绝对禁止】不要出现以下让孩子害怕的元素:{items}。")
return "\n".join(context_parts)
2.2 成就提取与通知流程
当前流程在 app/tasks/achievements.py。需要完善闭环。
改进后的流程:
- Story Generation: 故事生成成功,存入数据库。
- Async Task: 触发 Celery 任务
extract_story_achievements。 - LLM Analysis: 调用 Gemini 分析故事,提取成就。
- Update DB: 更新
StoryUniverse.achievements。 - Notification (新增):
- 创建一个
Notification或UserMessage记录(需要新建表或使用 Redis Pub/Sub)。 - 前端轮询或通过 SSE (Server-Sent Events) 接收通知:"🎉 恭喜!在这个故事里,小明获得了[诚实勋章]!"
- 创建一个
2.3 记忆清理与衰减 (Maintenance)
需要一个后台定时任务(Cron Job),清理无效记忆,避免 Prompt 过长。
- 频率: 每天一次。
- 逻辑:
- 删除
ttl_days已过期的记录。 - 对
recent_story类型的base_weight进行每日衰减 update(或者只在读取时计算,数据库存静态值,推荐读取时动态计算以减少写操作)。 - 当
MemoryItem总数超过 100 条时,触发"记忆总结"任务,将多条旧记忆合并为一条"长期印象" (Long-term Impression)。
- 删除
3. API 接口规划
3.1 获取成长时间轴
GET /api/profiles/{id}/timeline
Response:
{
"events": [
{
"date": "2023-10-01",
"type": "milestone",
"title": "初次相遇",
"description": "创建了角色 [小明]"
},
{
"date": "2023-10-05",
"type": "story",
"title": "小明与魔法树",
"image_url": "..."
},
{
"date": "2023-10-05",
"type": "achievement",
"badge": {
"name": "好奇宝宝",
"icon": "..."
}
}
]
}
3.2 记忆反馈 (人工干预)
POST /api/memories/{id}/feedback
允许家长手动删除或修正错误的记忆。
- Action:
delete|reinforce(强化,增加权重)