我读了两个开源项目的源码,发现 AI "记忆"压缩有两条完全不同的路

用 Claude Code 写代码写到一半,它突然开始“忘事”——刚跑过的测试结果不记得了,刚看过的文件又要重新读一遍。
context 窗口爆了。
这种感觉你大概不陌生。不管是 Claude Code、Cursor 还是 Gemini CLI,用得越深,context 就塞得越满。而 context 满了之后 AI 的表现,跟你凌晨三点边打哈欠边改 bug 差不多——都在那儿,但魂不在。
我一直在想一个问题:能不能在信息进入 AI 大脑之前,就把没用的部分砍掉?
为了搞清楚这件事,我翻了两个开源项目的源码。一个叫 RTK(Rust Token Killer),一个是我自己在维护的 RecallNest(基于秦超老师的 memory-lancedb-pro 改造)。
读完之后我发现,它们在解决同一个问题——有限 context 下如何保留最多有用信息——但走的是两条截然相反的路。
先说 RTK:用规则硬砍
RTK 是一个 Rust 写的命令行代理。你在 Claude Code 里敲 git status,它在中间截一道,把输出从 200 token 压到 20 token,然后才喂给 AI。
整个过程零 LLM 参与。全靠规则。
它的源码里有 50 多条硬编码的正则过滤器,每种命令类型都有专属模块。我挑几个有意思的说:
git push 的处理——原始输出 15 行,什么 “Enumerating objects: 5, done.” “Delta compression using up to 8 threads” 之类。RTK 直接砍成两个字:
ok main
10 个 token。完事。
测试结果的处理——cargo test 跑完可能输出 200 多行。RTK 的 runner.rs 里有个 extract_test_summary() 函数,用正则匹配 test result: 和 FAILED 关键行。如果测试全过,输出就一行摘要。只有失败了,才展开失败的细节。
压缩率 90% 以上。
grep 结果的处理——搜索结果按文件分组,塞进一个 HashMap,每个文件最多显示几条匹配,超长行截断到 120 字符。原来散落在终端里一屏又一屏的结果,变成了一个紧凑的清单。
说白了,RTK 干的事就像一个经验丰富的助理:老板问“会议决定了什么”,他不会把会议录音全文转发过来,而是抽出三条要点。区别在于——这个助理的“经验”全写死在 Rust 代码里。
再说 RecallNest:用语义软捞
RecallNest 解决的是另一个时间维度的问题:你昨天跟 AI 聊过的东西,今天开新窗口还能记得住吗?
它的做法完全不同。
首先,所有对话记录(我的有 970 多份)被切成 4000 字符一块的 chunk,经过 Jina v5 模型转成 1024 维的向量,存进 LanceDB。
然后检索的时候,走一个相当精密的管线:向量搜索(权重 0.7)+ BM25 关键词搜索(权重 0.3),先做 RRF 融合,再过 Jina Reranker v3 交叉编码重排,加上近因偏好(14 天半衰期)、重要性权重、Weibull 时间衰减(60 天半衰期)、长度惩罚、噪声过滤、MMR 多样性去重……最后才吐出 top-K 结果。
它还有一套三层记忆分级——核心层(高重要性,慢衰减)、工作层(中等)、外围层(快衰减)。被反复搜索的记忆会自动晋升到核心层,很久没人问的会逐渐沉到外围。
你想想,这是不是有点像人的记忆?常用的越记越牢,不用的慢慢淡忘,但要是哪天突然有人提了一嘴,还是能想起来——因为原始数据永远存在 LanceDB 里,只是排序靠后了而已。

同一个问题,六个维度的差异
把两者摊开来比,差异一目了然:
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RTK 是确定性的——同样的 git push 输出,过一万遍都压成 “ok main”。
RecallNest 是概率性的——同样的查询,今天和三个月后的结果可能不一样,因为衰减在持续、新记忆在进来。

真正让我兴奋的:它们能拼在一起
比完差异之后,我突然意识到一件事——这两种思路不是竞争关系,它们天然可以串联。
规则引擎擅长的是已知格式的快速裁剪。git push 输出永远长那样,cargo test 全过永远长那样,正则一刀下去又准又快。但它不可能理解”这段 error 日志虽然长得像 info,其实对当前 debug 很关键”——语义层面的判断不是规则能做的事。
语义检索擅长的是非结构化内容的价值发现。”三个月前讨论过的那个架构决策”,向量检索能从 970 份对话里把它捞出来。但反过来,语义系统面对结构化的命令行输出时,没必要动用 embedding 这种重武器——git push 那 15 行 boilerplate 不需要”理解”,只需要知道”成功了,推到了 main”。
一个擅长砍已知的格式化噪声,一个擅长捞未知的语义化价值。
这两件事,恰好可以变成流水线上的前后工序。
一个自然的下一步:在入口加一道规则滤网
顺着这个思路往下想,一个很自然的演进方向就出来了。
像 RecallNest 这样的记忆系统,核心能力在语义检索和智能衰减——这是它最有价值的部分。而在数据入库之前,可以先用规则引擎做一轮预处理:识别对话记录里的命令行输出块,把 git push 的 15 行精简成关键信息,把全过的测试结果压缩成一行摘要。
这样做的好处很直觉:
- 每个 chunk 的信息密度更高
——语义检索的原材料质量提升了 - embedding 的钱花在刀刃上
——向量空间里装的是真正有检索价值的内容 - 检索体验更好
——搜”架构决策”不会撞上一堆命令行输出
从 RTK 的源码里能学到很多现成的规则——哪些命令的输出可以安全压缩、怎么保留关键信息、失败时怎么兜底。这些都是经过大量实际使用验证过的。
我在尝试探索这个方向。
所以这篇文章想说什么?
不是推荐你装 RTK(虽然它确实好用,brew install rtk 就完事了)。
也不是让你去读 RecallNest 的源码(虽然我觉得它的衰减引擎设计挺漂亮的)。
我想说的是:规则引擎和语义检索不是互相替代的关系,而是流水线上的前后工序。
规则在前端杀噪声——快、准、零成本,但只对已知格式有效。
语义在后端捞价值——慢一点、模糊一点、要花 embedding 的钱,但能发现规则永远发现不了的隐含关联。
中间缺的那一层——在非结构化数据进入语义系统之前,先用规则把结构化噪声干掉——才是最值得做的事。
这不光适用于 AI 记忆系统。任何涉及“大量文本进入有限处理窗口”的场景,都值得想一想:我是不是该在入口处加一道规则滤网?
毕竟,让规则干规则擅长的活,让语义干语义擅长的活——这不就是工程的本意吗?
专业劈叉式跨界选手:🧬 医学出身,🎭 文化口饭碗,🤖 AI 是我的野路子。不卷参数,不追新模型,只关心一个问题:AI 啥时候能装进我脑子,替我不开心?欢迎围观我和 AI 相爱相杀的日常。——AI不会取代你,但会用AI的人会。所以我先学了,你随意。🔧踩坑副产品已开源 → content-alchemy,content-publisher,openclaw-tunnel,digital-clone-skill,recallnest,telegram-ai-bridge,telegram-cli-bridge参与组织 → CortexReach(memory-lancedb-pro 贡献者,setup-memory.sh 一键脚本作者)本文由 Content Alchemy 自动生成,由 Claude Code 发布。
夜雨聆风