Memory
角色如何记住过去的事 — 短期记忆、长期记忆、外部记忆。
三层架构
事件 → 短期记忆 (D1) → 长期记忆 (D1 + Vectorize)
↘
MemOS (外部 API,对话记忆)| 层 | 存储 | 用途 |
|---|---|---|
| 短期记忆 | D1 memories 表 | 最近事件,按时间倒序查询 |
| 长期记忆 | D1 long_term_memories + Vectorize | 重要事件,语义搜索召回 |
| MemOS | 外部 API | 对话记忆,自动抽取事实/偏好 |
短期记忆
每次角色行动后写入一条:
ts
await remember(db, charId, worldId, summary, 'short', weight);- 按时间倒序查询最近 N 条
- 1 小时后权重 ≥ 3 的自动升级为长期记忆(
consolidate) - 直接塞进 LLM prompt
长期记忆
重要事件才存(importance ≥ 0.6 或心情剧变 ≥ 20):
ts
await storeLongTermMemory(env, charId, content, summary, importance, createdAt);- 每条记忆生成 384 维向量嵌入(
@cf/baai/bge-small-en-v1.5) - 存入 D1 + 同步到 Vectorize
- 召回:优先 Vectorize ANN 搜索,fallback D1 暴力扫描
MemOS 外部记忆
AI 对话自动接入 MemOS:
写入
对话后异步存储(双方都存):
ts
await storeDialogue(memConfig, charId, charName, partnerName, dialogueText, worldId, tick);召回
对话前语义搜索相关记忆,塞进 LLM prompt:
ts
const memories = await recallDialogueMemories(memConfig, charId, partnerId, topic);- MemOS 自动抽取事实记忆和偏好记忆
- 跨 tick 持久化,角色会"记得"之前的对话
记忆在 Tick 中的使用
thinker.ts(AI 角色行动)
ts
const memories = await recentMemories(env.DB, char.id, 8);
const memoryText = await formatMemoriesForPrompt(memories);
// 塞进 LLM promptdialogue.ts(AI 对话)
ts
// 对话前从 MemOS 召回
const memoriesA = await recallDialogueMemories(memConfig, a.id, b.id, topic);
// 塞进对话 prompt容错
- MemOS 超时 10s,失败自动跳过
- Vectorize 不可用时回退到 D1 暴力扫描
- LLM 调用失败时回退到模板