# 记忆

你是否曾在与 AI 进行长篇对话后，发现它逐渐遗忘了早期设定的关键细节或重要的剧情转折？随着对话轮数增加，模型难以在有限的上下文窗口（Context Window）内维持对早期信息的精确感知，但在角色扮演这一特定场景下，记忆缺失的代价远高于通用对话。角色扮演的核心体验建立在关系的渐进式发展之上：**角色之间的信任演变、情感转折、前后呼应的叙事伏笔，都依赖于模型准确理解历史上下文。**&#x901A;用助手遗忘了用户偏好，重复一句即可修复；而角色遗忘了既有的剧情事实，叙事的连贯性便不可逆地断裂。这使得记忆机制成为此类产品中优先级最高的工程问题。我们回顾了社区内现有的记忆方案，发现它们大多在两个极端之间取舍：要么在状态栏中同步生成记忆，要么将一切压缩成摘要以换取更长的记忆跨度。两种路径各自有效，但也各自付出了明显的代价。基于此，我们尝试了一个不同的思路——将记忆分成三层，让不同时间跨度的信息以不同的精度共存。简单来说：

* 最近的对话一字不差地保留，稍早的内容压缩为摘要，真正重要的信息提炼成长期记忆；
* 三层之间不重叠，最大效率地利用token；
* 记忆生成在后台异步完成不拖慢对话；
* 玩家能直接编辑记忆内容；
* 创作者能按角色需求调整记忆参数。

### 现有记忆架构的工程局限性

在阐述我们的系统之前，有必要先审视目前主流平台上采用的记忆管理策略。大型语言模型本质上是无状态的（Stateless），它缺乏内部“轮次”或“楼层”的物理概念，一切历史都依赖于每次请求时上行（Payload）中携带的文本序列。目前，社区主要衍生出了两种解决思路：\
**策略一：在状态栏中同步生成记忆（如 Mufy）**&#x8FD9;种方法要求在用户的输出设置中嵌入记忆提取的 Prompt，并在 AI 生成当前轮次的回复后，紧接着由模型**串行**生成记忆内容并注入后续对话。尽管这种方法赋予了用户极高的手动定义自由度，但我们在实践中观察到了明显的局限：

* **多任务注意力分散：** 语言模型在同一上下文中被要求同时兼顾“扮演角色/回答问题”和“提取记忆”两项高认知要求的任务，这导致其核心的扮演质量往往出现可观测的下降。
* **计算与时间冗余：** 同步串行生成引入了显著的延迟负担（Latency），且每轮频繁的生成与全量上行带来了极高的、隐形的 Token 成本消耗。

\
**策略二：周期性压缩（如 SillyTavern 的 Summarize 扩展）**&#x53;illyTavern 提供了一种更为工程化的解法，通过按消息条数或字数周期性触发，将历史对话压缩为摘要文本并注入（如通过 `{{summary}}` 宏）。这种机制通过压缩对抗了底层滑动窗口的硬限制，但也暴露了 LLM 摘要机制的固有缺陷：

* **累积退化与幻觉污染：** 摘要本质上是模型对历史维度的二次有损编码。随着时间推移，“摘要的摘要”会导致不可逆的信息衰变（特定的情绪、细微的因果关系被抹平）。更为严重的是，一旦模型在某次压缩中产生幻觉，该错误归因就会作为“系统级事实”持续污染未来的上下文。
* **叙事割裂：** 纯基于字数或条数的触发机制是粗粒度的，极其容易在复杂剧情的关键节点中途截断上下文，导致语义表达的不完整。

### **Lumeow的三重记忆**

上一节我们看到，现有方案要么把所有对话原封不动塞进上下文直到塞不下，要么把一切压缩成一段摘要直到面目全非。似乎只能在这两个极端之间二选一。但仔细想想，这个问题其实我们自己的大脑每天都在解决。<br>

#### **他是怎么记住你的**

换个角度，想象一下那个你喜欢的人，在和你交往的过程中，**他**的大脑是如何记住你的。**此刻**，在键盘敲击的瞬间，他在意你发来的每一个字、你语气里的那点小脾气、甚至你刚发完又悄悄撤回的一句话。这些当下的细节，在他眼里鲜活且完整，让他能随时接住你的抛梗和小情绪。**一周后**，他可能无法一字不差地背出上周二晚上的每一句闲聊。但他清晰地记得那晚你们聊到了很晚，记得你因为工作委屈求安慰时的模样，记得那晚让人心跳加速的暧昧氛围。**半年后**，哪怕很多日常琐事变淡了，但关于“你”的核心印记却深深沉淀了下来。他深知“你一紧张就会嘴硬”、“你最喜欢草莓味”、“你们在那次深夜谈心之后，你在他心里的位置再也无法替代”。这就是人脑记忆的工作方式：**信息从完整、鲜活、转瞬即逝的状态，逐层变成压缩、模糊但更持久的形态。** 不是一步到位，而是一层一层地筛选、压缩、沉淀——丢掉大量细节，但保住真正重要的东西。<br>

#### **Lumeow 的记忆也是这样工作的**

