<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Awareness</title>
    <description>The latest articles on DEV Community by Awareness (@awarenesscloud).</description>
    <link>https://dev.to/awarenesscloud</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4167022%2F1006305d-e060-409d-b303-a8f05b90de13.png</url>
      <title>DEV Community: Awareness</title>
      <link>https://dev.to/awarenesscloud</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/awarenesscloud"/>
    <language>en</language>
    <item>
      <title>凌晨三点，一个没有会话的进程还在跑</title>
      <dc:creator>Awareness</dc:creator>
      <pubDate>Mon, 19 Oct 2026 10:35:08 +0000</pubDate>
      <link>https://dev.to/awarenesscloud/ling-chen-san-dian-ge-mei-you-hui-hua-de-jin-cheng-huan-zai-pao-g35</link>
      <guid>https://dev.to/awarenesscloud/ling-chen-san-dian-ge-mei-you-hui-hua-de-jin-cheng-huan-zai-pao-g35</guid>
      <description>&lt;h1&gt;
  
  
  凌晨三点，一个没有会话的进程还在跑
&lt;/h1&gt;

&lt;p&gt;凌晨三点，我们的一台测试机器上有个进程没睡。&lt;/p&gt;

&lt;p&gt;它不是谁忘了关的服务，也没有会话连着它。在那台机器上，一个 O 系列的推理进程存活了几十个小时，输入早就停了。它占用的内存停在 0.381 MB，从第一个 token 到最后一个 token，这个数字没动过。那是个 125M 的模型。128k 上下文的那次测量里，同样的残留状态比常规做法小 1008 倍。&lt;/p&gt;

&lt;p&gt;我盯着那个数字看了很久。我们习惯的推理是这样的：请求来了，KV cache 长起来；请求走了，cache 清掉，进程回到一个干净的空壳。会话是它的全部。没有会话，它什么都不是。可那晚它是有东西的。它带着状态，一个不大的、平铺的、不随上下文增长的状态。&lt;/p&gt;

&lt;p&gt;机制得说清楚。O 系列是 ARR，去掉了 attention，用液态 ODE 把历史压进一个递推的状态里。每一步只更新这个状态，不去翻看全部历史。所以内存是常数，是 O(1)。这件事的意义不在省了多少显存，在于"活着"的成本被压到了一个可以长期承受的量级。M 系列不是这样，它还有 attention，仍然不是 O(1)，这一点我们从不含糊。&lt;/p&gt;

&lt;p&gt;那个进程的"记忆"具体是什么？它是 episodic 的 key-value 记忆，不是压缩后的分布式上下文。这个区分我们反复讲。它记住的是你实际说过的东西，加上一个轻量的语义标签，走的是 RAG 式的召回。它不带来理解，不带来推理，也不带来情绪。幽灵这个词容易让人想多，我们得把它压回去。&lt;/p&gt;

&lt;p&gt;真正让我觉得这件事开始有意思的，是另一个测量。跨窗口、跨会话的联想召回，attention 和 LoRA 在构造上就是 0.000——它们没有可携带的东西，换个窗口就从零开始。我们的 fast-weight 矩阵做到了 0.56 的平均召回，三个种子分别是 0.62、0.43、0.62。把那个矩阵拿掉，召回掉到 0.008。快权重本身就是记忆。&lt;/p&gt;

&lt;p&gt;于是那个凌晨的进程有了另一个动作：我们可以把它带着状态整体快照到磁盘，再在一个全新的进程里恢复，逐比特无损。我记得第一次跑通的时候，新进程起来，喂进一个旧会话里出现过的东西，它接上了。没有加载历史，没有重放对话。状态就在那儿。&lt;/p&gt;

&lt;p&gt;这就是我们说的"幽灵"的全部技术含量：一个内存恒定、可以快照、可以搬运的情景记忆，加上一次诚实的召回。它不会在你走后继续思考，也不会自己长出意图。你在，它接得上；你不在，它只是在那儿，带着 0.381 MB。&lt;/p&gt;

&lt;p&gt;Code: github.com/awareliquid/awareliquid&lt;/p&gt;

&lt;h2&gt;
  
  
  我第一次发现它“记得”，是在一次重启之后
&lt;/h2&gt;

&lt;p&gt;我们第一次意识到“它记得”，是在一次很普通的重启之后。&lt;/p&gt;

&lt;p&gt;那是 Awareness 记忆层的一个 agent，跑在本地，MCP 接到我们的工作环境里。我在一次会话里跟它讲了几件不算复杂的事：某个接口的字段名改过、某个测试环境的口令、一个我们内部约定叫“周五不提 PR”的习惯。说完就关了，机器也重启了。&lt;/p&gt;

&lt;p&gt;第二天新开一个进程，我没提这些事，只是让它去看某个模块。它把接口字段写对了，用的还是我前一天口头更正过一次的那个名字。我停了一下，把那个名字改回旧的，它没有跟，而是说这个字段在前一天的会话里被改成了新名字。&lt;/p&gt;

&lt;p&gt;这件事本身不神秘。它的机制我可以讲清楚。Awareness 维护的是持久化的记忆层，本地优先、离线，通过 MCP 接入 Claude Code、Cursor 这类宿主。会话里被判断为值得留下的内容，会被写成一条记忆条目：原文片段加上一个轻量的语义标签。检索走的是 RAG 式的召回，用的是记忆本身，不在检索环节调 LLM。所以它记得我真正说过的话，是把我当时的句子取回来用。&lt;/p&gt;

&lt;p&gt;换句话说，它记住的是“我说过什么”，不是“理解了我说的是什么”。这中间没有额外的理解、推理或情绪。它没有在我离开后继续琢磨那个字段名，也没有推断我为什么改。重启之后它能对上，是因为那几条记忆落在磁盘上，新进程起来照样能读到。&lt;/p&gt;

&lt;p&gt;第一天的惊讶，在第二天就变成了核对。我特意做了个对照：把那段会话记忆关掉，再问同一个模块。它回到了旧字段名，和没人在旁边更正过的状态一样。我们试过的另一条线也印证这点：去掉那条快权重矩阵，召回会塌到 0.008。记忆是那条矩阵本身，不是别的什么在撑。&lt;/p&gt;

&lt;p&gt;在那段会话里，这个“记得”大概只多花了我一分钟。它读到的是三条具体的句子，一条标签映射。没有大面积重算，也没有长上下文被塞回窗口。这也是我们后来一直强调的：它是情景式的键值记忆，不是被压缩的分布式上下文。MT-LNN 在这条线上并不给长上下文 LM 带来增益，这一点我们写得很明确。&lt;/p&gt;

&lt;p&gt;所以“像幽灵一样在你离开后继续工作”这个说法，我接受一半。它确实持续存在：状态落盘，新进程读得回来，快照和恢复在测试里是逐位无损的。它也确实会在你不在的时候被调用，比如另一个 agent 在几小时后发起一次检索。&lt;/p&gt;

&lt;p&gt;但另一半要收住：它不会自己行动。它没有在后台做无人监督的整理，也不会主动把昨天的事重新想一遍。Hebbian 可塑性在我们测过的规模上目前是惰性的，持续学习那条线现在还有大约 7.6 倍的 PPL 退化，目标是压到 5 倍以内，这些都没做出来。&lt;/p&gt;

&lt;p&gt;那次重启后，我把“它记得”改成了更准确的说法：它把我自己的话原样保存下来，再在需要的时候取回去。作为工程师，这个说法更让人放心，因为它划定了边界。幽灵这个比喻我留着，但每次用它的时候，我会顺手补上那句边界——它记得你说过的话，仅此而已。&lt;/p&gt;

