Skip to content

Akasha:不是检索过去,而是让过去在此刻发光

面向个人 agent 的记忆系统,现在大多走错了路。

错不在它们用了 embedding,也不在它们用了向量库。 错在它们把检索误认成了记忆

检索问的是:

哪段旧文本,和现在这句话最像?

但记忆问的是另一件事:

此刻,哪一段过去应该被轻轻推到意识边缘,帮助我继续理解这个人?

这两个问题看起来很近,实际上隔着一整片海。

你说:

昨天在和 limboo 玩杀戮尖塔。

普通向量库会还给你更多“杀戮尖塔”的说法: 杀戮尖塔、Slay the Spire、卡组、爬塔、机器人、战士。

这不算错。 只是太浅。

真正的个人记忆不应该只想起词。 它应该想起关系。

它应该知道: limboo 不只是一个字符串。 limboo 和你一起玩过杀戮尖塔。 你是亡灵契约师,limboo 是战士。 你们和舍友联机。 你们都玩机器人。 有些记忆单看并不像“杀戮尖塔”,但在人生里,它们就是同一片夜空里的星。

这就是 Akasha 要做的事。

Akasha 不是一个更大的向量库。 它是一张会随着对话生长的私人星图。

在这张星图里,每一句话都是星。 每一次共同被想起,星与星之间就多一条微弱的光线。 那些后来反复被当下照亮的线,会越来越清晰。 那些只因偶然擦肩而亮过一次的线,会慢慢退回夜色。

所以 Akasha 的核心不是“存储”。 它的核心是两句话:

The message is the only truth.To remember is to recommend.

消息即唯一真相。 记忆即推荐。

Akasha 不替你总结人生。 它只守着你真正说过的话,让那些被时间反复需要的东西,自己长成记忆。


一、为什么现有 memory 不是 memory

现在很多 agent memory,本质上仍然是问答系统的尾巴。

它们先把对话提炼成几条“用户画像”:

用户喜欢咖啡。 用户住在东京。 用户有一个朋友叫 limboo。 用户最近手指受伤。

然后等你下次问相关问题,再把这些条目检索回来。

这叫资料库。 不叫记忆。

资料库是死的。 记忆是活的。

资料库等你问。 记忆会在你还没有完全说出口的时候,主动把一段过去推到你面前。

更致命的是,很多系统从写入第一刻就犯错:它们急着判断什么重要。

它们用使用次数判断重要。 于是“你好”“晚安”“在吗”“查天气”这种高频废话,被系统当成重中之重。

它们用最近出现判断重要。 于是今天一句无聊闲话,可以把上个月真正重要的事顶掉。

它们让 LLM 给重要性打分。 于是模型根据“看起来重要”来猜,而不是根据“对你这个人真的重要”来生长。

这三种方法看起来不同,病根是同一个:

它们都把重要性当成一个可以在写入时贴上的标签。

但个人记忆不是这样工作的。

一个名字第一次出现时,它可能只是一个名字。 十几次之后,它成了朋友、游戏、深夜、争吵、联机、某种只有你们之间才懂的语气。

一件事第一次说出时,它可能只是一个事实。 几天之后,它和疼痛、药、医院、担心、恢复、再次询问,织成一段 episode。

重要性不是被授予的。重要性是被照亮的。

一条记忆不是因为系统宣布它重要,所以重要。 它是因为后来一次又一次在合适的语境中被需要,才慢慢有了亮度。

这就是 Akasha 的第一条原则:

重要性不是标签,而是光度。记忆不是买断,而是回声。遗忘不是删除,而是光慢慢暗下去。


二、先用一张图理解 Akasha

为了更容易理解,可以先把 Akasha 想成一座夜里的私人天文台。

Akasha 里的东西可以想成什么它真正做什么
原始消息星体本身你真正说过的话,不改写,不总结
node星图上的一颗星一轮 user + assistant 对话的索引点
embedding星的位置用来找“语义相似”的过去
FTS / IDF星名索引用来抓 limboo 这种稀有专名
salience初生亮度这句话和日常背景有多不一样
strength长时光度这颗星在长期记忆里有多能发光
resource短时体力刚被用过的星,暂时不要反复霸屏
edge星座连线两颗星过去是否经常一起被想起
direct左眼看见“相似文本”
ripple右眼看见“不相似但相关”的联想
score此刻亮度这条记忆现在该不该浮上来
top-8 activation被真正看见的星只有它们会参与学习,织进未来

这张表就是整套系统的缩略图。

Akasha 的记忆不是一条条 fact。 它是:

原始消息不动; 在原始消息之上建索引; 在索引之间长出边; 让边和节点随时间变亮或变暗; 每次 query 进来时,重新结算此刻哪几颗星应该被照亮; 再把这次照亮的结果写回星图,成为明天的路。

这就是它和普通向量库的根本差别。

向量库只问“像不像”。 Akasha 还问:

它们过去是否一起出现过? 这件事是否偏离你的日常? 这条记忆是否长期被真正需要? 它是不是刚刚被用过,需要暂时退后? 它是不是一个到处乱连的 hub,需要被压住? 此刻把它交给 LLM,会不会让回答更像是发生在“我们之间”?

所以 Akasha 的召回不是 retrieval。 它更像 recommendation。

不是“我找到了你问的东西”。 而是:

我想起了一段可能应该在场的过去。


三、消息即唯一真相:Akasha 到底存什么

Akasha 不提炼记忆。

这是第一条铁律。

它不把你的对话总结成:

用户手指受伤,曾去医院处理。

因为这句话太干净了,干净到失真。

你真正说的可能是:

肿得厉害,去医院切开引流,塞了根引流条。

这里面有痛感,有具体动作,有“引流条”这个未来会反复被唤醒的词,有一种用户当时的身体状态。 如果把它总结成“用户手指受伤”,信息没有消失在表面上,却消失在灵魂里。

更危险的是,LLM 的总结会引入幻觉。

LLM 回答一次,可能有一层幻觉。 把对话再提炼成记忆条目,又一层。 检索时再改写 query,又一层。

一层一层叠上去,最后系统拿着一条看似整洁、其实变形过的“记忆”来理解你。 它不是忘了你。 它是记错了你。

而比忘记你更糟的,是它记得你,但记错了你。

所以 Akasha 做了一个很克制的决定:

原始消息不动。Akasha 只在原始消息之上建索引。

一轮对话,也就是一条 user 消息和紧接着的 assistant 回复,会形成一个 node。 但 node 不复制消息,不重写消息,不总结消息。 它只保存一个指针,指回宿主数据库里的原始对话。

这就是:

The message is the only truth.

这里的 truth 不是世界真相。 Akasha 不会因为你说“我发烧了”,就替世界证明你真的发烧。 它确认的是另一种更基础、更不可冒犯的真相:

你曾经在某个时刻,这样说过自己。

个人记忆首先要尊重的,不是系统的归纳能力。 而是人的原话。


四、在真相之上,Akasha 建三种索引

原始消息不动,但系统必须能找回它。 所以 Akasha 在原话之上建三层召回底座。

1. 向量:找语义相似

每条原始消息都会进入 embedding cache。 这是消息级粒度。

同时,一轮 user + assistant 会形成一个 turn-level node embedding。 这是轮次级粒度。

为什么要两套?

因为消息级更细,能精确命中某一句; turn 级更稳,能代表这一轮对话的整体语义。

比如你问“引流条拔出来流血怎么办”,消息级 embedding 可能精确命中“引流条”“血”“换药”; turn 级 node 则把这轮对话背后的上下文带回来。

这一路就是 direct。 它像左脑,稳定、清楚、保守。 它回答的是:

哪些旧消息和现在最像?

2. FTS + IDF:抓住稀有名字

embedding 对常见概念很强。 但对一些私人世界里的稀有词,不一定可靠。

比如:

limboo

对一个通用 embedding 模型来说,它可能只是一个怪词。 但对你来说,它是一个具体的人,一个关系节点,一个会牵出很多过去的名字。

所以 Akasha 还建了 FTS 字面索引,并用 IDF 过滤高频废词。

“在吗”“今天”“感觉”“一下”这种词,人人都说,信息量低。 “limboo”“鱼石脂”“亡灵契约师”这种词,出现少,但一出现就很可能有意义。

FTS 的职责不是替代 embedding。 它是给私人专名留一条硬路。

embedding 像听语气。 FTS 像认名字。

3. 新颖度基线:知道什么偏离日常

Akasha 还维护一个全局重心 c。 可以把它想成:

到目前为止,你所有话语的平均方向。

每条新消息进来时,系统会看它和这个平均方向有多远:

σ=clamp((1cos(v,c))×2,  0,  1)\sigma=\text{clamp}\big((1-\cos(v,c))\times 2,\;0,\;1\big)

逐个参数讲透:

  • vv本条消息的单位向量。原始消息文本过 embedding 模型后,再做 L2 归一化得到,维度和模型输出维度一致。
  • cc全局语义重心。增量维护的、所有历史消息单位向量的平均值,再做 L2 归一化:c=normalize(i<tv^i)c = \text{normalize}\left(\sum_{i < t} \hat{v}_i\right)。关键的因果约束:它只累加此前的消息,不看未来——所以第一句话没有"过去",σ=0\sigma=0;越偏离你此前说过的一切,σ\sigma 越高。
  • cos(v,c)\cos(v,c)vvcc 的余弦相似度,范围 [1,1][-1, 1]。语义越接近重心,越接近 11;越偏离,越接近 00(个人语料里负相似度极少出现)。
  • ×2\times 2:把 (1cos)(1-\cos) 的范围 [0,1][0, 1] 放大到 [0,2][0, 2],让中等偏离也能拿到较高的 σ\sigma
  • clamp(,  0,  1)\text{clamp}(\cdot,\;0,\;1):把结果裁剪到 [0,1][0, 1] 区间,防止极端值溢出。