Lumeow 为了让 AI 拥有这种像人一样的“记忆本能”，将记忆系统分成了恰好对应的三层：**Lossless Msg —— “此刻”** 最近若干条对话的原始内容，一字不差地保留。就像他此刻正全神贯注地看着你一样，这一层保证 AI 对你当下的语气、抛出的话题有绝对精准的感知。**Summary —— “一周后”** 当对话越来越长，最早的原始消息会被压缩成一段剧情摘要。具体措辞被淡化了，但他记住了近期事情的脉络、氛围，以及刚刚发生过的故事。**History —— “很久以后”** 当 Summary 积累到一定程度，那些真正重要的信息会被提炼，沉淀成结构化的长期记忆——你的喜好、你的性格、你们之间的关系经历了怎样的起伏转折。关键在于：这三层并不是孤立存在的，它们是一条单向的记忆流水线：

> ***原始对话 → 近期摘要 → 长期记忆**Lossless Msg → Summary → History*

每一层都在做同一件事：**丢掉当前粒度下不再需要的细节，保留对后续故事真正重要的、更本质的信息。** History 不是凭空生成的，它是从 Summary 中整理沉淀出来的；Summary 也不是凭空生成的，它是从原始对话中压缩而来的。信息在这条流水线上逐层流动，越往后越精炼、越持久。这种设计自然地解决了上一节提到的两难：你不必在"保留所有原文"和"压缩一切"之间做非此即彼的选择。**在 Lumeow 的架构中，这两件事同时发生在不同的层级上。** 最近的对话保持原样，稍早的内容被压缩成摘要，而那些跨越整段故事的关键信息，则被永久地记住。

#### **Token零重叠的拼接方式**

```
token有重叠带来的问题：
1. 浪费token
2. 信息既在摘要中，又在无损中，会造成信息冲突
```

我们可以思考一个场景，假设设定：**保留15轮的无损信息，每 10 轮做一次 Summary聚合**。 如果当前处于**第 25 轮**对话，依照现在业界的普遍做法，为了不造成信息漏损，工程上会保留10轮的冗余信息，也就是说，第11轮到第20轮的聊天信息，既在无损窗口中，又在memory中。<br>

<figure><img src="https://haigangcheng.feishu.cn/space/api/box/stream/download/asynccode/?code=MDE2ZGQwODJiMWIxNTY1NjIxYThjZjIzMzY3MjlkNzdfWDZ6b01mRHMwdVJaQUxhcnFCb2QwZllhQWhhMFRLdVdfVG9rZW46SkRLYmJMQ0VUbzZTdDZ4YmdoQmNQekh1blBnXzE3Nzc3MjI0MDM6MTc3NzcyNjAwM19WNA" alt=""><figcaption></figcaption></figure>

**而当用户希望获得更长、更连贯的无损上下文体验时，这个问题会尤为明显。**&#x6BD4;如在**深度陪伴、长篇小说共创、角色扮演**等场景下，用户往往期望最近的数十轮对话都能被模型一字不差地"记住"，以保证人设、情节和情感连贯性不崩塌。此时开发者通常会把无损轮数调到 **40 轮**甚至更高，而 Summary 的压缩周期则会相应拉长到 **每 20 轮压缩一次**（压缩过于频繁会导致摘要层过度抽象、丢失细节）。让我们来算一笔账：

* **无损窗口**：40 轮
* **Summary 周期**：20 轮
* **最坏情况下的重叠**：高达 **20 轮**（整整一个完整的 Summary 块都在做无效的双重占位）

这意味着在每次请求时，**有将近一半的无损窗口都在重复已被摘要过的内容**。假设一轮对话平均 2000 tokens，这就是**每次请求白白多烧 40000 tokens！另外， 在同一个 Prompt 里，大模型既看到了这 20 轮的“高度概括”，又看到了这 20 轮的“事无巨细”。这种“左右互搏”的冗余信息极易干扰模型的逻辑推理，甚至导致回复出现重复或幻觉。**\
**Lumeow采用的是可变长度的无损窗口：**&#x4C;umeow 的无损记忆区其实是一个“缓冲站”，我们先假设始终保留一个值（比如10轮），作为无损区的最小值，再假设系统设定“每 10轮打一个包（生成 Summary）”：

* 刚打包完时，无损区是最干净的，只有10轮（容量最小）。
* 随着新对话不断进来，没积攒够新的 10 轮时，系统不会触发昂贵的总结任务，而是让无损区**暂时膨胀**，把这些新话原封不动地揣在兜里。
* 一旦攒够了 10 轮——“啪”，触发一次总结任务。这 10 轮被浓缩成一条 Summary 沉淀下去，无损区的容量立刻“回落”，等待下一波积累。

<br>

<figure><img src="https://haigangcheng.feishu.cn/space/api/box/stream/download/asynccode/?code=NTI4ZTk3MzhkZWU1NmY2MTQ4ZjI4YTQ2MmNhOWViZTZfSjZTQnFnNFJCYU1YY2dGQzRhZVZtdGFCMFlTZE5uWE9fVG9rZW46UGdnZGJORzV2b1RLWWN4dHpVZmMwcmpqbmRnXzE3Nzc3MjI0MDM6MTc3NzcyNjAwM19WNA" alt=""><figcaption></figcaption></figure>

