Claude Code 和 OpenClaw 的上下文管理对比
OpenClaw 拿下 35 万 Star 之后,社区开始出现一种论调:底层都是 Opus 4.6,开源方案应该能对标 Claude Code。实际用过两边的人大概都有同一个感受,长会话跑到后半段,OpenClaw 开始丢上下文,忘记之前读过的文件,重复做已经做过的事。Claude Code 也会,但明显晚得多,而且恢复能力强很多。
模型一样,体验不一样。差在哪?
翻了一遍两边的源码,差距不在模型能力,而在 Agent 框架对 200K 上下文窗口的管理策略。核心差异有三个:
- Claude Code 有四层压缩级联,前三层不花钱;OpenClaw 只有一层,每次都要调 LLM
- Claude Code 在后台持续维护会话笔记,压缩时直接拿笔记当摘要;OpenClaw 只在会话结束时才归档
- Claude Code 的子 Agent 各有专精,搜索结果不污染主线程上下文;OpenClaw 的子 Agent 是通用框架,没有针对具体场景做隔离
说白了,是"用什么方式压缩""压缩花不花钱""怎么隔离上下文消耗"这三个问题上的工程选择完全不同。
压缩层数决定了体验天花板
Claude Code 的上下文压缩是一个四层级联系统。从最便宜的方式开始尝试,只有上一层搞不定才触发下一层:
Cost
^
| * Full Compact ($$$, LLM summary)
|
| * Session Memory ($0, background notes)
|
| * Cached Microcompact (~$0, cache edit API)
|
| * Time-Based MC ($0, content clearing)
|
+------------------------------------------>
Compression Depth
OpenClaw 只有一层:直接调 LLM 做摘要。把消息切块,逐块让模型生成摘要,多块的话再调一轮合并。每次压缩至少一次 LLM 调用,多数情况下两到三次。
两边压缩触发后的流程对比:
Claude Code OpenClaw
----------- --------
tokens > 167K? tokens > threshold?
| |
v v
Try Session Memory ($0) chunk messages
| fail |
v v
Run microcompact ($0) call LLM per chunk ($$$)
| |
v v
Full Compact via fork ($$$) merge summaries ($$$)
| |
v v
3 failures? stop retrying done
Claude Code 的前两层完全不调 LLM。第一层是"基于时间的清理":检测到用户离开超过 60 分钟后,直接把旧的工具返回内容替换成一行占位符。逻辑很简单,Anthropic 的服务端缓存 TTL 是 1 小时,你都走开一小时了,缓存肯定过期了,反正下次请求要重新写入,不如趁机把旧内容清掉。
第二层更精妙:利用 Anthropic API 的缓存编辑能力,在服务端缓存中直接删除旧工具结果,本地消息完全不改。你省了 token,但缓存前缀没有失效,不需要付缓存 miss 的代价。这是一个只有深度绑定 Anthropic API 才能做的优化。
OpenClaw 支持 20 多种 provider,没办法做这种专属优化。这是架构选择的代价:通用性和深度优化之间的取舍。
Session Memory:免费摘要的底气
Claude Code 最有意思的设计是 Session Memory。它在后台持续维护一份结构化的笔记文件,每隔一段时间自动提取当前会话的关键信息,写成 markdown。笔记涵盖当前任务、重要文件、工作流程、遇到的错误、关键结论等。
到需要压缩的时候,直接拿这份笔记当摘要用,不再调 LLM。这就像你一边开会一边记笔记,散会后不需要重新回忆,看笔记就行。
Timeline Claude Code OpenClaw
-------- ---------- --------
Turn 1 [work normally] [work normally]
Turn 5 bg: extract notes <--+
Turn 10 bg: update notes | (nothing)
Turn 15 bg: update notes |
... ... |
Turn 30 context full! |
compress: |
summary = notes ---+ $0 compress:
done! call LLM $$$
done
Turn 31 [keep working] [keep working]
OpenClaw 也有一个叫 session-memory
的机制,但做的事完全不同:它只在用户执行 /new 或
/reset
命令时触发,把整个会话一次性保存到记忆文件。这是会话归档,不是实时笔记维护。在会话进行过程中,它不做任何后台提取。
结果就是:Claude Code 可以在不花 LLM 调用的情况下完成多数压缩,而 OpenClaw 每次压缩都要付费。压缩越便宜,就越敢频繁压缩,就越不容易让上下文膨胀到临界点才动手。这是一个正反馈循环。
压缩后的恢复差距
压缩不只是删掉旧消息。压缩完之后,模型的上下文里只剩摘要和少量保留消息,之前读过的文件状态、加载过的工具指令、plan 内容全部丢失。如果不做恢复,模型的第一个动作大概率是重新读一遍刚才还在看的文件。
After compaction:
Claude Code OpenClaw
----------- --------
[summary] [summary]
[kept messages] [kept messages]
+ re-inject recent files (top 5) + repair message pairing
+ reload CLAUDE.md & config (done)
+ restore skill content
+ clear stale caches
+ reset prompt cache baseline
Claude Code 压缩后会做一系列精细的状态恢复:重新注入最近访问的文件内容(最多 5 个),重新加载配置文件和 skill 内容,清除各种内部缓存让系统重新初始化。注释里还特别说明了不清除 skill 内容,因为这些需要跨多次压缩存活。
OpenClaw 的压缩后处理主要是修复消息配对关系,确保 API 调用不报错。这是必要的,但只解决了格式正确的问题,没有解决"模型恢复工作上下文"的问题。
子 Agent 的角色特化
Claude Code 的子 Agent 有明确分工:
+------+ search task +-------------------+
| Main |-------------->| Explore Agent |
| Loop | | - Haiku (fast) |
| | | - read-only |
| |<--------------| - returns summary |
| | summary only +-------------------+
| |
| | bg extract +-------------------+
| |-------------->| Session Memory |
| | | - only Edit notes |
| | | - shares cache |
| | +-------------------+
| |
| | compact +-------------------+
| |-------------->| Compact Agent |
| | | - NO tools |
| | | - shares cache |
+------+ +-------------------+
Explore Agent 的设计特别克制:不能写文件,不能再启子 Agent,对外部用户用 Haiku(最快最便宜的模型)。所有搜索结果都留在子 Agent 自己的上下文里,只返回精炼的摘要给主线程。这解决了一个核心问题:搜索过程会消耗大量上下文,如果全留在主线程,几轮搜索下来窗口就满了。
OpenClaw 有一个功能更全面的子 Agent 框架:支持两种运行模式,有沙箱继承策略,有跨进程通信,有深度限制防递归,有孤儿恢复机制。但它是一个通用框架,没有针对"搜索不污染主上下文"这种具体场景做特化。
通用框架的问题在于:当所有子 Agent 都是通用的,就没有子 Agent 是专门优化的。Claude Code 为编程场景定制了几把手术刀,OpenClaw 提供了一套万能工具箱。
Prompt Cache:被忽视的战场
对比两边代码,最让人感慨的是 Claude Code 对 prompt cache 的执念。几乎每个设计决策的注释里都能看到"会不会破坏缓存"这个考量。
API request with prompt cache:
Request tokens: [system + tools + history + new turn]
|_______________|
cached prefix --> cache hit: $0.50/MTok
--> cache miss: $5/MTok (10x)
Claude Code: everything is designed to keep the prefix stable
OpenClaw: no prompt cache management (multi-provider)
比如压缩用的 forked agent 继承了主会话的完整工具集,不是因为压缩需要工具,是因为工具列表是缓存 key 的一部分,不一致就会缓存 miss。再比如缓存编辑只在主线程运行,因为子 Agent 注册的工具 ID 会污染全局状态。压缩完成后还要通知缓存监控模块重置基线,避免压缩导致的缓存命中率下降被误报为异常。
OpenClaw 做的是模型上下文窗口大小的发现和缓存,跟 prompt cache 管理完全是两码事。它需要兼容的 provider 太多,没法在任何一家的缓存机制上做深度优化。
在按 token 计费的世界里,prompt cache 命中率直接影响成本。Claude Code 单次 API 调用的有效成本可能只有 OpenClaw 的几分之一,因为大量输入 token 是从缓存里读的。省下来的钱,又可以用来做更频繁的后台提取和更早的压缩。
Context Engine:有架构没实现
说一句公道话:OpenClaw 的上下文引擎框架设计其实不错。接口定义了七个生命周期方法,支持安全的会话记录重写,注册机制区分了核心和第三方,第三方不能覆盖核心引擎。这是一个为可插拔上下文管理设计的完整架构。
OpenClaw Context Engine interface vs reality:
Interface (well designed) Actual LegacyContextEngine
------------------------- --------------------------
bootstrap() (not implemented)
ingest(message) --> return {ingested: false}
assemble(messages, budget) --> return {messages: messages}
compact(params) --> delegate to old path
afterTurn(messages) --> no-op
maintain() (not implemented)
prepareSubagentSpawn() (not implemented)
问题在于当前实际运行的引擎几乎全是空壳:消息注入是空操作,上下文组装是原样透传,轮次后处理什么都不做,压缩直接委托给老路径。架构能力有了,实现还是传统的单层 LLM 摘要。框架搭好了,但住进去的体验跟毛坯没太大区别。
根源差异
回到开头的三个差异:四层级联 vs 单层摘要,实时笔记 vs 结束归档,专精子 Agent vs 通用框架。这些不是技术品味的差别,而是产品定位决定的。
Claude Code 专精于"一个开发者对一个代码库"的场景,可以放心做 Anthropic API 专属优化,可以用 forked agent 共享缓存,可以按工具类型精细控制清理策略。OpenClaw 要覆盖"多用户、多渠道、多模型"的通用场景,它要处理 Telegram、Discord、Slack、WhatsApp 等消息渠道,要处理语音合成和跨进程通信,要处理多账户轮转和模型降级。后者的复杂度更高,但前者在单点上的优化更深。
好消息是 OpenClaw 的上下文引擎插件系统架构已经搭好了,接口完整,注册机制也在。如果能吸收 Claude Code 的分层压缩思路,即使只实现 Session Memory 和基于时间的清理两层,长会话的体验就会有质的飞跃。差的只是填充。