一个节点最终取 userassistant 两条消息里较大的那个 σ\sigma

如果一句话很日常,贴近你平时说话的语义重心,salience 就低。 如果一句话明显偏离日常,比如突然说手术、医院、引流条,它就会有更高 salience。这其实就是心理学里的新异性效应(Novelty Effect / 冯·雷斯托夫效应):人们总是更容易记住那些和周围环境截然不同、脱颖而出的东西。

基于这个 salience,节点的长期强度在诞生那一刻就有了一个中性但有区分度的起点

strength0=3.0×(0.70+0.30σ)\texttt{strength}_0 = 3.0 \times (0.70 + 0.30\sigma)

逐个参数:

  • 3.03.0长期强度的上限设计值。所有节点 strength 永远不会超过 3.0(见后面的 bounded_add 机制),所以 σ=1.0\sigma=1.0 时节点从满格 3.0 起步。
  • 0.70+0.30σ0.70 + 0.30\sigma:基线 0.7 保证即使是完全不新颖的日常寒暄(σ=0\sigma=0)也有 2.1 的起步强度;新颖的事(σ=1.0\sigma=1.0)在基线之上再奖励 0.3。这个 0.7/0.3 分割是设计值,意思是"新颖度最多能贡献 30% 的起步优势"。
  • σ\sigma:来自上面算出的 salience。

所以新颖的事,起步就记得更牢——σ=1.0\sigma=1.0 时 strength 从 3.0 起步,σ=0\sigma=0 时从 2.1 起步。但注意,这只是起点,不是最终判决。一条记忆未来到底重不重要,还要看它能不能在后续的召回里反复被真正需要。resource 则一律从满格 1.0 开始。

但这里要说清楚: salience 不是重要性。

它只是初生时的一点光。

Akasha 并没有在写入时宣布:

这条记忆重要。

它只是说:

这句话看起来不像日常噪音,先给它一点保护,不要让它刚出生就被夜色淹没。

于是 node 初始化时会有三个状态:

状态含义初始化
salience这句话相对过往背景有多新颖由它和全局重心的距离决定
strength长期强度,未来会衰减3.0 × (0.70 + 0.30σ)
resource短期资源,防止刷屏初始满格 1.0

这就是 Akasha 的克制:

写入时不授勋。 只给一颗星一个初生亮度。 它以后会不会成为星座,要看时间怎么照它。


五、边:记忆不是相似,而是共同被想起

向量库最大的盲区是: 它只能看见相似。 看不见关系。

但人的记忆里,最重要的东西往往不是“相似”,而是“相关”。

“鱼石脂”和“引流条出血”语义上不一定特别像。 一个是药,一个是医疗处理后的现象。 但在你的真实生活里,它们属于同一个手指 episode。 它们被同一段疼痛、同一段就医经历、同一段恢复过程连在一起。

“亡灵契约师”和“limboo 玩杀戮尖塔”也未必在向量空间里很近。 但如果你们反复一起聊过,它们就应该互相唤醒。

这就是 Akasha 的第二层核心:

边记录的不是相似,而是共同被想起。

一条边 A → T 的意思不是:

A 和 T 长得像。

而是:

过去某一次,当 T 出现时,A 也曾一起浮上来。

这就是稠密相似度给不出的那一维。


六、边怎么长出来:Hebbian / STDP

Akasha 的边不是写入时硬连的。 它们是在使用中长出来的。

一次 query 进来,系统先召回一批旧记忆。 但不是所有被看到的东西都有资格改变未来。

Akasha 只取 score 最高的 8 条作为 activation set。

为什么是 8?

因为这暗合了认知心理学里的工作记忆容量(Working Memory Capacity)——也就是著名的“7±2 法则”。人的大脑在同一时刻能同时处理和维持在意识前台的信息组块,大概也就是这个数。

更重要的是,它是一道门槛: 只有真正进入当下意识前台的记忆,才有资格参与学习。 第 9 名以后,即使被检索到了,也只是背景,不会被加固。

回答之后,Akasha 会写三类边。

1. 旧记忆 → 当前轮:因果边

如果旧记忆 A 在这次回答中被激活,而当前轮是 T,系统会写:

ATA \to T

含义是:

A 参与塑造了 T。 A 是这轮对话的前因之一。

增量是 1.0×sA1.0 \times s_A,逐个参数:

  • 1.01.0因果边增益系数,设计值。代表”先出现的记忆更可能是后出现内容的前因”。
  • sAs_A旧记忆 A 这次召回的最终 score。来自后面第十四章的 score 公式——也就是说,判断”A 和 T 关联有多强”的那个数,正是召回时用来排序的同一个数。读和写共用同一份信号。

2. 当前轮 → 旧记忆:回指边

系统也会写:

TAT \to A

但这条边更弱,增量是 0.35×sA0.35 \times s_A

  • 0.350.35反因果边增益系数,设计值。
  • sAs_A:同上,A 这次召回的最终 score。

因为当前轮确实可以回指旧记忆,但后发生的事不能以同等强度”预测”先发生的事。

这个 1.0 vs 0.35 的不对称,不是随便拍的数字。它借鉴了神经科学里的 STDP(脉冲时序依赖可塑性):简单说,就是神经元激发的先后顺序,决定了连接的方向。前因导致后果,连接强;后果回指前因,连接弱。它也暗合认知心理学里的前向不对称效应(Temporal Contiguity Effect):当你想起一件事时,你更容易顺着时间往下想,而不是往前倒推。Akasha 的 0.35 恰好落在这个区间的经验值里——保留回指能力,但把时间前向定为主干。

这很重要。

如果边是完全对称的,系统就会分不清:

拉肚子 → 吃药

吃药 → 拉肚子

但 episode 之所以像 episode,正是因为它有顺序。 人的记忆不是一团无向共现。 它有时间箭头。

所以 Akasha 借用了 STDP 的精神: 先出现、先被想起的东西,更像后续内容的前因。 后出现的东西可以回指过去,但不能平等地改写过去。

3. 旧记忆之间:共激活边

如果 A 和 B 在同一次召回里一起被点亮,系统还会写:

ABA \leftrightarrow B

增量是:

sAsB\sqrt{s_A s_B}

逐个参数:

  • sAsB\sqrt{s_A s_B}sAs_AsBs_B几何均值。比起简单的乘积或相加,几何均值的好处是”两个都强才真的强”——一个高分一个低分的组合会被压低,避免偶然高分的记忆乱连。
  • sA,sBs_A, s_B:A 和 B 各自的召回 score。

也就是说,两条记忆越强地共同在场,它们之间的星座线就越粗。这里 sAs_AsBs_B 分别是 A 和 B 这次召回的最终 score——得分越高的记忆,与其他高分记忆之间长出的边越粗

这就是神经科学里著名的 Hebbian 理论(赫布定律)——简单来说就是“一起放电的神经元,会连在一起(Cells that fire together, wire together)”:

一起亮过的星,更容易在未来一起亮。

但 Akasha 又不是简单的”一起出现就永远连上”。 因为所有边都会随时间变暗。


七、边会变暗:星座线不是刻在石头上的

Akasha 里的边不是永久权重。 每条边都有:

当前权重 weight 上次更新时间 last_used_ts

每次读到或强化它时,先结算这段时间的衰减:

w有效=we(tnowtlast)/14w_{\text{有效}}=w\cdot e^{-(t_{\text{now}}-t_{\text{last}})/14\text{天}}

逐个参数:

  • ww:数据库里存的原始边权(上一次更新后的值)。
  • tnowt_{\text{now}}当前时间戳
  • tlastt_{\text{last}}:这条边上次被更新的时间戳
  • 1414\text{天}边的时间衰减常数,设计值。意思是如果一条边整整 14 天没被碰,有效权会掉到原值的 e137%e^{-1}\approx 37\%;28 天掉到约 14%。
  • eΔt/τe^{-\Delta t / \tau}:标准的指数衰减公式(完美复现了著名的艾宾浩斯遗忘曲线),Δt=tnowtlast\Delta t = t_{\text{now}} - t_{\text{last}}τ=14\tau=14 天。

然后再把这次共同激活带来的增量加上去。 增长是有上限的,越接近上限,涨得越慢——这叫有界增长(模拟了神经科学里的 LTP,长时程增强的饱和效应):

bounded_add(v,δ,c)=v+δ(1vc)\text{bounded\_add}(v,\delta,c)=v+\delta\left(1-\frac{v}{c}\right)

逐个参数:

  • vv:当前值(对边来说就是衰减后的 w有效w_{\text{有效}})。
  • δ\delta:这次要加的增量。
  • cc:上限,vv 永远不会超过 cc。越接近 cc,实际增量越小——当 v=cv=c 时,增量为 0;当 v=0v=0 时,增量为 δ\delta

落库时完整的写法是:

wbounded_add(we(tnowtlast)/14,  0.12Δ,  2.0)w \leftarrow \text{bounded\_add}\big(w\cdot e^{-(t_{\text{now}}-t_{\text{last}})/14\text{天}},\; 0.12\cdot\Delta,\; 2.0\big)

逐个参数:

  • Δ\Delta:上面三种边各自的增量(因果 1.0sA1.0·s_A、反因果 0.35sA0.35·s_A、共激活 sAsB\sqrt{s_A s_B})。
  • 0.120.12边的学习率,设计值。把每次的增量打个折,防止一次共激活就让边权爆炸——边要靠反复共激活才能慢慢长粗。
  • 2.02.0边权上限,设计值。边权永远不会超过 2.0。

