OpenClaw 为什么又贵又健忘?OpenViking 基本上就是来治这个的
如果你认真跑过一阵 OpenClaw,大概率会被两个问题反复扎到。
如果你认真跑过一阵 OpenClaw,大概率会被两个问题反复扎到。
第一,它很废 token。
第二,它很容易失忆。
这两个问题其实经常一起出现。你和它聊得越久,历史消息堆得越厚,它每一轮都得把前面那一大坨上下文重新吞进去。token 一路往上烧,成本越来越难看。可奇怪的是,钱花了,记性却没有跟着变好。聊到后面,它还是会忘掉你前面说过的偏好,忘掉已经解决过的坑,甚至把刚聊完的结论又绕回来一遍。
这事最烦人的地方,不是贵,也不是笨,而是又贵又笨。
表面看,OpenClaw 的问题像是“上下文不够大”。但你真去翻实现,会发现问题不在上下文小,而在上下文太原始。它擅长把东西不断加进去,不擅长把过去整理成下一轮还能高效使用的结构。于是系统像一个只会追加日志、不会做索引的存储层。消息当然都在,可一到要用的时候,不是拿不到,就是拿得太贵。
这也是 OpenViking 真正有价值的地方。
它不是又造了一个“长期记忆”的营销词,也不是简单给 OpenClaw 加个数据库。它干的事情更像是:给 OpenClaw 补上一层上下文操作系统。目标非常明确,就两个:把 token 压下来,把记忆留得住。
OpenClaw 到底为什么废 token
先把问题掰开。
OpenClaw 本身就不是一个轻上下文系统。哪怕你只发一句 hello,它背后也会把一整套运行现场一起打包进去:消息结构、回复链、转发链、群组信息、session 归属、权限指令、技能、工具、项目上下文、系统提示词、历史消息,最后才送去模型。
换句话说,模型看到的从来不是一句裸的 hello,而是一份很厚的执行快照。
这套设计当然有它的必要。因为 agent 不是只回答问题,它还要知道自己在哪个会话里、能不能调工具、该不该走某条路由、之前发生过什么。问题在于,这套东西一旦进入长对话,token 消耗就很容易失控。
最朴素的原因是:线性追加。
旧消息不断往后堆,新消息每来一轮,都要把相当一部分旧上下文重新带上。你可以把它想成每次函数调用,都把整个历史栈从头拷贝一遍。短对话还能忍,长对话就会变成纯粹的成本灾难。
更糟的是,这种“全带上”的方式并没有真的解决记忆问题。因为 transcript 只是原始材料,不是可回忆的结构。用户说过什么、偏好什么、踩过什么坑、哪件事是关键事件,这些信息如果只是埋在大段聊天记录里,那它们技术上存在,使用上却等于不存在。
于是你会看到一个很别扭的现象:上下文越来越长,但 agent 并没有越来越懂你。
OpenViking 怎么下手
OpenViking 的切入点很硬。它先承认一件事:不是所有过去都值得原样带进现在。
真正配进入下一轮上下文的,不是原始聊天记录本身,而是从聊天记录里提出来的结构。比如:
- 这是用户的长期偏好
- 这是某次解决问题留下来的案例
- 这是后续还会反复出现的实体
- 这是一个值得记住的事件
- 这是可以复用的模式
也就是说,它不把“记忆”理解成把旧对话存起来,而是把旧对话加工成以后还能低成本命中的信息层。
这背后有三件很关键的实现机制。
1. 分层记忆:L0 / L1 / L2
这是 OpenViking 最像工程系统、也最有效的一刀。
它不是给每条记忆只存一个版本,而是拆成三层:
- L0:一句话抽象,通常对应
.abstract.md - L1:概览版,通常对应
.overview.md - L2:完整内容,也就是原始完整记忆文件
这套结构的意义非常大。因为它把“回忆”这件事,从一次昂贵的全文加载,改成了逐层探测。
先看 L0,成本最低,适合快速语义检索。
再看 L1,拿更多上下文做判断。
真有必要,才去看 L2。
这个思路和存储层级很像。不是每次读数据都直接打到最慢、最贵的那一层,而是先用更便宜的近端层做筛选。你也可以把它理解成 cache line 先命中,再决定要不要下钻到主存。这样一来,记忆检索不再是“相关就整段塞进 prompt”,而是“先便宜地找,再谨慎地带”。
token 为什么能降,第一根梁就在这里。
2. 会话压缩:把历史从流水账变成摘要 + 索引 + 活跃区
OpenViking 解决的第二个问题,是会话会无限膨胀。
OpenClaw 的对话天然会越聊越长。如果系统只是把消息原样累加,那 prompt 成本只会一路向上。OpenViking 的做法是,一旦会话里的 pending_tokens 到了阈值,就触发 commit 和压缩。
压缩之后,旧内容不会再以原始聊天记录的样子留在前台,而会被改写成三块:
- Session History Summary:会话摘要
- Archive Index:归档索引
- Active Messages:当前活跃消息
这个结构很重要。因为它让上下文从“无界追加”变成了“有界重组”。
摘要负责告诉模型,之前大概发生了什么。
索引负责保留可追溯性,必要时还能展开。
活跃区只保留眼下最该参与推理的消息。
这样系统就不需要每一轮都把所有旧内容背在身上。你可以把它理解成虚拟内存里的换页:不是数据没了,而是它不再占前台最贵的位置。
token 为什么不会无止境上涨,第二根梁在这里。
3. 结构化提取:不是保存聊天,而是抽取长期有用的信息
如果压缩只做到“写摘要”,那它还只是一个省钱工具。OpenViking 更值钱的地方,在于它会从会话里提取长期有用的结构化记忆。
参考它现在的机制,大致会抽六类内容:
- PROFILE
- PREFERENCES
- ENTITIES
- EVENTS
- CASES
- PATTERNS
这个设计看起来像分类目录,实际上是在回答一个更本质的问题:什么东西值得被下一轮再次命中?
比如“用户偏好 async/await”,这是偏好。
比如“上次 mock timing issue 是怎么解的”,这是案例。
比如“某个项目、某个工具、某个概念反复出现”,这是实体。
一旦这些东西从 transcript 里被抽出来,后面的 recall 就不再是在一坨聊天记录里捞针,而是在结构化内存里查索引。
这里的变化不是量变,是质变。因为 agent 缺的从来不是更多历史,而是可检索、可重排、可预算控制的历史。
它怎么避免“记住一堆没用的东西”
光有 recall 还不够。任何做长期记忆的系统,最后都会撞上一堵墙:如果什么都记,等于什么都没记。
OpenViking 在这点上处理得也比较工程化。
它的 recall 不是简单按向量相似度拉一批结果回来,而是会做后处理:
- 去重
- 分数阈值过滤
- 重排
- 按 token budget 裁剪
也就是说,最后送进 prompt 的,不是“所有相关候选”,而是“这一轮最值得占位置的少数内容”。
这很像查询优化器。第一轮把候选集拉大一点,后面再用更贵但更准的逻辑收紧结果。目的不是召回得越多越好,而是让真正进上下文的东西尽量少、尽量准。
另外它还有冷记忆归档机制。热度低的内容会被移到 archive,不再参与高频检索。不是因为这些内容没用,而是因为它们不该在每一轮都来抢上下文预算。
这件事听起来像“遗忘”,其实恰恰是成熟记忆系统该有的能力。真正好的长期记忆,不是假装自己不会忘,而是知道该把什么放近、把什么放远。
所以它到底解决了什么
如果你只从产品话术上看,OpenViking 像是在解决两个问题:省 token,补记忆。
但如果从实现层看,这其实是同一个问题的两面。
OpenClaw 之所以又贵又容易失忆,不是因为它没有历史,而是因为它没有把历史整理成下一轮还能高效使用的形态。原始 transcript 太重,全文加载太贵,关键信息又埋得太深。
OpenViking 做的事,就是把“历史存在”变成“历史可用”。
它先把旧内容压缩掉,防止上下文无限膨胀;
再把有价值的信息提出来,沉成长期记忆;
然后用分层检索、重排和预算裁剪,把这些记忆在合适的时候送回当前轮。
所以我更愿意把它理解成一种上下文治理系统,而不只是记忆插件。
它治的也不是一个小毛病,而是 agent 走向长会话时最早暴露出来的那个结构性问题:
过去没有被整理。
而一旦这件事开始被整理,OpenClaw 才第一次有可能不靠蛮力硬撑长对话。
评论区
已有 0 条评论,当前支持二层回复。
登录后即可参与评论
评论会展示你的昵称与头像。支持直接回复评论,当前限制为二层结构。