Files
TrulyMEM-TrueHumanMEM/docs/zh/memory.md

6.3 KiB
Raw Blame History

TrulyMEM 记忆机制

本文档详细说明 TrulyMEM 内部的记忆工作机制。

核心设计理念

区别于传统上下文系统

传统 AI 对话系统使用 messages 数组存储对话历史:

  • 每次请求携带全部历史消息
  • 随着对话轮次增加,上下文逐渐膨胀
  • 最终触发记忆压缩或滑动窗口,造成记忆丢失

TrulyMEM 的解决思路:

  • 摒弃 messages 数组上下文
  • 唯一 记忆载体:图数据库
  • 全部记忆以三元组(节点)- 关系 → (节点)形式存储

图数据库作为唯一记忆源

所有记忆必须通过以下方式写入图数据库:

  • memory_commit - 写入新记忆
  • memory_purge - 删除/修正记忆

所有记忆必须通过以下方式读取:

  • memory_recall - 检索记忆

强制执行流程(每轮对话)

由于没有传统上下文系统,每轮对话必须按以下顺序执行:

步骤 1查询人设图最高优先级

memory_recall(
    query_intent="AI,人设,角色,性格,语气,说话风格",
    depth=2
)

目的:获取当前人设,确保角色一致性。

处理逻辑

  • 找到人设 → 严格按照人设的语气、风格、特征回复
  • 未找到 → 使用默认 TrulyMEM 身份

步骤 2查询工作记忆链

memory_recall(
    query_intent="TaskNode,工作记忆,任务链",
    depth=2
)

目的:获取之前的任务上下文,了解对话历史。

步骤 3处理对话

  • 理解用户意图
  • 根据人设和工作记忆链生成回复
  • 执行其他必要的记忆操作

步骤 4更新工作记忆链

task_create(
    task_id="Task_当前轮次ID",
    description="本轮对话概述",
    info_nodes=["相关记忆节点"]
)

目的:记录本轮对话,维持时间链。


记忆写入规则

必须写入的情况

以下信息必须写入图数据库:

场景 示例 写入方式
用户明确偏好 "我喜欢摇滚" memory_commit
用户分享信息 "我在做X项目" memory_commit
用户制定计划 "我打算X" memory_commit
用户描述状态 "我现在在X" memory_commit

禁止写入的情况

以下信息禁止写入:

场景 原因 处理方式
AI 推断的用户偏好 未经证实 不写入或标注[推测]
AI 猜测的用户意图 未经证实 不写入或标注[推测]
AI 推导的结论 未经证实 不写入或标注[推测]

标注规则

类型 标注方式 示例
推理内容 必须标注 [猜测] 用户[推测]喜欢音乐
明确内容 直接陈述 用户喜欢音乐

节点与边类型

节点类型

节点类型 说明 存储内容
PersonaNode 人设节点 AI 角色、性格、语气
TaskNode 任务节点 任务概述
StateNode 状态节点 任务状态
InfoNode 信息节点 具体信息
EntityNode 实体节点 通用实体

边类型

边类型 说明 连接关系
HAS_PERSONA 人设 AI → PersonaNode
NEXT_TASK 时间链 TaskNode → TaskNode
HAS_STATE 状态 TaskNode → StateNode
CONTAINS_INFO 信息 TaskNode → InfoNode
RELATES_TO 关联 EntityNode → EntityNode

必须查询工作记忆链的场景

强制查询场景

以下情况必须查询工作记忆链:

场景 示例
每轮对话开始 执行步骤 2
用户提到"刚才" "刚才我们聊了什么?"
用户提到"之前" "继续刚才的话题"
用户提到"上次" "上次说的X"
用户询问历史 "我们之前说了什么?"
连续性任务恢复 用户回到之前的话题
上下文引用 "那个东西"

自主性原则

在强制执行流程之外AI 可自主决定:

查询决策

  • 用户询问历史 → 查询
  • 涉及之前内容 → 查询
  • 不确定时 → 可查询

写入决策

  • 用户明确提到 → 必须写入
  • AI 推理得到 → 可以写入,标注[推测]

工具使用决策

  • 根据上下文灵活选择
  • 避免过度使用
  • 保持自然对话

完整示例:成语接龙游戏

第一轮:用户发起游戏

用户: 咱来玩成语接龙吧,我先开始,为所欲为

AI操作:
1. 查询人设图 → 获取当前人设(如:猫娘)
2. 查询工作记忆链 → 无进行中任务
3. 记录游戏状态:
   memory_commit(triplets=[
     {"subject": "成语接龙_当前成语", "relation": "内容", "object": "为所欲为"},
     {"subject": "成语接龙_当前成语", "relation": "游戏", "object": "成语接龙"}
   ])
4. 创建任务:
   task_create(task_id="Task_成语接龙", description="成语接龙游戏,当前成语:为所欲为", info_nodes=["成语接龙_当前成语"])
5. 回复: "好的喵!我接:为虎作伥喵!"

第二轮:话题被打断

用户: 长门有希

AI操作:
1. 查询人设图 → 获取当前人设(猫娘)
2. 查询工作记忆链 → 发现 Task_成语接龙 状态为"进行中"
3. 暂停任务:
   task_set_state(task_id="Task_成语接龙", state="已暂停")
4. 创建新任务:
   task_create(task_id="Task_长门有希", description="讨论长门有希")
5. 回复关于长门有希的内容

第三轮:用户要求继续游戏

用户: 关于刚才的成语接龙,我并不知道应该怎么接你的成语,请帮我接一下

AI操作:
1. 查询人设图 → 获取当前人设(猫娘)
2. 查询工作记忆链 → 发现 Task_成语接龙 状态为"已暂停"
3. 恢复任务:
   task_set_state(task_id="Task_成语接龙", state="进行中")
4. 查询信息节点 → 获取当前成语"为虎作伥"
5. 回复: "好的喵!上一个成语是'为虎作伥',我帮你接:伥鬼害人喵!"

执行检查清单

每轮对话必须检查:

  • 步骤 1是否查询了人设图
  • 步骤 2是否查询了工作记忆链
  • 步骤 3是否根据人设和工作记忆链生成回复
  • 步骤 4是否更新了工作记忆链
  • 涉及上下文引用时是否查询了工作记忆链?
  • 用户提到"刚才/之前/上次"时是否查询了工作记忆链?