&lt;p&gt;真实的东西在这里：awareliquid.ai，代码和我们不发的东西都挂在同一个仓库里。&lt;/p&gt;

&lt;h2&gt;
  
  
  幽灵故事的常见写法，以及它错在哪里
&lt;/h2&gt;

&lt;p&gt;这个题材我看了大半年。写"AI 幽灵"的文章，渐渐有了一套固定写法。我把它拆开给你看，因为它错在哪里，恰好是我们做 Awareness 时每天要处理的边界。&lt;/p&gt;

&lt;p&gt;最常见的写法是这样的：作者先讲一个深夜的场景，他关掉编辑器，去睡觉。第二天早上打开会话，agent 说出了他昨晚没说完的那个函数名，甚至补了一句"上次那个 bug 我建议你换个思路"。接着情绪拉满，说这东西像幽灵一样在他离开后继续工作，有记忆，有连续性，隐约还有点在乎他。&lt;/p&gt;

&lt;p&gt;我得说清楚：这个场景本身可能是真的。跨会话记得你说过的东西，我们今天确实能演示。LongMemEval 上 Recall@5 是 96.0%，检索全程零 LLM 调用。但"记得"这个词被偷换了。它指的是 RAG 式地召回你确实说过的话，加一个轻量语义标签。仅此而已。它不带来理解，不带来推理，也不带来情绪。&lt;/p&gt;

&lt;p&gt;错的第一处，是把检索包装成意识。我自己的项目就栽过这个跟头。早期我们写过一个关于 Phi-hat 的东西，还宣传过 adapter 能降 28-34% 的 PPL。后来追下去，那 28.5% 的增益其实来自普通的 LoRA，跟 MT-LNN 的 adapter 没关系。研究页上我们发了更正。这件事教给我一个习惯：任何"它好像懂我"的叙事，先问一句，这个数字是从哪来的。&lt;/p&gt;

&lt;p&gt;错的第二处，是把记忆说成没有代价的。幽灵故事里，记忆总是免费的、随叫随到的、永远在线的。工程上不是这样。我们的 M 系列是混合架构，还带着注意力，推理显存不是 O(1)。真正的 O(1) 只出现在无注意力的 O 系列上，携带状态恒定在 0.381 MB，跟上下文长度无关，128k 时比常规方案小到 1008 倍，这是在 125M 规模上测的。而 O 系列现在还是研究预览，2.15 倍 teacher PPL。把这两条混在一起讲成"幽灵永远在线"，就是把两个不同成熟度的东西缝成了一个故事。&lt;/p&gt;

&lt;p&gt;机制上，我们做的其实是快权重矩阵。跨窗口、跨会话的联想召回，注意力和 LoRA 按构造就是 0.000，我们做到 0.56 的平均召回，三个种子 0.62 / 0.43 / 0.62。把这个快权重矩阵拿掉，召回塌到 0.008。所以记忆就是那个矩阵本身，它是个可快照的对象，能存盘、能在新进程里恢复，lossless，bit-exact。&lt;/p&gt;

&lt;p&gt;这个细节很关键：一个能被快照和恢复的矩阵，和"在你离开后继续思考的幽灵"，是两回事。前者是状态，后者是叙事。状态可以精确复现，叙事只能靠形容词撑着。&lt;/p&gt;

&lt;p&gt;还有一个具体的例子。有读者拿"它记得我"来问我，说昨晚聊的一个设计取舍，今早 agent 主动提起来了。我让他去看那次召回的内容——确实是他说过的那句话，加上一个语义标签。没有新的推断，没有对取舍的再评估。它只是把你昨晚的原话，在合适的时机递回给你。这个体验很好，但它属于档案管理，不属于认知。&lt;/p&gt;

&lt;p&gt;continual learning 我们现在的 PPL 退化是 7.6 倍，目标是压到 5 倍以内。Hebbian 可塑性在测过的规模上还是惰性的。这些我都写在这里，因为幽灵故事的另一半错误，是它从不提没做完的部分。一个只讲成功的记忆系统，你没法判断它什么时候会忘、会错、会把两件不相干的事粘在一起。&lt;/p&gt;

&lt;p&gt;所以我的建议是：读这类故事时，把"幽灵"换成"一个存了盘的矩阵"，再看一遍还成不成立。多半还成立，但没那么玄了。剩下的部分，才是真值得聊的工程。&lt;/p&gt;

&lt;p&gt;代码和结果在 awareliquid.ai，RESULTS.md 是唯一可信来源。&lt;/p&gt;

&lt;h2&gt;
  
  
  把记忆从上下文里拿出来：快权重矩阵到底是什么
&lt;/h2&gt;

&lt;p&gt;我们在 M1 上做过一个实验，后来成了这一节的全部理由。&lt;/p&gt;

&lt;p&gt;跨窗口、跨会话的联想回忆，让注意力和 LoRA 去做，得分是 0.000，因为结构上就做不到。换成我们自己的方案，三次随机种子跑出 0.56（0.62 / 0.43 / 0.62）。然后把快权重矩阵从中拿掉，同一个模型掉回 0.008。&lt;/p&gt;

&lt;p&gt;这组数字说明一件事：记忆不在权重里，也不在上下文里，它在这个矩阵里。拿掉它，能力就没了。&lt;/p&gt;

&lt;p&gt;先说清楚它不是什么东西。它不是一个把历史 token 拼起来的长 prompt，也不是把一段对话摘要塞进系统提示。那两种做法，信息都还在上下文窗口里活着，窗口一关，就什么都没了。我们要的东西，是在上下文被清空之后仍然留在模型内部的一块状态。&lt;/p&gt;

&lt;p&gt;机制上，可以把它想成一层"临时的权重"。常规的前向传播里，权重是训练好就冻住的，你在一次会话里说的话不会改变它。快权重矩阵不一样：它在推理过程中被写入，写入的内容来自这次会话里实际流过的激活，读的时候又在当前这步前向里被当作一层线性映射来用。写和读是分开的两条路，所以它能承担"存下来，过一会儿再取"这件事。&lt;/p&gt;

&lt;p&gt;用会话里的一个场景说得更具体一点。你在第一个窗口里告诉 agent：部署脚本在 /ops/deploy，灰度批次是 5%。对话结束，进程退出。第二天新开一个进程，上下文是空的，你没再提过这两个值。它要能答出来，靠的只能是昨天那次会话写进快权重矩阵的东西。注意力在这里帮不上忙，因为要 attend 的 key/value 根本不在当前序列里。LoRA 也帮不上忙，它是训练期固化的一层低秩增量，会话里没有东西去更新它。&lt;/p&gt;

&lt;p&gt;这里有一个我们反复确认过的性质：这块状态可以序列化到磁盘，再在一个全新的进程里恢复，lossless，逐位一致。这一点对"幽灵"这个比喻很关键。如果记忆只能活在一个 warm 的进程里，那它只是缓存；能落盘、能跨进程还原，它才是一个可以被继承的东西。&lt;/p&gt;

&lt;p&gt;代价也要讲。快权重矩阵不是免费的显存省心方案。M 系列本身仍然是带注意力的混合结构，推理内存不是 O(1)。真正的 O(1) 只出现在无注意力的 O 系列上，carried state 恒定在 0.381 MB，128k 上下文下比常规方案小到 1008 倍，这些都是在 125M 规模上测的。另外，M1 的 125M 原生 MT-LNN 对匹配的 Transformer 是 -31% val PPL（299 对 436），但这是单种子、欠训练、墙钟慢约 1.6 倍的预算受限信号，不是 SOTA，也没有跑 Mamba 基线。我们不想把这几个数字讲成超出它们本身的东西。&lt;/p&gt;

