Skip to content

可追踪的记忆

记忆和摘要系统并不新鲜。 许多 Agent 系统都有类似能力。 但 AI RP 需要的记忆,不只是把事实存下来,还要能说明这些事实从哪里来,为什么会影响现在。

记忆系统已经很常见

现在只要谈 Agent,几乎都会谈记忆。

常见做法是:

  • 从对话里提取事实。
  • 把长对话压缩成摘要。
  • 在下一轮生成前检索相关内容。
  • 把检索结果放回提示词。

这套流程很容易理解,也确实有用。

对于普通任务型 Agent 来说,它通常已经够用了。系统只要记得用户偏好、项目背景、任务进度,就能减少重复询问,提高连续性。

但 AI RP 的情况不完全一样。

AI RP 里的记忆,不只是为了让系统“记得一些信息”。它还会影响角色关系、世界状态、剧情走向和玩家体验。

所以这里的记忆系统需要更强的可追踪性。

酒馆生态的特殊之处

酒馆面向的用户,是来玩 AI RP 的。

他们不是只想让系统完成一个外部任务。他们在意的是一段叙事能不能成立。

在这样的场景里,记忆错误会带来很明显的问题。

例如:

  • 角色突然记得一件从未发生过的事。
  • 系统忘记了几轮前已经承诺过的约定。
  • 某个 NPC 的态度发生变化,但使用者看不出原因。
  • 一条摘要把玩家没有做过的行动写成了事实。
  • 一条长期记忆来自模型误解,却在后续多次被注入。

这些问题都不是简单的“记忆召回率不够高”。

它们会破坏叙事因果。

在 AI RP 中,使用者通常会追问:

  • 这条记忆是从哪一轮来的?
  • 当时是谁说了这句话?
  • 这是用户确认过的事实,还是模型自己推断的?
  • 这条记忆为什么会在这一轮被注入?
  • 它有没有覆盖旧记忆?
  • 它和另一条记忆是否冲突?

如果系统回答不了这些问题,记忆就会变成新的黑箱。

AI RP 需要能揭示因果关系的记忆

普通记忆系统常常只关心两件事:

text
存了什么 → 取出什么

AI RP 需要多问几步:

text
为什么存下它 → 它来自哪里 → 它更新了什么 → 它为什么在现在被使用

这就是“可追踪的记忆”。

一条记忆不应该只是孤立的文本。它最好能带上下面这些信息:

  • 来源楼层。
  • 来源消息。
  • 所属分支。
  • 记忆类型,是事实、摘要,还是未闭合事项。
  • 作用域,是全局、会话、分支,还是楼层。
  • 提取或更新的理由。
  • 与其他记忆的关系。
  • 当前是否仍然有效。
  • 本轮是否被检索、被注入、被裁剪。

这样使用者才能看见一条记忆在叙事中的位置。

例如,系统不只是告诉你:

text
角色 A 害怕水。

它还应该能告诉你:

text
这条记忆来自第 12 楼。
当时角色 A 在河边提到童年溺水经历。
第 18 楼的摘要强化了这条事实。
当前分支仍然保留这条记忆。
本轮因为场景发生在码头,所以它被注入提示词。

这才是 AI RP 中更有用的记忆。

摘要尤其需要追踪

摘要是记忆系统里最容易出问题的部分。

因为摘要会压缩信息。

压缩会带来两个风险。

第一,细节会丢失。原本带有条件、语气和不确定性的内容,可能被压成一个更确定的句子。

第二,因果会被改写。原本只是角色怀疑某件事,摘要可能写成了事情已经发生。

如果摘要没有来源,使用者很难判断它是否可信。

所以摘要也需要被追踪:

  • 短摘要覆盖了哪些楼层。
  • 长摘要由哪些短摘要压缩而来。
  • 摘要里哪些内容来自用户输入,哪些来自 AI 输出。
  • 压缩时是否丢弃了重要条件。
  • 新摘要是否更新、替代或冲突了旧摘要。

这不是为了把摘要系统做得复杂,而是为了让压缩之后的信息仍然可以回查。

摘要越长,越需要知道它从哪里来。

记忆关系也很重要

记忆之间不只是并列关系。

有些记忆支持另一条记忆。

有些记忆更新另一条记忆。

有些记忆和另一条记忆冲突。

例如:

text
第 5 楼:角色 B 说自己从未去过王都。
第 20 楼:角色 B 承认自己曾经在王都受训。