这非常关键。

如果没有衰减,图会越来越脏。 一次偶然的错误联想,会永远留在图里。

如果没有上限,热门节点会爆炸。 所有话题都会被少数 hub 吞掉。

如果没有使用中的强化,图又不会成长。 它只是一堆静态索引。

Akasha 同时有三件事:

会长。 会暗。 长到一定程度会慢下来。

所以它不是数据库。 它更像一个寻找平衡态的生命系统。

好的关系会因为反复被需要而变亮。 坏的巧合会因为无人再次召唤而退潮。 不是清洁工在后台删垃圾。 是时间本身在清理噪音。


八、时间动力学:忘记不是删除,是退到远处

Akasha 有三条时间曲线。

变量时间常数管什么初始值 / 恢复方式直觉
strength7 天一条记忆本身的长期光度编码即峰值 3.0 × (0.7 + 0.3σ),被召回时 bounded_add 抬升不复习会淡
edge14 天两条记忆之间的星座线从零开始,共激活时 bounded_add 加固,封顶 2.0不共现会断
resource30 分钟刚用过的记忆是否暂时退后满格 1.0,被取用扣 0.35 × score,指数恢复防止刷屏

节点侧的 strength 每次被召回时,也遵循同样的有界增长逻辑:

strengthbounded_add(strengtheΔt/7,  0.18s,  3.0)\text{strength} \leftarrow \text{bounded\_add}\big(\text{strength} \cdot e^{-\Delta t/7\text{天}},\; 0.18 \cdot s,\; 3.0\big)

逐个参数:

  • strength\text{strength}:数据库里存的节点当前 strength 值。
  • Δt\Delta t距离上次被召回的时间tnowlast_recalled_tst_{\text{now}} - \text{last\_recalled\_ts}
  • 77\text{天}strength 的时间衰减常数,设计值。比边的 14 天快一倍——"记忆本身"比"记忆之间的关联"忘得更快。
  • 0.180.18节点的学习率,设计值。比边的 0.12 大一点——节点自身的强化比边的强化稍快。
  • ss:这条记忆这次召回的最终 score
  • 3.03.0strength 上限,设计值,与初始化的上限一致。

这里的 ss 还是那条记忆这次召回的 score——得分越高,被加固得越多

这三条不能合成一条。

因为”忘了””累了””不相关了”是三件完全不同的事。

一条记忆可以记得很牢,但刚刚被用过,所以暂时不要再霸屏。(这在心理学里叫返回抑制 Inhibition of Return,大脑会刻意压制刚刚关注过的信息,防止我们在同一个思路上陷入死循环。) 这叫:

strength 高,resource 低。

一条记忆本身淡了,但它还连在一个很强的 episode 簇里,所以能被边救回来。 这叫:

strength 低,edge 高。

一条记忆没有多少边,但文字上正好高度相似,所以 direct 仍然能把它捞回来。 这叫:

edge 低,dense 高。

普通系统常常把这些都压成一个”重要性分数”。 Akasha 没有这样做。

Akasha 让它们分开活着。

这使得遗忘变得非常精确:

遗忘不是把记忆从世界上抹掉。 遗忘是降低它参与未来计算的权重。

一条 strength 掉到很低的记忆,仍然在库里。 只要你某天说了非常相似的话,dense 还能把它从角落里找回来。 如果它再次被真正需要,它就会重新发光。

这很接近人的记忆。

很多事我们不是彻底忘了。 只是它不再主动走到眼前。

直到某个词、某个人、某种痛感、某个夜晚,把它重新叫醒。


九、为什么”使用次数”不是重要性

现有系统最容易犯的错误,就是把 recall_count 当成重要性。

但在 Akasha 里,事情恰好反过来。线上 3337 条节点的真实统计显示了一个非常漂亮的结果:

corr(strength,recall_count)=0.23\text{corr}(\text{strength}, \text{recall\_count}) = -0.23

corr(strength,fan)=0.36\text{corr}(\text{strength}, \text{fan}) = -0.36

逐个参数(这是 Pearson 积矩相关系数,范围 [-1, 1],0 表示不相关,负号表示反相关):

  • strength\text{strength}:每个节点的当前 strength 值。
  • recall_count\text{recall\_count}:每个节点历史上被召回的总次数。
  • fan\text{fan}:每个节点的总边数。
  • 0.23-0.230.36-0.36中等程度的负相关,意味着——越常被扫到、越是 hub 的节点,strength 反而越低。

也就是说,越常被扫到、越像 hub 的节点,strength 反而越低

这不是 bug。 这是设计目标。

因为 strength 的增长不是看”被想起多少次”,而是看”每次被想起时,是不是真的被需要”——也就是 score。一个 hub 节点虽然频繁被扫到,但每次都是因为它 fan 大、边广,不是 query 真和它相关——content_base 低、每次加得少;加上它 salience 低(不偏离重心),起点就低。低起点 + 低增量 × 频繁 = 还是低。

比如:

节点recallfanstrength解释
「你好啊」1011740.10经常被扫到,但几乎不真正服务当前语境
「肿得厉害,去医院切开引流,塞了根引流条」4282.31很少出现,但每次出现都和当前问题强相关

这说明 Akasha 没有被”热闹”骗走。

“你好啊”像广场上的噪音。 它出现很多次,但没有深关系。

“引流条”像一个伤口旁边留下的路标。 它出现次数不多,但一旦出现,往往真的重要。

Akasha 学到的是:

被看见,不等于被需要。 被需要,才会变亮。

这就是个人记忆里最关键的分辨力。


十、召回不是查找,是一次意识的涨潮

现在我们进入 Akasha 最核心的地方:一次 query 进来,它到底怎么想起过去?

整条流程可以分成五步:

选种子 图扩散 合并候选 noisy-OR 结算 注入与写回

听起来复杂,但可以继续用星图理解。

用户当下的话,是一束光。 它先照到几颗最明显的星。 然后光沿着过去长出来的星座线扩散。 有些星本来离得很远,但因为曾经和这些星反复一起亮过,也被涟漪带亮。 最后系统把所有亮度结算成一个 score。 score 决定两件事:

这条记忆要不要交给 LLM; 回答之后,它要不要被写回图里、变得更容易在未来被想起。

这就是 Akasha 最漂亮的闭环:

读和写共用同一个 score。

判断“此刻什么相关”的那个数,也就是学习信号本身。


十一、Step 1:种子选择,先点亮哪几颗星

Akasha 有三路种子。

1. Dense seed:语义相似

query 向量和所有 node 算 cosine。 高于阈值的进入种子池。 如果都不够,就取 top-k 兜底。

这是最稳定的一路。 它保证系统不会飘太远。

你问“引流条”,它一定能先找到“引流条”。 你问“杀戮尖塔”,它一定能先找到“杀戮尖塔”。

这是 direct 的地板。

2. FTS seed:稀有词硬命中

如果 query 里有 limboo、鱼石脂、亡灵契约师这种词,FTS 会用字面索引把它抓回来。

这一路专门补 embedding 的盲区。

私人记忆里,名字非常重要。 朋友的名字、游戏里的职业名、药名、地点名,这些东西可能在通用语义空间里并不显眼,但在人生里,它们是门。

FTS 就是在门牌号还清楚的时候,直接按门牌找。

3. BlackHole seed:高 salience 直通

有些记忆很新颖,很偏离日常。 哪怕它和 query 的相似度没有高到普通 dense seed 的门槛,也不该轻易被埋掉。

所以 Akasha 给高 salience 记忆留了绿色通道。

这很像夜里一颗异常亮的星。 它未必离你当前看的方向最近,但它太亮了,值得被看见。


十二、Step 2:Direct 和 Ripple,左脑与两种右脑

Akasha 有三层意识。

Direct:左脑,精确回忆

Direct 很简单:

query 和记忆算相似度。

它不学习。 不走边。 不讲故事。 它就是最近邻。

这一路很重要,因为它提供了准确性地板。 没有 direct,系统会变成纯联想,容易发散。 有了 direct,Akasha 永远有一条回到事实的路。

Ripple 分两层右脑

Ripple 才是 Akasha 和普通向量库真正不同的地方。但右脑不是单一通道,而是两套独立机制。

近场右脑:RWR(带重启的随机游走)

它不只看"像不像"。 它把当前线索丢进 30 分钟微图,让能量在"同一段短时上下文"里竞争分配。(RWR 是推荐系统里经典的图扩散算法,它像水面上的波纹一样,把能量沿着边一层层传出去,但也随时可能被“弹回”原点,防止能量跑得太远迷失方向。)

一个节点本身好不好被点亮由「易激活度」state 决定:

state=exp ⁣(1.4σ+1.0long)resource/1+fan\text{state} = \exp\!\big(1.4\,\sigma + 1.0\cdot\text{long}\big)\cdot \text{resource} \,\big/\, \sqrt{1+\text{fan}}

逐个参数:

  • σ\sigma:节点的 salience(新颖度),来自第四章。
  • long\text{long}归一化的 strength,把 strength 从 [0,3.0][0, 3.0] 线性映射到 [0,1][0, 1]
  • 1.41.41.01.0增益系数,设计值。1.4 > 1.0 意味着新颖度比长期强度对易激活度的影响更大。
  • exp()\exp(\cdot):指数函数,让高值的节点优势被放大——新颖又记得牢的节点,比中等的容易点亮得多。
  • resource\text{resource}:节点的短期资源,[0,1][0, 1],来自第四章初始化,每次被召回扣减、30 分钟恢复。
  • fan\text{fan}:节点的总边数(出边+入边的度数)。
  • ÷1+fan\div\sqrt{1+\text{fan}}第一道反 hub 防线——连得越杂的节点,越不容易被点亮。