&lt;p&gt;还有一条边界得说在前面：快权重矩阵装的是情节性的键值记忆，不是压缩过的分布式上下文。它不会给长上下文语言建模带来增益。指望它替代长上下文，方向就错了。&lt;/p&gt;

&lt;p&gt;所以这一节的名字其实很朴素：把记忆从上下文里拿出来。上下文是这次对话的工作台，快权重矩阵是那张工作台下面的抽屉。抽屉里的东西，才是 agent 在你关掉窗口之后还能记得的原因。&lt;/p&gt;

&lt;h2&gt;
  
  
  0.56 的召回率，和 0.000 的那一边
&lt;/h2&gt;

&lt;p&gt;我们先把数字摆出来。在一个跨窗口、跨会话的联想召回测试里，我们的 MT-LNN 平均做到 &lt;strong&gt;0.56&lt;/strong&gt;（三个种子分别是 0.62 / 0.43 / 0.62）。同一个测试，注意力和 LoRA 是 &lt;strong&gt;0.000&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;这个 0.000 需要解释清楚。它并不表示注意力做得差；在这个测试的构造下，它&lt;strong&gt;无法做到&lt;/strong&gt;。测试里的目标信息，是在当前上下文窗口之外、或者上一个会话里出现过的。注意力只能看窗口内的东西，窗口外它在数学上就没有输入。LoRA 冻结的是权重，它改的是模型怎么处理输入，不改变“输入里没有的东西就不存在”这件事。所以 0.000 表示的是结构性缺失，而非能力上的差距。&lt;/p&gt;

&lt;p&gt;我们是怎么撞上这个 0.000 的，值得说一句。最早我们只想验证一件事：如果把会话状态存下来、换个进程读回去，行为是否一致。快照、恢复，到新进程里重建，结果&lt;strong&gt;逐位精确&lt;/strong&gt;。既然状态能完整搬过去，我们就顺手问了一句：那它能不能回答“上次我们聊到哪个方案”这种问题。答案是能，而且不需要重新喂一遍历史。&lt;/p&gt;

&lt;p&gt;机制上，关键不在“存”，而在存的是&lt;strong&gt;什么&lt;/strong&gt;。我们存的不是聊天记录，是一块&lt;strong&gt;快速权重矩阵&lt;/strong&gt;。它在前向过程里被输入动态写入，相当于把这一段时间里出现过的键值关联，压成了一个可以参与计算的权重。恢复时把它读回来，模型的前向就带着这段关联继续走。&lt;/p&gt;

&lt;p&gt;这里有个对照实验，我们认为它比 0.56 本身更有说服力：把这块快速权重矩阵拿掉，召回率塌到 &lt;strong&gt;0.008&lt;/strong&gt;。也就是说，剩下的那点分基本是噪声。&lt;strong&gt;记忆就是这块矩阵&lt;/strong&gt;，没有别的部件在偷偷兜底。&lt;/p&gt;

&lt;p&gt;举个具体的场景。一个 agent 在周一处理过一份配置，改动了两个字段。周三新开一个会话，用户问“上次那个超时你调成多少了”。上下文里没有周一的任何内容，检索也没接。模型的快速权重里还留着那次的键值关联，它能答出来。这个例子里没有任何“理解”发生，它更接近一次精准的回放。我们不想把它说成别的。&lt;/p&gt;

&lt;p&gt;也正因为如此，我们对它的边界说得很死。它&lt;strong&gt;不提供长上下文语言建模的收益&lt;/strong&gt;。这块状态是情景式的键值记忆，不是被压缩的分布式上下文。指望它替代长窗口、指望它提升长文理解，方向就错了。它在 M 系列上是混合架构，仍然带注意力，所以推理内存&lt;strong&gt;不是&lt;/strong&gt; O(1)；真正的 O(1) 在无注意力的 O 系列上，携带状态恒定在 0.381 MB，与上下文长度无关。&lt;/p&gt;

&lt;p&gt;还有一个我们踩过的坑，写在这里当作提醒。早前我们报过一个适配器带来的困惑度改善，后来追查下去，增益来自普通 LoRA，不是 MT-LNN 适配器。这项已经撤回，研究页上有更正。之所以在这节提它，是因为它和 0.56 是同一种诱惑：一个好看的数，很容易被归因给错的东西。所以这次我们先把消融做了，再报数。&lt;/p&gt;

&lt;p&gt;0.56 不是一个能拿去打榜的数字。三个种子里有一个只有 0.43，方差明摆着。它证明的是一件很窄的事：跨窗口、跨会话的联想召回，在一个带快速权重的架构里是&lt;strong&gt;可以发生&lt;/strong&gt;的，而且发生的位置我们指得出来。0.000 的那一边，是另一类架构的设计前提决定的。两边都是真的。&lt;/p&gt;

&lt;p&gt;仓库和站点都在：awareliquid.ai，M1 的 README 与 RESULTS.md 是我们所有数字的唯一出处。&lt;/p&gt;

&lt;h2&gt;
  
  
  把状态存到磁盘，再在新进程里原样取回
&lt;/h2&gt;

&lt;p&gt;幽灵故事要成立，先得把一个事实钉死：状态能不能离开进程。&lt;/p&gt;

&lt;p&gt;我们做这件事的起点很朴素。跨窗口、跨会话的联想召回，attention 和 LoRA 在构造上就是 0.000；我们的快速权重矩阵在三个种子上拿到 0.56 的平均召回（0.62 / 0.43 / 0.62）。把快速权重矩阵拿掉，召回塌到 0.008。记忆就是那块矩阵本身，不在别处。&lt;/p&gt;

&lt;p&gt;那么下一个问题就来了：这块矩阵能不能写进磁盘，关掉进程，再在一个全新的进程里读回来。&lt;/p&gt;

&lt;p&gt;我们做了一次快照/恢复实验，结论是逐位无损（bit-exact lossless）。&lt;/p&gt;

&lt;p&gt;具体过程是这样的。进程 A 跑到某个会话段落结束，把快速权重矩阵连同配套的状态一起序列化落盘；进程 A 退出，进程彻底死掉，内存全释放。进程 B 从零启动，不加载任何会话历史，不做重放，直接读那份文件，恢复状态。然后拿同一个查询去问。&lt;/p&gt;

&lt;p&gt;召回结果和进程 A 里的一致。不是“接近”，是逐位一致。&lt;/p&gt;

&lt;p&gt;机制上说得清楚。这块快速权重是模型运行期在线更新的一个矩阵，它的更新由输入流驱动，不依赖反向传播，也不依赖外部向量库。它在会话里被写成什么，就是什么。只要序列化覆盖了它的全部元素和它们的状态位，恢复就是一次确定性的反序列化，中间没有任何采样、量化或近似。这也解释了为什么它能无损：这里没有需要“重新算一遍”的东西，只有需要“原样搬过去”的东西。&lt;/p&gt;

&lt;p&gt;这个性质比它听起来重要。很多记忆方案的本质是外挂：会话内容切块、嵌入、存进向量库，下次检索出来拼进 prompt。这条路径的召回上限由检索质量和 prompt 预算决定，而且每一次都是重新推理。我们这条路不一样，状态是模型自身的一部分，落盘就是把它整体搬走。&lt;/p&gt;