这两条信息不能简单地同时存在,然后都被注入提示词。

系统需要知道它们之间的关系。

第二条可能是在更新第一条,也可能是在揭示角色 B 之前说谎。不同解释会带来不同剧情含义。

因此,记忆系统需要能够表达关系边,例如:

  • supports:一条记忆支持另一条记忆。
  • updates:一条记忆更新另一条记忆。
  • contradicts:一条记忆和另一条记忆冲突。

这些关系不是装饰。它们是叙事因果的一部分。

分支让记忆追踪更必要

TavernHeadless 有真正的分支结构。

这意味着,同一个会话里可能存在多条故事线。

在主线里,角色 A 可能活着。在另一条分支里,角色 A 可能已经死亡。

如果记忆只放在会话级别,这两条故事线就会互相污染。

所以记忆也需要作用域。

有些记忆属于全局。比如世界观常识。

有些记忆属于会话。比如整个会话都确定的背景。

有些记忆属于分支。比如这条故事线里的选择和后果。

有些记忆只属于某个楼层。比如一次回合的临时判断。

可追踪的记忆要能回答:这条记忆属于哪条线,它从哪里继承来,又有没有在当前分支被更新。

否则,分支会让记忆问题变得更难排查。

和 Prompt Runtime 的关系

Prompt Runtime 关注的是提示词运行过程。

它可以告诉使用者:这一轮哪些记忆被注入了,哪些被排除,记忆摘要是否进入了提示词。

但这只回答了一部分问题。

如果使用者继续问:这条被注入的记忆从哪里来,为什么它存在,是否可靠,它和旧记忆有什么关系,就需要记忆系统自己的追踪能力。

因此,两者分工不同。

Prompt Runtime 说明记忆在本轮提示词中怎样被使用。

可追踪的记忆说明记忆本身怎样形成、怎样更新、怎样和其他记忆发生关系。

两者合在一起,才能回答完整的问题:

text
这条记忆为什么存在,又为什么在这一轮影响了回复?

和 Memory Agent 的关系

后续如果引入 Memory Agent,它不应该只是一个自动写记忆的后台进程。

它应该提出建议,并留下理由。

例如:

  • 建议新增哪条事实。
  • 建议更新哪条旧记忆。
  • 建议标记哪条记忆为过时。
  • 建议保留哪个冲突,等待后续确认。
  • 建议把哪条记忆从楼层提升到分支。

这些建议不应该静默生效。

影响叙事正史的记忆写入,应当有明确的提交边界。至少要能在事后看到:是谁提出了这条写入,依据是什么,最后是否被接受。

这样 Memory Agent 才不会变成另一个难以解释的状态修改者。

可追踪记忆解决的核心问题

可追踪记忆解决的不是“存得更多”。

它解决的是下面几个问题。

来源可查

每条记忆应该尽量能回到来源楼层和来源消息。

如果一条记忆有问题,使用者可以回到当时的上下文,而不是只能看到一段孤立摘要。

更新可查

记忆不是一次写入后永远不变。

角色关系会改变,事实会被补充,误解会被澄清。

系统需要记录旧记忆如何被更新,新记忆是否替代了旧记忆。

冲突可查

AI RP 中,冲突不一定都是错误。

有些冲突是剧情的一部分,例如角色说谎、误会、信息不完整。

系统不应该简单删除冲突,而应该先把冲突标出来,让后续流程判断。

注入可查

一条记忆存在,不代表它每一轮都应该进入提示词。

使用者需要知道本轮为什么选择了它,为什么没有选择另一条记忆,以及它是否因为预算被裁剪。

分支可查

同一会话下不同分支的记忆应当互不污染。

使用者需要知道当前分支继承了什么,修改了什么,和其他分支有什么差异。

成本很高,受益也很高

可追踪的记忆会带来成本。

系统需要记录来源、作用域、关系、状态和后台作业结果。摘要压缩时也要保留覆盖范围和来源列表。记忆检索和注入时,还要记录本轮为什么选中或排除某些记忆。

API 和 SDK 也要把这些信息以稳定结构暴露出来。

前端如果要展示它,还需要有合适的 Inspector。否则信息太多,使用者也看不明白。

另外,可追踪不等于完全正确。

LLM 仍然可能提取出错误记忆。摘要仍然可能压缩出偏差。系统只能让这些错误更容易被发现和修正,而不能保证它们永远不发生。

这些都是负担。

但对于 AI RP 来说,这个负担有意义。