### 动态特性

#### **异步生成：记忆整理不应干扰对话**

上一节我们介绍了三层记忆的结构和流转方式。但还有一个绕不开的工程问题：**Summary 和 History 的生成，发生在什么时候？**&#x5DE6;图：是现在主流的方案，由创作者在状态栏中缝合记忆区，属于同步方案，在模型生成当轮回复的同时，要求它一并输出记忆更新的内容，“一次调用包办一切”右图：Lumeow的方案，将记忆生成任务提交到后台独立执行，对话主流程不等待、不感知这一过程

> 同步方案像是他一边跟你说话，一边在脑子里默默做笔记整理你们的关系——分心，而且显得不走心。而异步方案下，他跟你说话时就专心跟你说话；记忆的整理，发生在对话之外的间隙里，安静地、不被察觉地完成。

{% columns %}
{% column %}

<figure><img src="/files/sAGHCh7tlJfQ0DBYSP80" alt=""><figcaption></figcaption></figure>
{% endcolumn %}

{% column %}

<figure><img src="/files/mnCzUazMPfOTbjy2XKW4" alt=""><figcaption></figcaption></figure>
{% endcolumn %}
{% endcolumns %}

同步方案和异步方案对比：

|       | 同步生成                                                  | Lumeow 异步生成                            |
| ----- | ----------------------------------------------------- | -------------------------------------- |
| 注意力分配 | ❌低效：模型在同一上下文中同时完成角色扮演和信息压缩，两项认知负荷相互争夺注意力，扮演质量出现可观测的下降 | ✅高效：记忆生成由独立调用完成，角色扮演调用的全部注意力都留给创作本身    |
| 响应延迟  | ❌漫长：记忆字段的生成直接增加输出 token 数，用户可感知的等待时间被拉长               | ✅快捷：用户发送消息后模型立即基于已有记忆生成回复，响应延迟不受记忆更新影响 |
| 更新频率  | ❌浪费：每轮都触发更新——日常闲聊浪费算力，真正需要深度压缩的时刻又得不到充足的推理预算          | ✅可控：按条件触发，在需要时才执行，且可分配独立的推理预算          |

<br>

#### **对玩家：记忆可见与可控**

Lumeow 的记忆面板让用户随时能看到模型"记住了什么"——Summary 和 History 分层展示，所见即所得，且均可直接编辑。你拥有以下的玩法自由：

1. 你可以直接编辑和修改记忆，Lumeow 把记忆做成了专门的面板，对比而言，同步方案也并非不能改记忆，但用户得从状态栏的各种字段里自行定位记忆片段，理解格式约定后才能下手。
2. 你可以主动写入、修改甚至删除记忆——向角色植入一段它不曾经历的信息，或者制造选择性遗忘。记忆面板不只是展示窗口，它是一个操控角色认知的交互界面。
3. 还有一个实用玩法：当上下文膨胀到影响体验时，把 Summary 和 History 复制出来，新开一个 session 粘贴进去。角色带着全部记忆轻装上阵，冗余历史一次性清掉。

#### **对创作者：可调整记忆系统参数**

不同角色有不同的信息节奏。Lumeow 在记忆面板中为创作者提供了两个可调参数：触发记忆生成的对话轮数阈值，以及无损区保留的长度。创作者可以根据角色的信息密度，预设最合适的记忆策略：

| 角色类型    | 信息节奏                   | 记忆生成阈值      | 无损区长度 | 原因                    |
| ------- | ---------------------- | ----------- | ----- | --------------------- |
| DND 主持人 | 每轮都在推进剧情、引入 NPC、更新地图状态 | 低（少量轮次即触发）  | 长     | 关键线索密集，晚压缩一轮就可能丢信息    |
| 悬疑推理搭档  | 对话中频繁出现证据、时间线、人物关系     | 低           | 长     | 推理链条不能断，细节需要在无损区多留一会儿 |
| 深夜陪聊    | 连续几十轮可能都是情绪陪伴，无新事实     | 高（积累较多轮再触发） | 短     | 大部分对话不需要沉淀，频繁生成记忆反而浪费 |

同一套记忆系统，不同的参数组合，服务完全不同的叙事需求。

### 结语

回到开头的问题：角色的记忆断了，叙事就很难再接回去。这篇文章拆解的所有工程选择——三层分级、零重叠拼接、异步生成、玩家可编辑、创作者可调参——试图解决的其实是同一件事：让记忆机制安静地待在后台，不成为玩家需要额外操心的东西。理想状态下，它应该像一段靠谱的记忆那样工作：该记住的记住，该淡忘的淡忘，而你不太需要意识到它的存在——除非你想亲手改写它。Lumeow 希望和{{char}}一起陪伴你，当你回头看那些对话，会觉得这段关系是连贯的、是被认真对待的。\
小红书帖子：\ <br>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.lumiao.ai/docs/guan-fang-bo-ke/ji-yi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