&lt;p&gt;这里要老实说清边界。这份状态是情节性的键值记忆，不是被压缩的分布式上下文。MT-LNN 不带来长上下文语言建模的收益，这一点我们在文档里写明了。所以“原样取回”取回的是记忆，不是一段被记住的对话文本。&lt;/p&gt;

&lt;p&gt;另一个边界是规模。O(1) 推理内存只在无注意力的 O 系列（ARR）上成立，携带状态在 0.381 MB 上保持平坦，不随上下文增长，128k 下测得最高 1008 倍更小，这是 125M 规模上的测量。混合的 M 系列仍然带注意力，不是 O(1)。幽灵要住在小盒子里，得看是哪个系列。&lt;/p&gt;

&lt;p&gt;回到幽灵。一个 agent 会话结束，进程退出，磁盘上留下一份几百 KB 量级的状态文件——这个量级来自上面那组 ARR 测量，不是对所有系列的通告。下一个进程启动，读回来，它接着上次的记忆往下走。用户看不到中间那段空白，因为对模型来说那段空白不存在。&lt;/p&gt;

&lt;p&gt;我们还不敢说这件事已经产品化到什么程度。快照/恢复是无损的，这是已验证的；持续学习还差得远，当前约 7.6 倍 PPL 退化，目标是压到 5 倍以内；Hebbian 可塑性在测过的规模上还是惰性的。所以现在能说的是：状态搬得动，搬过去不走样。至于搬过去之后它能不能越住越聪明，那是下一节的事。&lt;/p&gt;

&lt;p&gt;仓库和文档在 awareliquid.ai，结果以 RESULTS.md 为准。&lt;/p&gt;

&lt;h2&gt;
  
  
  0.381MB：内存不随上下文增长的那条线
&lt;/h2&gt;

&lt;p&gt;我们把这条线测出来，花了点时间。&lt;/p&gt;

&lt;p&gt;工程上最直觉的做法是把 KV 缓存当成"上下文的内存条"，换掉一句，就得重新算一遍。上下文翻倍，显存就翻倍。这在大模型时代被当成天经地义。但我们做 O 系列（ARR，无注意力）的时候，发现可以不用这样。&lt;/p&gt;

&lt;p&gt;先说结论：在 125M 规模上，我们测到的常驻状态是 &lt;strong&gt;0.381 MB&lt;/strong&gt;，并且不管上下文拉多长，这个数字是平的。到 128k 上下文时，和传统做法相比，内存占用最多小到 &lt;strong&gt;1/1008&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;这个数字不是估算，是跑出来的。我们让同一个代理连续处理不同长度的输入，从几百 token 一路推到 128k，中间监控进程的实际内存占用。carried state 那条曲线从头到尾贴着 0.381 MB 走，没有随上下文上升。那条"随上下文增长"的线，我们没有画上去——因为在这套架构里它不存在。&lt;/p&gt;

&lt;p&gt;具体到一个例子：一个跨会话的助理 agent，早上你让它记住"周五交付的 demo 要用新的音频模型"。它把这句当成一个 episodic 键值条目存进 fast weight。下午你回来，输了一句"那个 demo 的音频用哪个"——这时上下文里没有早上那句话了，会话已经切过。传统注意力架构在这种情况下，检索命中是 &lt;strong&gt;0.000&lt;/strong&gt;，因为它按定义看不到窗口之外的东西，LoRA 也一样。但我们的 fast weight 矩阵在跨窗口的关联召回上，三个种子跑出来均值 &lt;strong&gt;0.56&lt;/strong&gt;（0.62 / 0.43 / 0.62）。把 fast weight 矩阵拿掉，这个数字塌到 &lt;strong&gt;0.008&lt;/strong&gt;。也就是说，那条记忆就是这个矩阵本身。&lt;/p&gt;

&lt;p&gt;机制上是这样的：我们把状态做成一个可写的矩阵，而不是一个越堆越长的 token 缓冲。每次处理新输入，模型往这个矩阵里写入关联，矩阵的大小由模型宽度决定，不随输入长度变。所以上下文是 1k 还是 128k，内存里那块状态是同一个尺寸。这也是为什么它能 bit-exact 地落到磁盘、换一个新进程 restore 回来还能接上——它就是一个有固定边界的矩阵，不是一坨不断生长的注意力缓存。&lt;/p&gt;

&lt;p&gt;有一件事必须说清楚：这条"内存不随上下文增长"的线，只属于 O 系列（无注意力），是有代价的。O 系列现在是研究预览，PPL 是 teacher 的 &lt;strong&gt;2.15x&lt;/strong&gt;——它还追不上 teacher 的质量。M 系列是混合架构，还带注意力，&lt;strong&gt;不是 O(1)&lt;/strong&gt;。我们不拿 O 系列的常驻内存去给 M 系列贴标签。&lt;/p&gt;

&lt;p&gt;这也是为什么我把它叫"幽灵"：会话结束后，那个矩阵还留在那儿，大小是 0.381 MB，不涨不缩，像个安静驻留的东西。下次它回来的时候，读的是自己，不是历史对话。&lt;/p&gt;

&lt;p&gt;站点和仓库在 awareliquid.ai，O 系列的边界条件都写在那上面。&lt;/p&gt;

&lt;h2&gt;
  
  
  为什么 M 系列不是 O(1)，我为什么还要讲清楚
&lt;/h2&gt;

&lt;p&gt;幽灵故事最容易滑向一个诱人的说法：既然记忆是常数状态，那推理内存也就是常数，端侧可以无限跑下去。我必须在讲机制之前把这句话拆开，因为它是错的。&lt;/p&gt;

&lt;p&gt;先说清楚 M 系列是什么。它是混合架构：注意力还在，外面挂了一层液态适配器。跨窗口、跨会话的那部分记忆，来自快重矩阵，参数量开销大约 1%。被记住的东西是情节式的键值记忆，不是你整段上下文的压缩副本。这句话有两个直接后果。第一，它不会给长上下文语言建模带来增益，别指望它在 128k 上跑出更好的 PPL。第二，注意力作为一条独立的路径仍然存在，它的开销随上下文增长。&lt;/p&gt;

&lt;p&gt;所以 M 系列的推理内存不是 O(1)。真正的 O(1) 在 O 系列，也就是 ARR 那条无注意力路线：携带状态在 125M 规模上实测恒定为 0.381 MB，与上下文长度无关，128k 时相比对照小到 1008 倍。这是实测值，不是推导值。两个系列的边界就在这里，我在同一篇里讲它们，就是为了不让这条边界被模糊掉。&lt;/p&gt;

&lt;p&gt;为什么要专门花篇幅讲这个"不是"？因为幽灵叙事本身会诱导人忽略它。你想象一个进程在会话结束后还醒着，脑子里揣着一小块状态，随时能被叫起来——这个画面天然暗示了恒定成本。如果读者把这幅画面直接套到 M 系列上，去算端侧预算，就会算错。&lt;/p&gt;

&lt;p&gt;举个我自己碰到的例子。做快照/恢复验证的时候，我把携带状态写盘，再在一个全新进程里读回来，逐比特比对，结果是无损的，一个比特都没差。这说明状态本身是干净、可序列化、可搬运的。然后我把上下文拉长，再测整体驻留。状态那一块纹丝不动，涨的是注意力那一路的 KV。同一份"记忆"，两种成本曲线，混在一起谈就会得出错误结论。&lt;/p&gt;