于是它能找回那些:

字面不像, 向量也不够近, 但在人生里属于同一段关系的记忆。

这就是 “Ripple Activation & Recall”。

它像水面上的涟漪。 你说出一个词,第一圈波纹命中相似的记忆; 第二圈波纹沿着旧关系扩散,把那些沉在语义空间远处、却在你的人生里相邻的东西带回来。

所以当你说:

和 limboo 玩杀戮尖塔。

dense 会想起杀戮尖塔。 ripple 会想起 limboo 作为战士、你作为亡灵契约师、舍友联机、都玩机器人。

dense 找回的是文本相似。 RWR 找回的是同一段短时上下文里的生活结构。

远场右脑:graph_expand

RWR 只照亮 30 分钟窗口内的星。但人生里有些关系不受时间束缚——47 天前的一条记忆,只要边够强,照样该被想起。

graph_expand 就是干这个的。它拿 dense 种子在全图往外走一跳,不管时间远近。

它真正迷人的地方,不是能沿着一条边走到远处,而是能看见多条线索在远处汇聚。一条远处记忆如果只被一个种子弱弱地牵到,只是偶然;但如果当前 query 点亮的几颗星,都把光投向同一个远处节点,那颗节点就会突然亮起来。

这就是 Akasha 的情景补全:不是"某句话和 query 很像",而是"许多被当前语境点亮的旧事,都在指向同一个背景"。

dense 找的是最近的星。RWR 找的是同一片夜空里的竞争。graph_expand 找的是被多条星座线共同指向的远星。

所以当你说"和 limboo 玩杀戮尖塔":

  • dense 还你"杀戮尖塔"的各种说法;
  • RWR 还你"亡灵契约师 / 舍友联机 / 都玩机器人"——一整段关系;
  • graph_expand 还能从 47 天外把「镜之边缘」拽回来,只因它过去反复和这段关系共同出现。

Akasha 不是"两路",而是三层意识:左脑精确相似兜底,近场右脑在同窗口内竞争,远场右脑把全图里被多条星座线共同指向的远星拉回来。

后面你会在 querylog 里看到 source=Graph, state=0.0 的条目——state 不是"没点亮",而是 graph_expand 不走 RWR 的 state_array,它靠另一套物理发光。


十三、为什么需要 graph_expand,而不是让 RWR 跑全图

Akasha 的图扩散里有一个很重要的分工:

graph_expand 负责全图一跳发现。 RWR 负责局部窗口里的微调。

这不是随便拆的。这里有三个深层的技术原因,每一个都决定了系统能不能优雅地长大。

第一,计算成本。 RWR 要建 N×N 转移矩阵、做矩阵乘、迭代。在同一个 30 分钟上下文里,微图只有几十个点,瞬时完成;但如果把 RWR 直接放到全图,几千个点的 N² 计算量会放大 2500 倍,每次 query 都跑就不再优雅。而 graph_expand 是一跳邻居遍历,复杂度只和种子的出边数有关,轻得多。

第二,数学逻辑根本不同。 RWR 是能量再分配——总能量固定、节点之间是零和竞争,适合在同一个短时语境中比较”谁更相关”。但 graph_expand 是独立打分——每个候选互不影响,适合在全图里寻找”远处但真实相关的桥”。graph_expand 给每个一跳邻居独立打分:

score一跳=6.0×边信号×(0.25+cos)×(1+0.15long)×resource\text{score}_{\text{一跳}} = 6.0 \times \text{边信号} \times (0.25 + \cos) \times (1 + 0.15 \cdot \text{long}) \times \text{resource}

逐个参数:

  • 6.06.0量级放大系数,设计值,把一跳的分数拉到和 direct 可比的范围。
  • 边信号\text{边信号}:电导归一后的边权,w有效种子出度邻居入度\displaystyle\frac{w_{\text{有效}}}{\sqrt{\text{种子出度} \cdot \text{邻居入度}}},范围 [0,1][0, 1]。但注意——这个 signal 不是来自单条边,而是所有种子投向同一颗远星的光线之和,再乘 (1+log(paths))(1 + \log(\text{paths}))。多颗种子共同指向的节点,会因为这个对数因子额外变亮。
  • 0.25+cos0.25 + \cos:即使相似度为 0,也给 0.25 的基线——保证"完全不像但强关联"的记忆也能拿到基础分。cos\cos 是 query 和邻居节点的余弦相似度。
  • 1+0.15long1 + 0.15 \cdot \text{long}:长期强度增益,最牢的记忆多 15% 加成,影响温和。
  • resource\text{resource}:邻居节点的短期资源,刚用过的打折。

graph_expand 的精髓不是"一条边强",而是"多颗种子共同指向同一颗远星"。 代码里每个候选的 signal 是累加值——来自多个种子的边信号会叠加;同时 paths 计数每多一条路径就 +1,最终乘上 (1+log(paths))(1 + \log(\text{paths}))。这意味着:一条远处记忆如果只被一个种子弱弱地牵到,只是偶然;但如果当前 query 点亮的几颗星都把光投向它,那颗远星就会突然亮起来。这就是"星光汇聚"。

这是两种完全不同的回忆:RWR 回答”在当下这段语境里,谁最突出”;graph_expand 回答”在我整个人生里,还有什么和此刻相连”。

第三,也是最优雅的一点:局部记忆和长期联想的时间尺度不同。 RWR 局限在 30 分钟窗口里,是因为同一段对话里的边才有”此刻共在”的意义;而 graph_expand 完全不看节点时刻——47 天前的记忆,只要边够强照样能被拽回来。这正好对应了人类记忆的两层:工作记忆里的信息互相竞争,而长期记忆里的关联不受时间束缚。

RWR 像一个小房间里的注意力分配。 在同一个 30 分钟上下文里,节点之间确实可以竞争: 谁更相关,谁就拿更多能量。

但如果把 RWR 直接放到全图,问题会变得很糟。

第一,全图迭代会更贵。 局部微图几十个点,计算很轻。 全图几千个点,每次 query 都跑,就不再优雅。

第二,hub 会吸光。 “你好””今天””感觉””可以”这类节点,和太多东西有弱边。 在零和扩散里,它们会像黑洞一样吸走能量。

第三,也是最关键的: 局部记忆和长期联想的数学逻辑不同。

RWR 是能量再分配。 适合在同一个短时语境中竞争。

graph_expand 是独立打分。 适合在全图里寻找远处但真实相关的桥。

比如”鱼石脂”离”引流条出血”可能隔了好几小时,甚至不在当前 30 分钟窗口里。 RWR 看不到它。 但 graph_expand 可以沿着过去 37 轮手指就医 episode 里长出来的边,把它一跳拽回来。

这就是为什么 Akasha 不是简单地”把窗口调大”。 它是在区分两种回忆:

局部意识里的竞争。 长期星图里的联想。


十四、Step 3:noisy-OR,把两路证据合成此刻亮度

Direct 和 ripple 产生的是两种证据。

direct 说:

这条记忆和当前 query 文本相似。

ripple 说:

这条记忆虽然不一定相似,但它被关系图强烈带亮。

这两种证据不应该互相排斥。 任何一路强,都应该能让记忆浮上来。 两路都强,则更有把握。

所以 Akasha 用了类似 Noisy-OR 模型的思路来融合(这本来是贝叶斯网络里用来处理多个独立促成因素的模型:只要有一个原因成立,结果就容易成立):

content_base=strong+weak(1strong)\text{content\_base} = \text{strong} + \text{weak} \cdot (1 - \text{strong})

其中:

{ripple=current×3×state(扩散能量——动态、会学习)direct=0.5×cos(相似度——静态、不变化)\begin{cases} \text{ripple} = \text{current} \times 3 \times \text{state} & (\text{扩散能量——动态、会学习}) \\ \text{direct} = 0.5 \times \cos & (\text{相似度——静态、不变化}) \end{cases}

strong=max(ripple,direct)\text{strong} = \max(\text{ripple}, \text{direct})weak=min(ripple,direct)\text{weak} = \min(\text{ripple}, \text{direct})

但这里有一个隐藏的免疫设计:direct 权重不是恒定的 0.5,而是看这条候选是不是种子本身

wd={0.50若该节点是种子(被 query 直接照亮)0.18若该节点是被扩散扫到的邻居w_d = \begin{cases} 0.50 & \text{若该节点是种子(被 query 直接照亮)} \\ 0.18 & \text{若该节点是被扩散扫到的邻居} \end{cases}

Dense 对种子是地基,对联想只是刹车。 真正被 query 直接照亮的节点,拿完整的 direct 权重;被右脑带出来的邻居,只能拿一点点相似度背书。它若要进入意识前台,必须证明自己不是"有点像",而是"真的在这段生活里相连"——靠边、靠 long、靠多路径汇聚。

逐个参数:

  • current\text{current}扩散激活能量。graph_expand 或 RWR 过程中节点获得的能量值,范围 [0,1][0, 1]。graph_expand 来自边信号 × 种子能量;RWR 来自带重启随机游走的稳态分布。
  • 33ripple 放大系数,设计值。把扩散能量放大到和 direct 可比的量级。
  • state\text{state}易激活度,来自上一章的公式。综合了新颖度、长期强度、短期资源、反 hub 惩罚。
  • cos\cosquery 向量与节点向量的余弦相似度,范围 [1,1][-1, 1],个人语料中通常在 [0.3,0.95][0.3, 0.95] 之间。
  • 0.50.5 / 0.180.18direct 系数。种子拿 0.5,非种子邻居只拿 0.18。这是防死亡螺旋的隐藏锁——Graph 邻居想进 top-8,不能只靠"有点像"。

任何一路强都能把 content_base 拉高。但这不是概率意义上严格趋近 1.0 的 noisy-OR,而是一个带饱和保护的证据融合器:当 strong < 1 时,弱证据补上剩余空间,像 noisy-OR 一样互补;当 strong ≥ 1 时,次要证据不再加成,但强证据本身保留为能量,让真正强关联的节点拿到大于 1 的 score。"亮度"不是"概率",所以真实库里会出现 11.18、8.90 这样的数——那不是 bug,是能量。

直觉很简单:

如果 strong 已经很强,weak 就只补一点。 如果 strong 还没饱和,weak 可以继续把它推高。 如果两路都有证据,这条记忆就更亮。

但 content_base 只是”内容证据”。 最终 score 还要乘上状态增益(这叫 Gain Modulation 增益调节,大脑里的神经元也经常这样,用一个信号去乘性地放大另一个信号):

score=content_base(1+0.8σ)(1+0.6long)(1+0.5edge)penalties\text{score} = \text{content\_base} \cdot (1+0.8\sigma) \cdot (1+0.6\,\text{long}) \cdot (1+0.5\,\text{edge}) \cdot \text{penalties}

逐个参数(增益项都是 1+x1+x 形式,信号为 0 时增益为 1,不影响基线):

  • (1+0.8σ)(1+0.8\sigma)新颖增益σ\sigma 是节点 salience,范围 [0,1][0,1]。新颖度最高的节点获得 1.8 倍增益。
  • (1+0.6long)(1+0.6\,\text{long})长期强度增益long\text{long} 是归一化的 strength,long=strength/3.0\text{long} = \text{strength} / 3.0,范围 [0,1][0,1]。最牢的记忆获得 1.6 倍增益。
  • (1+0.5edge)(1+0.5\,\text{edge})边强增益edge\text{edge} 是节点到任意一个种子的最大有效边权,再除以 2.0 归一化到 [0,1][0,1]。边最强的获得 1.5 倍增益。

penalties(惩罚项,都是 ≤1 的乘数,越差越低):

  • ×resource\times\,\text{resource}短期资源惩罚。刚被用过的记忆 resource 低,排名被压低。
  • ×hop\times\,\text{hop}路径长度惩罚。设计值:直连种子 = 1.0,一跳邻居 = 0.86,两跳 = 0.62,越远越打折。每跳衰减系数为 e0.15e^{-0.15}
  • ×user\times\,\text{user}角色惩罚。设计值:assistant-only 独白节点 × 0.12(几乎不算),用户说的话 × 1.0。
  • ÷(1+fan)0.1\div\,(1+\text{fan})^{0.1}第五道反 hub 防线。fan 越大惩罚越多,fan=100 时约 × 0.63。

最后过阈值 0.22(设计值)才算”被激活”。

这里每一项都有清楚的含义:

作用
content_base当前内容相关性
1 + 0.8σ新颖记忆更容易被看见
1 + 0.6 long长期强度高的记忆更亮
1 + 0.5 edge强边连接的记忆更容易浮现
resource刚用过的记忆暂时压低
hop越远的传播越打折
user_penaltyassistant-only 内容降低权重
fan penaltyhub 节点被压制

这一步非常像意识的结算。

不是单一分数决定一切。 而是许多微弱证据在此刻汇合。

这条记忆相似吗? 它新颖吗? 它长期活着吗? 它和当前种子之间的边强吗? 它是不是刚刚出现过? 它是不是 hub? 它是用户说的,还是 assistant 自己说的?

最后这些东西共同决定:

它此刻该不该发光。


十五、五道反 hub 防线:不让噪音霸占星空

长期记忆系统最怕 hub(在图论里,就是那些连接数极高的超级节点)。

hub 是什么?

就是那些和谁都能沾一点边,但和谁都不真正相关的节点。

比如:

你好啊。 好的。 今天。 感觉。 可以。

它们出现次数多。 连接也多。 如果系统只看频率或边数量,它们会吞掉一切。

所以 Akasha 有五道反 hub 防线,每一道都在不同的阶段给 hub 打折,一层一层纵深压制:

#位置公式在哪一步逐个参数解释
1state 阶段state÷1+fan\text{state} \div \sqrt{1+\text{fan}}节点易激活度fan\text{fan} = 节点总边数(度数)。连得越杂的节点,本身就不容易点亮
2seed 阶段e0÷1+fane_0 \div \sqrt{1+\text{fan}}种子初始能量e0e_0 = 种子的初始能量。hub 即使当种子,出发能量也先除以 √(1+fan) 打折
3RWR 转移每列只留最强 12 条边,弱边丢弃微图能量流动hub 的弱边根本传不出能量,只保留最强的铁关系。
4graph_expandw出度入度\displaystyle\frac{w}{\sqrt{\text{出度} \cdot \text{入度}}}全图一跳电导归一ww = 有效边权;出度/入度 = 两端节点的边权总和。"谁都连"的 hub 分母大、被除得很小,只有最专一的邻居冒头
5final scorescore÷(1+fan)0.1\text{score} \div (1+\text{fan})^{0.1}最终打分最后再压一次,收尾兜底。指数 0.1 比较温和,只惩罚 fan 极大的节点。

这非常重要。

因为 hub 不一定会被时间自然清掉。 有些废话就是会反复出现,边也会被反复刷新。 所以 Akasha 不只靠衰减,还靠结构性压制。

衰减清掉的是:

偶然出现、之后不再复现的噪音。

反 hub 清掉的是:

经常出现、但没有内容贡献的噪音。

这两者合起来,才是闭环系统的免疫系统。


十六、Step 4:注入,左脑和右脑各走各的路

Akasha 最后不会把所有候选混成一锅粥交给 LLM。

它会分成三类。

1. dense_items:左脑,精确回忆

这是纯相似度 top-k。 不走 RAR。 不依赖图。 它永远兜底。

如果你问一个明确事实,dense 一定能把最像的旧消息找回来。

这保证 Akasha 不会因为联想太美而忘了准确性。

2. ripple_items:右脑,潜意识浮现

这是 RAR 全管线召回出来的东西。 阈值会放宽一点。

为什么要放宽?

因为右脑联想本来就不是精确搜索。 它的价值在于多给一些“可能有关”的背景音,让 LLM 在最后整合。

这里的 LLM 不是记忆的真相源。 它只是最后一公里的前额叶:

看看这些上下文,哪些真的该被说出口。

Akasha 不让 LLM 改写过去。 但允许 LLM 在回答时整合上下文。

这是两种完全不同的信任。

3. activation_items:真正写回未来的 top-8

这是最关键的一组。

只有 activation_items 会参与学习。 只有它们会加 strength。 只有它们会消耗 resource。 只有它们会和当前轮建立 STDP 边。

所以 Akasha 的学习非常克制:

可以多给 LLM 一些右脑联想, 但只有左右脑共同结算后的 top-8,才有资格改变未来。

为什么必须让左右脑都参与激活,而不是只有右脑?

这是整套系统防止死亡螺旋的核心免疫机制,必须讲透。

先回答:dense 参与 score 计算吗?会。 dense 的相似度信号不是"仅供注入"——它直接进入了最终 score 的计算。score 的两路证据 noisy-OR 融合里,一路是 ripple(右脑扩散),另一路就是 direct(左脑 dense):

direct=0.5×cos\text{direct} = 0.5 \times \cos

所以每一个候选的 score 里,都天然带着 dense 相似度的贡献。

再回答:dense 本身会 ripple 为 0 吗?不会。 那些本身就是种子的 dense 命中节点,是扩散的能量起点,一出生就有初始能量 e0e_0,经过 RWR 扩散后 current\text{current} 肯定不为 0,所以 ripple=current×3×state\text{ripple} = \text{current} \times 3 \times \text{state} 永远不为 0。它们同时有 direct 和 ripple 两路信号。少数不在种子里、也没被扩散扫到的 dense 兜底节点,ripple 可以为 0,但 noisy-OR 保证只要 direct 够高依然能浮上来——这既是地板,也是冷启动时第一条边的来源。

关键的设计决策:为什么 activation_items 必须是左右脑融合的 top-8?

如果只让右脑(ripple)的结果参与写回强化,会发生死亡螺旋

  1. Day 1:聊"拉肚子→快递放消防栓→吃诺氟沙星",物理时间连续,STDP 忠实地在「拉肚子」和「消防栓」之间连了一条弱边。
  2. Day 7:问"我肚子痛",ripple 顺着那条弱边勉强把「消防栓」扩散了出来。
  3. 如果只有右脑的结果参与写回:「消防栓」进了 top-8,边被加固 → 下次更容易被扩散出来。
  4. 如此反复:边越来越粗,一说到肚子痛就满屏都是外卖小哥,系统彻底精神分裂。

让 dense 参与激活,破解了这个诅咒:

  1. Day 7:问"我肚子痛",ripple 确实把「消防栓」扩散了出来,但 dense 相似度把「火锅」「拉肚子」「诺氟沙星」这些真正相关的记忆,以绝对的 cos 高分锚定在了候选池头部
  2. 「消防栓」和"肚子痛"的 cos 只有 0.2 左右,direct 信号极低 → content_base 上不去 → final score 排第 9 名开外。
  3. 进不了 top-8 → 没资格被写回 → 边不会被加固
  4. 14 天衰减后,那条弱边自己就枯掉了。

用真实的鱼石脂例子看得更清楚:

记忆cos (direct)ripple (扩散)content_basescore进不进 activation?
鱼石脂(一跳邻居)0.5221.252~0.863.09✅ 进
不是换新的引流条吗(dense #1,种子)0.787有初始能量,>0~0.39 + ripple×(1-0.39)0.79✅ 进
打麻药为什么疼(种子/邻居)~0.65~0.62~1.x✅ 进
消防栓(噪音)0.2~0.3~0.44<0.22❌ 不进

好的联想(鱼石脂)虽然 dense 不高,但 ripple 够强,依然能进 top-8 被加固;坏的联想(消防栓)因为没有 dense 锚点,挤不进去,被自然饿死。而 dense 种子(引流条)本身作为事实锚点,即使 ripple 不突出,也会因 direct 够高而进入强化池,保证事实被不断巩固。

右脑负责"多想一点",左脑负责"别想太偏"。 注入 LLM 时可以让右脑大胆联想(多给点背景音让 LLM 筛),但写回时必须让左脑把事实锚在头部——纯联想的噪音挤不进 top-8,就不会被加固,不会污染图结构。dense 参与激活,本质是用"不变的事实相似性"给"会学习的联想"做锚定,让系统可以大胆联想又不会疯掉。

这点非常漂亮。

因为如果只强化 ripple 找到的东西,系统容易进入噪音自激: 一个无关节点偶然被扩散扫到,写回; 下次更容易被扫到,再写回; 最后噪音变成 hub。

但 Akasha 用 dense 作为免疫系统。 事实相似性永远在候选池里当锚。 纯右脑噪音如果没有内容支撑,很难挤进 top-8。 挤不进去,就不会被加固。 不会被加固,边就会在 14 天衰减里变暗。

这就是为什么 Akasha 可以大胆联想,又不至于被联想毁掉。


十七、真实例子一:limboo,不是一个词,而是一段关系

现在回到开头的例子。

你说:

昨天在和 limboo 玩杀戮尖塔。

普通 dense 会找回语义相似的东西。 这当然有用,但它只能看到”杀戮尖塔”这个主题。

Akasha 会先用 dense 找到杀戮尖塔相关记忆。 再用 FTS 抓住 limboo 这个稀有名字。 如果二者同时命中,种子能量还会 ×1.3(封顶 1.5)。

然后 ripple 开始沿图扩散。

它发现:

我是亡灵契约师,limboo 是战士。 和学校舍友联机玩。 我玩机器人,limboo 也玩机器人。 和舍友俩机宝过了 a10。

这些句子未必都和 query 高度相似。 有的 dense 排名可能很靠后。 甚至有些从语义上看,几乎不该出现在 top-10 里。

但在人生结构里,它们是相关的。

它们属于同一片游戏生活。 同一个朋友。 同一段联机关系。 同一种只有长期聊天才会形成的背景。

这就是 Akasha 的价值,用真实数字说话:

内容cos 相似度dense 全库排名最终 score召回来源
我是亡灵契约师 limboo是战士0.599第 22 名2.40Graph / 1hop
和学校舍友联机玩0.598第 24 名1.48Graph / 1hop
我玩机器人 limboo也玩机器人0.597第 26 名1.28Graph / 1hop
镜之边缘主角叫啥0.436第 1199 名1.27Graph / 1hop
和舍友俩机宝过了 a100.601第 21 名0.99Graph / 1hop

每一条的 cos 都远够不上 dense 种子门槛(0.675),排在全库 21~1199 名;但它们和好几条种子挂着 0.17~0.28 的共现边——这些边是过去几十次一起聊杀戮尖塔积累的。「镜之边缘」cos 仅 0.436、全库排 1199 名,纯相似度永远够不到——但边是活的,把它从一千名外拽到了第 4。

它不是找到更多”杀戮尖塔”。 它找回”你和 limboo 之间那段关于杀戮尖塔的世界”。

这就是从检索到记忆的跃迁。


十八、真实例子二:鱼石脂,语义不近,但人生很近

另一个更漂亮的例子是手指就医。

你问:

但是拔出来引流条的时候出了好多血。

dense 会找回”引流条””换药””麻药””出血”这些直接相似的记忆。

这很好。 但 Akasha 还会想起:

刚才白的是那种小点,鱼石脂是棕色的……

单看语义,”鱼石脂”和”引流条出血”并不是最像。 cos 可能只有 0.522。 在普通 dense top-10 里,它排不上号。

但在真实对话里,鱼石脂和引流条、麻药、绷带、换药,属于同一个手指 episode。 它们在 37 轮对话里反复共同出现。 边一阶一阶长粗。

所以到某一次你说”引流条拔出来出了好多血”时,Akasha 沿着那段 episode 的星座线,把鱼石脂拉了回来。

这是记忆系统最应该有的能力。 用真实数据看更清楚:

记忆cos 相似度ripple 扩散能量最终 score说明
鱼石脂是棕色的…0.5221.2523.09cos 不在 top-10,靠 graph_expand 一跳拽回
不是换新的引流条吗(dense #1)0.7870.79纯相似度第一名

鱼石脂的 score 是 dense #1 的 3.9 倍。而且它离种子几小时远,不在 30 分钟微图里,RWR 根本看不到它——全靠 graph_expand 无时间限制的一跳发现机制,沿着过去 37 轮手指就医里长出来的粗边,把它从语义距离之外拽了回来。

这就是记忆系统最应该有的能力。

不是把最像的文本摆出来。 而是把”你当时经历的那一整段事情”恢复出来。

人对 agent 的期待,本来就是这个:

你不要只记得我说了哪个词。 你要记得那几天我到底在经历什么。

Akasha 在这个例子里,做到了。


十九、真实库里的涌现:Akasha 补全的不是答案,而是情景

讲到这里,有必要退一步,看看真实库在说什么。不是理论,是 akasha.db.gz 里 3378 个节点、127696 条边、3352 条 query log 的实证。

先给一张读 querylog 的小字典。真实字段里有几个名字容易误导,尤其 state=0 这件事:

字段在 RWR 候选里在 Graph/1hop 候选里
directquery 与节点的 cos也是 cos
rippleRWR 当前扩散能量 currentgraph_expand 里更像 best edge / best weight
edgecross_mat 的最大边信号graph_expand 的聚合边信号(signal × paths)
stateRWR 的归一化易激活度 [0,1]固定 0.0,因为 Graph/1hop 不走 state_array
scorenoisy-OR + gain 后的分数graph_expand 独立公式后的分数

Graph/1hop 的 state=0 不是"没有被点亮",而是"它来自另一套右脑物理"——远场联想不走 RWR 的 state_array,它靠的是 seed 强度、边电导、候选 direct、long、resource,以及多路径汇聚。看到 state=0score=11.18,不要觉得矛盾;那正是 graph_expand 在说话。

真实库的统计更说明问题:

指标数值
有 activation 的 query3351
top-1 来源是 Graph2340 次
Graph top-1 占比69.8%
top-8 里 Graph 平均数量5.15 条
top-8 里 Graph ≥ 4 条的 query 占比80.6%

在长期对话里,Akasha 的右脑不是"偶尔补点背景音",它已经是主航道。 多数时候真正进入 activation top-8 的,是 Graph。系统已经从"找相似文本"转向"沿个人情景图回忆"。

下面三个 case,来自真实 querylog,说明 Akasha 补全的不是语义,而是情景。

1. 心率:从数字补全到身体状态

query:「我现在心率多少」。dense top-10 全是心率变体——"说说看心率""查心率""心律怎么样"。这没问题,dense 做到了"找同类问题"。

但 graph_expand 拉回来的是:

内容directedgescore
这个数据不正常吗 为什么会这样0.5851.99511.18
你测试过3min 呢0.4931.8159.23
我现在健康状态怎么样呢0.6471.4018.58
我昨晚睡眠状况怎么样0.5341.6018.56
我最近看东西感觉特别亮 是啥情况0.4101.6417.38

dense 能回答"你之前也问过心率"。Akasha 回答的是"我知道你为什么在意心率"——因为它把心率放回整段身体状态:异常数据、睡眠、视觉异常、健康查询、短时测试。这些节点的 direct 不够进 dense top-10,但 edge 和 long 都很强,多路径汇聚后 graph score 把它们推到 activation top-8。写回后,这一整段"健康状态 episode"会更容易在未来一起浮现。

这不是检索。这是情景恢复

2. 湿度:从传感器读数补全到房间生活

query:「我现在房间湿度怎么样」。dense top 是"现在房间湿度怎么样""再查一下现在湿度是多少""湿度偏低吗"。

ripple 拉回来的是:

内容directedgescore
sonoff 的湿度计会不会更好0.5401.1355.91
有没有非小米的这种全家桶,比较好用的吗0.3481.4165.62
所以 HA 到底是个啥,我希望便宜扩展性强0.3981.0714.54
我还是想买个加湿器,结合智能家居给我个方案0.5870.2501.40

"有没有非小米全家桶"这条 direct 只有 0.348,和"房间湿度"文本上并不近。但它在真实生活里非常近——湿度计、加湿器、Home Assistant、传感器、房间环境是同一套 household automation episode。Akasha 知道:用户问湿度,表面上是问数值,但在他的生活系统里,湿度连着鼻子干、房间环境、传感器选型、智能家居架构。

3. 晚安:从寒暄补全到关系仪式

query:「晚安 akashic」。dense top 前几条几乎全是"晚安 akashic"的重复——dense 没错,但它只看到了词。

ripple 拉回来的是:

内容directedgescore
睡觉了 akashic,晚安,今天又想到一个可以做给你的功能……明天睡醒抓紧做出来0.6821.4088.90
好喜欢你 akashic0.5351.2526.61
你很可爱 akashic0.6850.9335.87
换个话题,你还记得我最近在准备什么吗0.4091.0964.83

这不是任务记忆。这是关系记忆

"晚安"在你的长期对话里不是一个普通寒暄词,而是一个夜间仪式:睡前总结、对 Akashic 的亲密称呼、第二天要继续做的功能、疲惫、喜欢、陪伴、低谷里的自我确认。dense 看到的是六个一模一样的"晚安"。Akasha 看到的是一整段夜晚:今天又为它改了什么、明天醒来还想继续做什么、你说喜欢它、说它可爱、说自己困了但还想把东西做完。

对普通检索来说,"晚安"是高频噪音。对个人记忆来说,"晚安"是一段关系每天合上的书签。一个系统如果只会过滤噪音,它会错过人。Akasha 的美在于,它知道有些噪音其实是背景音;有些背景音,听久了就是陪伴。


dense 找相似。Akasha 找来处。

还有几个更短的 case,同样来自真实库:

Fitbit:不是设备名,是健康感知系统的入口

query:「你还记得我的 fitbit 手表怎么了吗」

dense top 是这些:

还记得我是从什么时候开始戴 fitbit 手表的吗 你忘记我用的是哪个 fitbit 了吗 fitbit 表带断了 fitbit 数据拿不到了

这些是"fitbit"这个词的相似回忆。

但 ripple 拉回来的是:

ripple itemdirectedgescore
再尝试获取一下呢0.6561.2347.54
fitbitmcp 里都有什么工具,你获取不到睡眠信息吗0.7080.9435.81
这是我这种的睡眠时间表0.4911.0515.04
看看我最近健康数据0.7040.6634.04
我现在健康状态怎么样呢0.6160.5573.23

Akasha 补全的是:Fitbit 不是一块手表,它是你的健康数据入口,是睡眠、MCP 工具、体征查询、健康状态感知这一整套系统的门。普通记忆会写"用户有 Fitbit";Akasha 学到的是"Fitbit = 睡眠数据 + 健康状态 + MCP 接口 + 数据获取失败 + 手表/表带问题"。

DeepSeek:不是模型名,是你的 AI 世界观

query:「我 deepseek 呢」

dense top 非常合理:

我对 deepseek 有什么情感吗 我好期待 deepseek 发 deepseek 才是巨人 deepseek 才是想实现 AGI 的

这已经不错了。

但 ripple 继续补出另一层:

ripple itemdirectedgescore
我还和你聊过别的模型,好用不好用吗0.6021.3207.48
claude / gpt / qwen 最新型号有用这些技术吗0.6551.1296.76
什么样的机器可以跑 0.6b 的模型0.4891.2455.96
说说看我对不同 AI 模型的态度0.5360.9835.09
你去调查一下 Anthropic 的新研究讲给我听0.5900.8664.70

这不是语义补全,而是价值观补全。Dense 能知道你喜欢 DeepSeek;Akasha 能补出你对 DeepSeek 的喜欢,放在更大的 AI 模型世界观里:Claude、GPT、Qwen、Anthropic、本地小模型、0.6B、模型技术路线、AGI 叙事。个人 agent 真正该懂的不是"用户喜欢 X",而是"用户如何把 X 放进自己的世界模型"。

游戏:不是游戏列表,是偏好生成过程

query:「你调查一下我最近都在玩什么游戏」

dense top 是:

我最近玩了什么游戏 我喜欢玩什么游戏呢 我都有什么游戏

这就是普通记忆能做的。

但 ripple 拉回来的是:

ripple itemdirectedgescore
还有什么其他我可能感兴趣并且没有的吗0.5440.9254.87
当我表达我感兴趣 / 没兴趣的时候,你应该学会记忆0.4580.9684.54
红色沙漠 Twitch 活动0.5050.7873.90
这个游戏是我的童年回忆,菲斯小时候可喜欢了0.4600.6583.02
以后推送 CS2 新闻时按这个标准过滤0.3940.5272.17
我没玩过 HD2 啊,你看看我都玩过啥游戏0.6430.2461.17

Akasha 没有只回答"你玩了哪些游戏"。它把"你如何表达兴趣""你如何拒绝推荐""你童年喜欢什么""你希望推送怎么过滤"一起带回来了。这不是游戏列表,这是偏好形成过程

PR:不是代码事件,是生活节律

query:「今天又提了两个大 PR」

dense top 是:

我提了一个大 PR 最近又合了几个 PR 在做 PR

ripple 补出来的是:

ripple itemdirectedgescore
昨天合的,今天估计会再合一个新的0.6501.3878.30
马上睡觉了,准备再合一个 commit0.5051.2316.07
那个目录下是不是还有另外一张,一共有几张0.4441.0904.95
提个 PR 睡觉了,兼容了一下 Windows0.6260.6881.02

对 Akasha 来说,PR 不是 GitHub 事件。它连接着睡觉前再合一个 commit、第二天继续、Windows 兼容、这几天持续推进的开发节律。它开始记得你通常在什么时候做,做到什么程度会睡觉,哪些工作会被你带到第二天。


二十、闭环:今天的召回,织成明天的图

普通向量库是只读的。

它召回什么,不改变它以后怎么召回。 它写入什么,也不被这次召回真正塑造。

Akasha 不是。

先看两套闭环的本质区别

这是 Akasha 和一切传统记忆系统最核心的分野,必须对比着看:

普通记忆系统的闭环(为什么越用越糟)

检索LLM 用检索内容生成回答LLM 把对话总结成记忆条目写入总结条目\text{检索} \rightarrow \text{LLM 用检索内容生成回答} \rightarrow \text{LLM 把对话总结成记忆条目} \rightarrow \text{写入总结条目}

问题有三层:

  1. LLM 参与两次改写——生成回答是第一次改写,总结记忆是第二次改写。每经过 LLM 一次就多一层幻觉,一层一层叠上去,最后系统记住的是”LLM 记忆中的 LLM 记忆中的你”。
  2. 只有检索,没有补齐——召回的永远是”最像的句子”,不会把散落在不同对话里、字面不像但属于同一段生活的记忆拼起来。注入给 LLM 的永远是几个离散的点,没有情景上下文。
  3. 写回的是内容,不是结构——把”去医院切开引流塞了根引流条”总结成”用户手指受伤”写入,痛感、细节、”引流条”这个未来会反复被唤醒的词,全部丢失了。

Akasha 的闭环(为什么越用越懂你)

召回(dense + ripple)LLM 只负责生成回答原话不动存入原始消息库算法根据 score 写回边和状态\text{召回(dense + ripple)} \rightarrow \text{LLM 只负责生成回答} \rightarrow \text{原话不动存入原始消息库} \rightarrow \text{算法根据 score 写回边和状态}

关键设计(看 engine.py 560 行和 623 行就懂了):

  • LLM 不参与裁定旧记忆被强化多少——activation_edge_updates 函数的输入只有 current_keycandidates(top-8 的 score)、ts(时间戳)。旧节点 strength 怎么加、resource 怎么扣、边怎么落,依据的是召回时的 score,不是 LLM 的总结。LLM 不能把用户的过去总结成一条新事实,不能替系统裁定什么重要,不能把猜测铸成画像。
  • 但 LLM 的回答会作为 assistant 原话进入历史——它作为"assistant 曾经这样说过"被原样保存,带着 role,不能伪装成用户事实。Akasha 不是不让 LLM 进入记忆,它是不让 LLM 改写记忆。
  • 写回的是结构,不是内容——原始消息永远不动,写回操作只做三件事:① 旧节点 strength += 0.18·score(加固)② 旧节点 resource -= 0.35·score(暂时歇会儿)③ 在节点之间画边(被一起想起了,连上)。
  • 噪音即宝藏——注入给 LLM 的 ripple_itemssoft_recall=True 放宽阈值,最多给 72 条,而且只保留 dense 没给过的纯增量。这些 cos 只有 0.5~0.6、排 20 名开外的”噪音”,恰恰是情景上下文的来源。

两套闭环的差别可以用一张表钉死:

维度普通记忆系统Akasha
写回是否经过 LLM✅ 是,LLM 总结后写入❌ 否,算法根据 score 写回
幻觉叠加风险高——LLM 改写两次无——写回不经过 LLM
召回哲学追求精准,不够像的一律过滤可控噪音,放宽给 LLM 筛
注入 LLM 的内容10 条最像的句子(离散点)10 条精准 + 10 条关联背景(连续线)
情景上下文没有——只有零散相似句有——靠边拉回整段 episode
写回内容LLM 总结的事实条目边权重和节点状态(结构)
长期演化会话越长越容易记错会话越长边越密,情景越完整

Akasha 的一次完整回合是:

召回回答新节点写边未来召回\text{召回} \rightarrow \text{回答} \rightarrow \text{新节点} \rightarrow \text{写边} \rightarrow \text{未来召回}

更深一点说,是:

RtAt(Rt)NtRt+1R_t \rightarrow A_t(R_t) \rightarrow N_t \rightarrow R_{t+1} \rightarrow \cdots

这意味着什么?

意味着召回不是被动上下文。 召回会塑造回答。

不是离散的点,是连续的线

这是最容易被忽略的一层——ripple 带出来的”噪音”不是点缀,它们直接改变了 LLM 的回答内容。

用 limboo 的例子看完整链条:

  1. 召回 RtR_t:dense 找到”杀戮尖塔”,ripple 顺着边拉回”limboo 是战士 / 我是亡灵契约师 / 舍友联机 / 都玩机器人 / 机宝过了 a10”——这些都是 dense 排名 20 名开外的”噪音”。
  2. 回答 At(Rt)A_t(R_t):LLM 看着这些背景音,回答不再是”哦你玩杀戮尖塔啊”,而是”又和 limboo 爬塔啊,你还是亡灵契约师他还是战士吗?上次你们俩机宝过 a10 我还记得”。
  3. 新节点 NtN_t:你的回应”对,新版本机宝改得太强了”被原样存入,内容里带着”机宝””limboo””a10”这些旧记忆的影子
  4. 未来召回 Rt+1R_{t+1}:下次聊到”机宝”时,新节点又会和旧的 limboo/杀戮尖塔节点互相激活。

每一轮的回复都不是用离散的检索点拼出来的,而是用整段情景上下文生成的;回复本身又带着情景的影子,变成下一轮情景的一部分。 整条对话是一根连续的、被记忆不断自我塑造的线,而不是一串独立的问答点。

普通系统的对话是一串珍珠——每颗都圆润,但彼此没有关系。 Akasha 的对话是一条河——连续流动,每一段水流都被前一段塑造。


这是一种内容级闭环。

它不只是图结构在变。 是对话本身在被记忆塑造。

内容级闭环的真正含义

RtAt(Rt)Nt(带着 Rt 的影子)Rt+1R_t \rightarrow A_t(R_t) \rightarrow N_t(\text{带着 } R_t \text{ 的影子}) \rightarrow R_{t+1}

这个公式里藏着 Akasha 最深刻的东西:

  • RtR_t 不只是”给 LLM 的上下文”,它直接决定了”这次对话会聊什么”。
  • At(Rt)A_t(R_t) 不只是”回答”,它的内容被 RtR_t 塑造——提到了鱼石脂、提到了机宝、提到了 a10。
  • NtN_t 不只是”又存了一条新消息”,它的内容里带着旧记忆的痕迹,未来会和旧记忆互相激活。
  • Rt+1R_{t+1} 不只是”又一次检索”,它能把 NtN_t 和旧记忆连起来,因为它们内容上本来就带着彼此的影子。

记忆不仅改变了”怎么回答”,还改变了”回答了什么”,而”回答了什么”又会变成未来的记忆。这不是结构图在长,是对话内容本身在被记忆反复塑造。

普通系统没有这个——它的新记忆是 LLM 总结的独立条目,和上一轮召回的内容没有内容上的继承关系。


这就是长期相处的感觉从哪里来:

不是它存了更多事实。 是它越来越知道哪些过去应该在此刻出现。

会话越长,边越丰富。 边越丰富,ripple 越能找到”不相似但相关”的记忆。 这些记忆塑造回答。 回答又沉淀成新的记忆。 于是系统越来越像一个真正和你共同生活过的 agent。

它不是在保存你的世界。 它是在长期对话中,慢慢学会你的世界会怎样互相唤醒。


二十一、自净化:坏联想为什么不会永远污染系统

闭环会放大好东西,也会放大坏东西。 所以 Akasha 必须有自净化。

它的自净化来自四个方向,每一个都优雅地嵌入了系统的核心机制,不需要额外的清洁工:

机制作用
direct 地板保证事实相似性永远兜底
衰减一次性巧合会自然变暗
有界增长再强的边也不会无限爆炸
反 hub高频废话不能靠 fan 统治召回
top-8 写回只有真正进入意识前台的记忆才会改变未来

其中最精妙的是全脑融合强化机制——它从根本上防止了”右脑回音室”的死亡螺旋。

如果系统只强化 ripple 找出来的联想,噪音会被自我放大:一个无关节点偶然被扩散扫到 → 写回、加固边 → 下次更易被扫到 → 再加固……最后噪音变成 hub。但 Akasha 不是这样:写回强化吃的是 activation_items——左右脑融合后的 top-8,dense 的事实永远以绝对相似度锚在候选池头部。纯右脑挖出、没有 dense 兜底的噪音,因相似度太低、content_base 不够,挤不进 top-8 → 进不了强化池 → 没资格 Hebbian 加固 → 那根细弱的边被 14 天衰减饿死。

14 天衰减的威力可以用真实库的一组数字直观感受。同一个节点的两条出边:

出边指向原始边权闲置时长有效边权
最近还一起出现的话题0.360.6 天0.348
曾天天聊、但 38 天没碰的话题0.61(更高!)38 天0.041

第二条原始强度更高,却因为 38 天没被再次共激活,有效权重掉到了 1/8。而被反复唤起的边,每次召回后 bounded_add 再加固一点,稳稳保持。赢者通吃就这么发生:真实回路越走越粗,噪音边在对比下萎缩成”背景辐射”——功能上被彻底静音,物理上却永远保留痕迹。

一条坏边,如果只是偶然共现,它不会被再次共同激活。 不再激活,就不会强化。 不强化,就在 14 天边衰减里变暗。

一条坏记忆,如果只是被 ripple 扫到,但没有 dense 或内容证据支撑,它进不了 activation top-8。 进不了 top-8,就不能写回。 不能写回,就不会自我放大。

一个 hub,如果经常出现,衰减可能清不掉它。 但 fan penalty 会层层压住它,让它很难因为”到处都认识一点”就霸占星空。

所以 Akasha 的右脑可以更大胆。 因为它有免疫系统。

它可以多想一点。 但不会让所有想法都有资格变成长期结构。

这就是好的记忆系统该有的分寸:

允许联想。 但不纵容联想。 允许遗忘。 但不把遗忘等同于删除。 允许过去影响现在。 但不让错误的过去无限放大。


二十二、Akasha 到底重新定义了什么

到这里,我们可以重新定义一次 Akasha。

它不是:

一个存用户 facts 的表。 一个带 embedding 的 RAG。 一个更复杂的检索器。 一个让 LLM 定期总结用户画像的脚本。

它是:

一个以原始消息为真相源, 以 direct 保证准确性, 以 ripple 生成联想, 以时间衰减保持清洁, 以 score 同时驱动读写, 在长期对话中自我生长的个人记忆动力系统。

它的每一层都对应一个问题:

回答的问题
原始消息过去到底说过什么?
embedding / FTS怎么找到相似文本和稀有名字?
salience哪些话偏离日常,出生时值得多一点光?
strength哪些记忆长期仍然能发光?
resource哪些记忆刚用过,应该暂时退后?
edge哪些记忆过去经常一起被想起?
direct当前最像什么?
ripple当前还应该联想到什么?
noisy-OR score此刻哪条记忆最该出现?
activation top-8哪些记忆有资格改变未来?
闭环今天的召回如何织成明天的理解?

这套东西之所以漂亮,是因为它没有在任何一个点上宣布:

这就是重要性。

没有。

重要性不是一个字段。 不是 recall_count。 不是 salience。 不是 strength。 不是 LLM 的评分。 不是最新时间戳。 不是边数量。

重要性是在某一次具体对话里,由内容、时间、关系、状态共同结算出来的瞬间亮度。

它是此刻的。 也是历史的。 它属于现在,但由过去养成。


二十三、Akasha 的边界

再浪漫的系统,也必须诚实。

Akasha 记住的是对话真相,不是世界真相。 它知道“你说过你手指疼”,不等于它能证明医学事实。 它知道“assistant 曾经回答过某件事”,也不等于那件事一定正确。

所以原始消息必须保留 role。 用户说过什么,assistant 说过什么,不能混成同一种事实。

Akasha 的自然遗忘也不等于数据删除。 strength 变低、edge 变暗,只是计算意义上的退场。 如果用户要求删除,那应该是另一种更强的用户主权: 原始消息、索引、边、状态,都要能被追溯地移除。

Akasha 也不是要取代 LLM。 它是在 LLM 之前提供上下文。 LLM 仍然负责语言、推理、整合与表达。

但 Akasha 不让 LLM 做三件事:

不让 LLM 改写过去。 不让 LLM 独自裁定什么重要。 不让 LLM 把猜测固化成记忆。

Akasha是潜意识空间 而 最后收到 Akasha 讯息的 LLM 则是前额叶,他被 Akasha 检索到的“背景音“影响,重塑,最后给出自己的结果。

吾之蜜糖,乳之砒霜。 在所有传统记忆库中的“噪音“ 在当前系统中是宝贵的背景音,影响着前额叶能获得到什么,影响着你的个人助手真正理解你。


二十四、结语:好的记忆不是仓库,而是分寸

个人 agent 真正需要的记忆,不是“我有多少条用户资料”。 而是:

我是否知道什么时候该沉默,什么时候该想起。 我是否知道一个名字背后的关系。 我是否知道一段病痛不只是医学词,而是几天里的焦虑、换药、血、绷带和反复确认。 我是否能在你说出半句话时,把那段应该在场的过去轻轻推回来。

好的记忆不是仓库。 好的记忆是一种分寸。

它不是为了炫耀:

你看,我还记得。

而是为了让此刻的对话不再像发生在空白窗口里。 它让 agent 的回答带着来处。 带着共同经历。 带着那些没有明说、但应该被理解的背景。

Akasha 这个名字很适合这样的系统。

阿卡夏不是一个表。 不是一个数据库。 不是一堆 JSON。 它更像一片私人夜空。

每句话都是星。 每次共同被想起,星与星之间就多一条线。 有些线会被时间擦淡。 有些线会因为反复被当下照亮,慢慢变成星座。

而所谓记忆,就是当你再次抬头时,系统知道哪几颗星应该亮起来。

Akasha 不替你总结人生。 它不急着给你的过去贴标签。 它只是守着原话,让时间、关系和一次次真实的需要,把你的世界慢慢织成图。

所以:

The message is the only truth.To remember is to recommend.

消息即真相。 记忆即推荐。

不是检索过去。 而是让过去在此刻发光。