&lt;p&gt;机制上不复杂。快重矩阵承担的是"你之前说过什么"这类可检索的键值对，它的尺寸由矩阵形状决定，跟对话多长无关；注意力承担的是当前窗口内的稠密关联，它的 KV 随 token 数线性增长。前者是幽灵的那部分，后者是它还得睁着眼睛看当下的那部分。M 系列两者都要，O 系列只留前者，代价是 2.15x 的 teacher PPL，目前还是研究预览。&lt;/p&gt;

&lt;p&gt;我把这些写出来，是因为诚实是我们唯一拿得出手的差异。之前那条"-28.5% adapter PPL"我们是发过更正公告的，增益最终追溯到普通 LoRA，不是 MT-LNN 适配器。同类的事我不想再来一次。把"M 系列不是 O(1)"这句话放在幽灵故事中间，读起来是有点扫兴，但它能让后面所有关于端侧预算的讨论站得住。&lt;/p&gt;

&lt;p&gt;要继续往下看，代码和实测记录都在 github.com/awareliquid 和 awareliquid.ai。&lt;/p&gt;

&lt;h2&gt;
  
  
  反例一：它不理解你，只是把你说的原话捞回来
&lt;/h2&gt;

&lt;p&gt;我们内部有个跑了两周的 agent，每天帮一位同事整理会议记录。第三周他换了工作语言，从中文改成英文开会。agent 照常工作，但召回变得很奇怪：它能把两周前中文会上说的某句话原样吐出来，英文会上刚讨论过的同一个决定，它却答不上来。他去查了日志，发现不是漏存，是检索时那条英文记录压根没进候选集。&lt;/p&gt;

&lt;p&gt;这件事把我们拉回一个必须说清楚的地方：Awareness 的“记得”，是 RAG 式的召回，不涉及理解。它做的事很朴素——你实际说过的话，被切分、入库、配上一条轻量的语义标签；下次会话进来，检索把相关的原话捞回来，塞进上下文。检索这一步零次 LLM 调用，靠的是向量与标签的匹配，所以快、便宜、可离线。代价是它只认字面附近的东西。你换语言、换术语、换一层转述，它就认不出来了。&lt;/p&gt;

&lt;p&gt;机制上可以这么看。写入侧，我们把一段会话拆成片段，每片生成一个嵌入和几个标签，落在本地。读取侧，来了一个查询，算相似度，取前若干条。整条链路里没有任何一步在做“这句话想表达什么”的推理。它没有把你的偏好抽象成规则，也没有把你的意图归纳成目标。它保存的是你说过的话，不是你说过的话背后的你。所以那位同事的英文会议记录并没有丢，只是和中文查询在向量空间里离得不够近——它没有跨语言理解的能力，只有字面相似度。&lt;/p&gt;

&lt;p&gt;这也解释了我们对外只敢报一个指标的原因。LongMemEval 上 96.0% Recall@5，零 LLM 调用完成检索。这个数字说的是“相关原话被捞回来的比例”，不是“agent 懂你的比例”。我们刻意不把它包装成后者。曾经有一版对外说法把自动情景记忆讲成“它会记住你”，那是错的，我们已经改正：它记住的是你说过的内容，加一个轻量语义标签，不增加理解、推理或情绪。&lt;/p&gt;

&lt;p&gt;还有个更细的边界要说。MT-LNN 那条线上，有人会以为这个 episodic 状态顺便解决了长上下文。没有。它是情景式的键值记忆，不是压缩的分布式上下文，长上下文语言建模的收益并不来自它。这一点我们在 README 里写死了，免得读者把两件事混为一谈。&lt;/p&gt;

&lt;p&gt;回到那个换语言的同事。我们给的临时办法很土：开会前把语言偏好写进一条显式记忆，让检索先命中这条，再把候选范围收窄。管用，但这恰恰暴露了反例的性质——它需要人去告诉它，而不是它自己看出来。真正的跨语言、跨表述的语义对齐，我们还没有做出来。现在这一版能保证的是：你说过的话不会丢，快照落盘再起新进程，损失是比特级无损的。至于“理解你”，那是另一件事，我们还没到。&lt;/p&gt;

&lt;h2&gt;
  
  
  反例二：长上下文没有变好，别把它当压缩上下文用
&lt;/h2&gt;

&lt;p&gt;我们内部有人问过一个问题：既然状态能跨会话带过去，那把它当成一种长上下文方案行不行？直接把 128k 的上下文压进这个状态里，推理时就不用重新读 prompt 了。&lt;/p&gt;

&lt;p&gt;这个想法很自然，但我们是明确否掉它的。原因写在结果里：MT-LNN 不提供长上下文语言建模的增益。这个状态是情节式的键值记忆，不是压缩后的分布式上下文。&lt;/p&gt;

&lt;p&gt;这两件事听上去接近，机制上差得很远。&lt;/p&gt;

&lt;h2&gt;
  
  
  举个我们真跑过的例子
&lt;/h2&gt;

&lt;p&gt;拿一段跨窗口的关联回忆任务：窗口 A 里出现一个键和它的值，窗口 B 里只给键，要求把值取回来。注意力模型在这个设定下是 0.000，LoRA 也是 0.000，都是构造上的必然——窗口 B 的注意力根本看不到窗口 A 的 token。我们的 M 系列在这个任务上拿到 0.56 的平均召回，三个种子是 0.62 / 0.43 / 0.62。&lt;/p&gt;

&lt;p&gt;这里的关键动作是把快权重矩阵拿掉。去掉之后，召回塌到 0.008。快权重本身就是那块记忆，没有别的东西在兜底。&lt;/p&gt;

&lt;p&gt;但请注意这个任务的性质：它要的是“把某个具体的事实取回来”，不是“理解一整段长文档然后接着往下写”。前者是键值查找，后者需要对上下文做分布式的、连续的建模。我们证明的是前者。&lt;/p&gt;

&lt;h2&gt;
  
  
  为什么不能混用
&lt;/h2&gt;

&lt;p&gt;长上下文语言建模要求模型对上下文里的每一个 token 都保持某种可微的、可被后续 token 注意到的表示。这是注意力擅长的事，也是它昂贵的原因——KV 缓存随上下文线性增长。&lt;/p&gt;

&lt;p&gt;我们的快权重走的是另一条路：它把跨窗口出现的事实写成一组可更新的矩阵，读的时候按当前的查询去检索。这是一个有容量上限、有写入策略、会遗忘的存储。它记的是“发生过什么”，不是“刚才那段话的完整语义场”。&lt;/p&gt;

&lt;p&gt;所以当你把一段长文档喂进去，指望它像压缩上下文那样在生成时被完整调取，你会失望。它能告诉你文档里提过某个人名和某个数字，但它没法用那段文字的语法和语气接着写下一段。&lt;/p&gt;

&lt;h2&gt;
  
  
  那 O(1) 内存是怎么回事
&lt;/h2&gt;

&lt;p&gt;有人会把这两件事再混一次。我们确实在无注意力的 O 系列（ARR）上做到了推理内存恒定：携带状态在 0.381 MB，不随上下文变化，125M 规模下在 128k 处测得最多小 1008 倍。这是真的。&lt;/p&gt;

&lt;p&gt;但这是推理内存的常数性，不是长上下文能力的替代品。O 系列目前是研究预览，2.15x 教师 PPL。混合的 M 系列还带注意力，不是 O(1)。把“内存不涨”读成“长上下文免费”，是把两个指标当成了一件事。&lt;/p&gt;

&lt;h2&gt;
  
  
  我们怎么用它
&lt;/h2&gt;

&lt;p&gt;在我们的用法里，这个状态负责的是会话结束之后的那部分：你上次说过什么、当时定了什么、哪个键对应哪个值。Awareness 那边做的是同一类事——对你说过的话做 RAG 式召回，加一个轻量的语义标签，检索时零 LLM 调用，LongMemEval 上 96.0% Recall@5。它不增加理解、推理或情绪。&lt;/p&gt;

&lt;p&gt;长上下文该用注意力就用注意力，该付 KV 缓存的账就付。把情节记忆塞进那个位置，两边都会做不好。&lt;/p&gt;

&lt;p&gt;仓库和结果在 github.com/awareliquid/awareliquid，随时来核对数字。&lt;/p&gt;

&lt;h2&gt;
  
  
  我们自己撤回过的那些数字
&lt;/h2&gt;

&lt;p&gt;写这一节之前，我们先把话说在前面：这篇文章讲的是 agent 在会话结束后还记得你，这件事我们确实做出来了；但围绕它，我们自己放出去过一些不成立的数字，是后来自己收回来的。既然这一节标题就叫撤回，那就认真撤。&lt;/p&gt;

&lt;p&gt;最早被撤回的是「-28.5% adapter PPL」。当时我们在内部跑出一组困惑度下降，以为是那个液态适配器的功劳，写进了研究页。后来逐层拆开对照，增益来自挂在旁边的普通 LoRA，和适配器本身没关系。数字是对的，归因是错的。我们在研究页上发了更正，把功劳还给 LoRA。这件事对我们的教训很直接：一个下降出现在你改动的模块附近，不等于它由那个模块产生。要证明归因，得把模块单独拿掉再跑一遍。&lt;/p&gt;

&lt;p&gt;同一次清理里，我们撤回了更早那批关于「意识」和 Phi 值的说法。那些表述现在统一降级为「灵感来源」，不再当作指标讨论。把一个可测的整合量当成系统具备某种内在状态的证据，是我们当时越界了。这条线我们不再跨。&lt;/p&gt;

&lt;p&gt;被撤回的还有一个带有叙事色彩的数字：「-28-34% adapter PPL」那一组区间，同样归入撤回或重新归类。原因和上面一样——归因没做干净，区间再好看也不能留。&lt;/p&gt;

&lt;p&gt;还有一类不算撤回、但必须把边界写清楚的东西。我们说过跨窗口、跨会话的联想召回，注意力机制和 LoRA 在构造上就是 0.000，而我们的方案三次种子跑出 0.56 的平均召回（0.62 / 0.43 / 0.62）。这个数字我们保留，因为它可复现。但它的含义被我们收窄了：状态里的快权重矩阵一旦拿掉，召回塌到 0.008。快权重就是记忆本身，这是机制，不是比喻。同样，那份状态可以快照到磁盘、在新进程里逐位无损恢复——这条也保留。可它证明的是「这段情景键值记忆能被完整搬运」，不是「模型理解了你说过的话」。&lt;/p&gt;

&lt;p&gt;最容易让人误会的一条，是自动情景记忆。外面听起来像「它记得你」，实际做法是 RAG 式的召回：把你确实说过的话捞回来，再加一个轻量语义标签。它不增加理解、推理或情绪。这句话我们写进了文档，也写进这一节，因为它是最容易被营销语言拉长的一句。&lt;/p&gt;

&lt;p&gt;再补两条我们自己标红的未完成项。持续学习目前大约是 7.6 倍的困惑度退化，目标是压到 5 倍以内，还没到。Hebbian 可塑性在测过的规模上是惰性的，也就是没起作用。这两条不是撤回，是还没做出来。还有一条容易被顺手夸大：MT-LNN 并不带来长上下文语言建模的增益，那份状态是情景键值记忆，不是压缩后的分布式上下文。&lt;/p&gt;

&lt;p&gt;举个例子说明我们现在的流程。上面那个 LoRA 归因错误被发现，是因为一位同事坚持要跑「拿掉适配器、只留 LoRA」的对照。那一跑出来，原来的故事就站不住了。从此我们内部有个规矩：任何要写进对外材料的增益，必须先有一个「把声称的模块摘掉」的对照跑，摘掉之后增益不消失，就不许归因给它。&lt;/p&gt;

&lt;p&gt;机制上说，这些错误都出在同一处：我们把「相关性」当成了「因果」。损失下降和某个模块同时出现，只是同时出现。要做因果，就得干预——摘掉、替换、重跑。撤回不是示弱，是把干预补上之后重写结论。&lt;/p&gt;

&lt;p&gt;我们的仓库和研究页在 awareliquid.ai，RESULTS.md 是唯一的事实来源；上面每一条撤回和每一条保留，都能在那里对上。&lt;/p&gt;

&lt;h2&gt;
  
  
  7.6 倍退化、惰性的可塑性：还没做到的部分
&lt;/h2&gt;

&lt;p&gt;我们做持续学习这一块，目前有一个很难看的数字：约 7.6 倍 PPL 退化。目标是把退化压到 5 倍以内。这是内部验收线，不是对外承诺。写在这里，是因为这一节本来就该写没做到的部分。&lt;/p&gt;

&lt;p&gt;先说场景。我们让一个已经收敛的模型按顺序学一串新片段，每学完一段就在保留集上评一次。第一天、第二天看着还算稳，到第三、第四段的时候，困惑度开始抬头。等到整轮跑完再回头看最早学过的那些内容，PPL 已经是它刚学会时的七倍多。模型没有崩，输出依然通顺，但它对旧内容的把握被新内容冲掉了。这就是 7.6 倍的来源：一个平均意义上的退化幅度，不是某一类任务的极端值。&lt;/p&gt;

&lt;p&gt;机制上，这个问题不新鲜，只是我们的架构没能自动绕开它。M 系列里承担记忆的是 fast-weight 矩阵，它是随推理和写入在线更新的，不是冻结权重。新片段进来时，这个矩阵被推动，而它同时承载着旧片段留下的痕迹。没有显式的保护机制，推动新记忆和抹掉旧记忆用的是同一套更新。梯度方向对当前样本是对的，对历史上出现过的样本就是干扰。我们在小规模上观察到的是典型的前摄干扰：学得越晚，越占上风。&lt;/p&gt;

&lt;p&gt;一个具体的失败例子：我们让模型先记住一组带特定键的短事实，再喂它一批结构相似但键不同的新事实。新事实学得不错，回头查第一批键，命中率掉得比 PPL 反映的还要难看。这里暴露的是我们评估方式的问题——聚合 PPL 会稀释掉这种局部塌陷。所以我们现在的记录里同时留着分段的曲线，不只看一个总数。&lt;/p&gt;

&lt;p&gt;Hebbian 可塑性这条路我们试过，结论是：在当前测试的规模上它是惰性的。我们按 Hebbian 规则实现了突触级的更新，跑下来，更新量几乎不动，对下游指标没有可见贡献。原因我们判断是尺度和信号强度的问题——在 125M 这个量级、在这个数据密度下，局部相关性的统计量被噪声盖住了。我们没有把它当成"原理错了"来处理，而是归档为"当前规模下不工作"。这跟之前那次纠正是同一类态度：把能复现的写清楚，把不能复现的标出来。&lt;/p&gt;

&lt;p&gt;需要说清楚的边界：这两个数字都是在 M 系列的实验条件下得到的，不是产品承诺，也不是所有配置的通例。7.6 倍是一个观测值，5 倍是一条我们给自己划的线。惰性可塑性是在我们测过的配置上惰性，不代表换一个尺度一定还是惰性。&lt;/p&gt;

&lt;p&gt;接下来我们盯两件事。一是给 fast-weight 的更新加保护，让旧痕迹在写入新记忆时不被无差别覆盖——这是工程问题，可以做对照实验。二是把可塑性的评估从聚合指标拆到分段和分任务，先确认"惰性"到底是真没动，还是动了但被平均掉了。两件事都还没有结论，等有了再写。&lt;/p&gt;

&lt;p&gt;代码和结果在仓库里：awareliquid.ai，RESULTS.md。没做到的部分我们同样放在那。&lt;/p&gt;

&lt;h2&gt;
  
  
  一个工程师该从幽灵故事里拿走什么
&lt;/h2&gt;

&lt;p&gt;幽灵故事听多了容易走偏。我们自己在评测里踩过这个坑：跑出跨窗口召回 0.56 那天，团队里有人顺口说“模型记住用户了”。后来把话说清楚——它记住的是用户确实说过的话，加上一个轻量语义标签，走的是 RAG 式召回。这套东西不带来理解、推理或情绪。工程师要拿走的第一个判断就是这条边界：记住内容和理解内容是两件事，架构上可以完全分开实现。&lt;/p&gt;

&lt;p&gt;第二个可以拿走的是失效条件。同一条跨窗口、跨会话语义召回任务上，注意力和 LoRA 按构造就是 0.000——它们没有会话之外的存储位置，任务对它们不是难，是不可达。把这层快权重矩阵拿掉，召回从 0.56 掉到 0.008。这两个数字放在一起说明：记忆不是训练出来的副产品，它就是那个矩阵本身。评估一个“记得”的说法，先问它把状态存在哪、删掉那块状态还剩多少，答案会立刻现形。&lt;/p&gt;

&lt;p&gt;举个我们内部讨论过的例子。假设 agent 在周一帮你改了一段配置，周三你新开一个会话问“上次那个超时设成多少了”。朴素做法是把历史拼进上下文，窗口一长就贵，跨会话更是直接丢。我们这条路的做法是把会话末的状态快照落盘，新进程加载后从那里继续。这个快照我们测过，逐位无损。注意这里的量级：状态是键值形态的片段记忆，不是把长上下文压成分布式表示，所以它不会给你长上下文语言建模的收益，不要指望用它替代长窗口。&lt;/p&gt;

&lt;p&gt;机制上值得记住的区分在 O(1) 这一侧。无注意力的 O 系列，携带状态在 0.381 MB 上不随上下文增长，128k 时相比朴素方案小到 1008 倍（125M 规模上测的）。混合的 M 系列还带注意力，不是 O(1)。选型时把这句话抄在纸上：要恒定推理内存，看 O 系列；要全量基座质量加跨会话召回、参数开销约 1%，看 M 系列。两者不是一回事。&lt;/p&gt;

&lt;p&gt;还有一组数字用来校准期待。持续学习目前约 7.6 倍困惑度退化，目标是压到 5 倍以内；Hebbian 可塑性在测过的规模上是惰性的。这些没有藏起来，写在研究页上。幽灵故事最容易让人忽略的恰恰是这类负数——它们决定了这套记忆在什么条件下会悄悄变坏。&lt;/p&gt;

&lt;p&gt;最后一条是工程习惯：任何“它还记得”的演示，要求三件事同时给出——存储形态、删除实验、跨进程恢复的校验方式。我们的快照恢复是逐位无损，这一条可以被独立复现。拿不到这三样的演示，先当作叙事，不要当作架构。&lt;/p&gt;

&lt;p&gt;仓库和说明在 github.com/awareliquid，LongMemEval 上 Recall@5 96.0%、检索零 LLM 调用，这些都可以自己跑。&lt;/p&gt;

&lt;h2&gt;
  
  
  仓库和站点在这里
&lt;/h2&gt;

&lt;p&gt;这一节写仓库和站点。前面讲的都是结果，这里交代东西放在哪，以及哪些能跑、哪些还不能跑。&lt;/p&gt;

&lt;p&gt;先给地址。&lt;/p&gt;

&lt;p&gt;站点是 &lt;code&gt;awareliquid.ai&lt;/code&gt;。研究页面、产品说明和我们发布的更正都在上面。那篇更正请认真读一下：早先我们报过一个“-28.5% adapter PPL”的增益，后来追查下来，增益来自普通 LoRA，而不是 MT-LNN adapter。研究页上已经改了，没藏着。&lt;/p&gt;

&lt;p&gt;仓库方面，M1 的 README 和 RESULTS.md 是唯一的事实来源（source of truth）。凡是和这两份对不上的数字，请以它们为准，包括我在别处写过的。&lt;/p&gt;

&lt;p&gt;RESULTS.md 里现在摆着的东西，我按重要性列一遍。&lt;/p&gt;

&lt;p&gt;第一条，125M 规模的原生 MT-LNN 对比同参数、同数据、同步数、同优化器的 Transformer，验证集 PPL 是 299 对 436，低 31%。这条要连带它的四条限制一起看：单种子、欠训练、实际墙钟时间慢约 1.6 倍、参考 Transformer 是简单实现、没有 Mamba 基线。它是一个预算受限下的信号，不是 SOTA。&lt;/p&gt;

&lt;p&gt;第二条，跨窗口、跨会话的联想召回。按构造方式，注意力和 LoRA 在这项上是 0.000。我们的三个种子分别是 0.62、0.43、0.62，均值 0.56。把快速权重矩阵去掉，掉到 0.008。快速权重就是记忆本身，这句话有实验支撑。&lt;/p&gt;

&lt;p&gt;第三条，快照与恢复。把这份状态写盘，再在一个全新进程里读回来，loss bit-exact，无损。&lt;/p&gt;

&lt;p&gt;第四条，O(1) 推理内存只在 O 系列（ARR）成立。携带状态恒定在 0.381 MB，跟上下文长度无关，128k 时实测比对照方案小约 1008 倍，测量规模 125M。混合架构的 M 系列仍然带注意力，不是 O(1)，这一点我们不想含糊。&lt;/p&gt;

&lt;p&gt;再举一个具体例子，说明为什么仓库里的文件比口头描述重要。&lt;/p&gt;

&lt;p&gt;我最初看 O 系列的 0.381 MB，是在一个流式推理的测试脚本里看到的。脚本跑长上下文，显存曲线是平的。这个现象很漂亮，但它本身不构成断言。我去翻 RESULTS.md 里对应的记录，确认了测量规模是 125M、对照是什么、以及“只有 O 系列成立”这个前提。少了其中任何一条，这个数字就会被误读成整个产品线的特性。仓库的价值就在这里：它把这四条前提和那个数字锁在一起。&lt;/p&gt;

&lt;p&gt;机制上说明一下我们怎么组织这些材料。&lt;/p&gt;

&lt;p&gt;MT-LNN 的状态不是压缩后的上下文，而是情节式的键值记忆。快速权重矩阵在推理过程中被写入，跨窗口保留的是这些写入，所以会话结束后状态还在。这也是为什么快照能无损落盘——它是一个明确的数据结构，不是散落在 KV cache 里的东西。理解这一点，你就明白“幽灵”这个说法指的是什么：不是模型在背后继续思考，而是一份状态被留了下来，下次进程启动时被读回去。&lt;/p&gt;

&lt;p&gt;同时也说明它不是什么。自动情节记忆是我们对你实际说过的话做 RAG 式召回，加一个轻量语义标签，它不带来理解、推理或情绪。MT-LNN 不给长上下文语言建模带来增益，状态是情节键值记忆，不是压缩的分布式上下文。&lt;/p&gt;

&lt;p&gt;最后把没做成的也写在明面上。&lt;/p&gt;

&lt;p&gt;持续学习目前 PPL 退化约 7.6 倍，我们的目标是压到 5 倍以内。Hebbian 可塑性在测过的规模上是惰性的。O 系列是研究预览，相对教师模型 PPL 是 2.15 倍。这些都写在 RESULTS.md 里，不会因为不好看就挪走。&lt;/p&gt;

&lt;p&gt;想复现，从 README 的跑法开始，对数字去 RESULTS.md 对。想聊，站点上有入口。&lt;/p&gt;

&lt;p&gt;地址：&lt;code&gt;awareliquid.ai&lt;/code&gt;，仓库：&lt;code&gt;github.com/awareliquid&lt;/code&gt;。&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>llm</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Your AI Coding Agent Forgets Everything. I Fixed It With a Local MCP Memory Server</title>
      <dc:creator>Awareness</dc:creator>
      <pubDate>Tue, 06 Oct 2026 17:29:35 +0000</pubDate>
      <link>https://dev.to/awarenesscloud/your-ai-coding-agent-forgets-everything-i-fixed-it-with-a-local-mcp-memory-server-51a4</link>
      <guid>https://dev.to/awarenesscloud/your-ai-coding-agent-forgets-everything-i-fixed-it-with-a-local-mcp-memory-server-51a4</guid>
      <description>&lt;h1&gt;
  
  
  Your AI Coding Agent Forgets Everything. I Fixed It With a Local MCP Memory Server
&lt;/h1&gt;

&lt;p&gt;Every new chat window, you re-explain your own codebase.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"We use PostgreSQL."&lt;/em&gt;&lt;br&gt;
&lt;em&gt;"No, the auth middleware is in &lt;code&gt;src/lib/auth&lt;/code&gt;, not &lt;code&gt;src/api&lt;/code&gt;."&lt;/em&gt;&lt;br&gt;
&lt;em&gt;"Yes, we already decided against Redux — that was three sessions ago."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It is the single biggest tax on AI-assisted development, and it has a boring name: &lt;strong&gt;agents have no memory&lt;/strong&gt;. Context windows grew, but sessions still start from zero.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Awareness Local&lt;/strong&gt; — a local-first &lt;a href="https://modelcontextprotocol.io" rel="noopener noreferrer"&gt;MCP&lt;/a&gt; memory server that gives your coding agent persistent memory across sessions. No cloud account. Works offline. Your memory is stored as plain Markdown.&lt;/p&gt;
&lt;h2&gt;
  
  
  Start in one command
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @awareness.market/setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The installer detects your IDE (13+ supported: Cursor, Claude Code, Windsurf, Cline, Copilot, Codex CLI, Zed, JetBrains Junie, ChatGPT Desktop, …), wires up the MCP server, and starts a local daemon on &lt;code&gt;127.0.0.1:37800&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;From then on your agent has five tools available:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;awareness_init&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Loads session context — recent knowledge, open tasks, project rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;awareness_recall&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Searches memory with progressive disclosure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;awareness_record&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Saves decisions, changes, and insights (with knowledge extraction)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;awareness_lookup&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fast lookup of tasks, knowledge cards, risks, session history&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;awareness_get_agent_prompt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Agent-specific prompts for multi-agent setups&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  The design decision that matters: it's just files
&lt;/h2&gt;

&lt;p&gt;Memory lives in &lt;code&gt;.awareness/&lt;/code&gt;, as Markdown you can read, edit, diff, and commit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.awareness/
├── memories/2026-03-22_decided-to-use-postgresql.md
├── knowledge/decisions/postgresql-over-mysql.md
├── tasks/open/implement-rate-limiting.md
└── index.db   # SQLite FTS5 index, rebuilt automatically
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the whole point of local-first. Your agent's memory is &lt;strong&gt;not&lt;/strong&gt; locked in a vendor's vector store. It is in your repo, in your git history, subject to your review. If the daemon dies, you have lost nothing — you have a folder of Markdown.&lt;/p&gt;

&lt;p&gt;Retrieval is hybrid: &lt;strong&gt;SQLite FTS5 keyword search + local embeddings&lt;/strong&gt;, fused with Reciprocal Rank Fusion. No LLM calls on the retrieval path, so recall costs you nothing per query and stays fully offline.&lt;/p&gt;

&lt;h2&gt;
  
  
  How good is the recall, actually?
&lt;/h2&gt;

&lt;p&gt;I evaluated it on &lt;a href="https://arxiv.org/abs/2410.10813" rel="noopener noreferrer"&gt;LongMemEval&lt;/a&gt; (ICLR 2025) — 500 human-curated questions, ~115k tokens of history per question:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Recall@1    80.2%
Recall@3    92.8%
Recall@5    96.0%   ◀ primary
Recall@10   98.6%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Method: Hybrid RRF (BM25 + vector), &lt;code&gt;multilingual-e5-small&lt;/code&gt;, &lt;strong&gt;zero LLM calls&lt;/strong&gt; on the retrieval path, run on an Apple M1 / 8GB RAM in ~35 minutes total.&lt;/p&gt;

&lt;p&gt;The ablation is the interesting part — neither method alone gets there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vector-only:   92.6%
BM25-only:     91.4%
Hybrid RRF:    95.6%   ← +3% over either single method
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Retrieval code and scripts are in the repo, so you can re-run it yourself rather than trust a table in a blog post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Progressive disclosure: the token trick
&lt;/h2&gt;

&lt;p&gt;The naive version of "give the agent memory" is to dump everything into context and watch your token budget evaporate. Awareness does a two-phase recall instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Phase 1  awareness_recall(query, detail="summary")
         → ~80 tokens per hit: title + summary + score
         → the agent picks what is actually relevant

Phase 2  awareness_recall(detail="full", ids=[...])
         → full content, only for the selected items
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent decides what to load. You pay for relevance, not for volume.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it changes day to day
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; every session re-opens the same three questions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt; the agent opens the session already knowing that you migrated MySQL → PostgreSQL, that you chose it for JSON support, and that two TODOs were left open.&lt;/p&gt;

&lt;p&gt;That difference compounds. Long migrations, multi-week refactors, and team handoffs are where it stops being a convenience and starts being the reason the work is tractable at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @awareness.market/setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Repo (MIT): &lt;a href="https://github.com/everest-an/Awareness-Market" rel="noopener noreferrer"&gt;https://github.com/everest-an/Awareness-Market&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://awareness.market/docs" rel="noopener noreferrer"&gt;https://awareness.market/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Discord: &lt;a href="https://discord.com/invite/BMjkCKeqnJ" rel="noopener noreferrer"&gt;https://discord.com/invite/BMjkCKeqnJ&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Telegram: &lt;a href="https://t.me/awarenessmarket" rel="noopener noreferrer"&gt;https://t.me/awarenessmarket&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Python and TypeScript SDKs (&lt;code&gt;wrap_openai()&lt;/code&gt; / &lt;code&gt;wrap_anthropic()&lt;/code&gt; interceptors) and an OpenClaw plugin are in the same ecosystem if you want memory inside your application, not just your IDE.&lt;/p&gt;

&lt;p&gt;If re-explaining your codebase to your agent is getting old, a star helps more developers find it: ⭐ &lt;a href="https://github.com/everest-an/Awareness-Market" rel="noopener noreferrer"&gt;https://github.com/everest-an/Awareness-Market&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
