跳转至

4. Comparison & Discussion

本节摘要

Claude Code 用模型解决State Management问题,OpenClaw 用工程解决State Management问题。 这个判断贯穿了两个框架在状态注入、丢弃、恢复、继承上的所有设计选择。本节不再逐维度罗列差异,而是提炼出最值得关注的几个核心分歧和一个重要共识。


最根本的分歧:状态住在哪

Claude Code 是单进程 CLI——启动进程就是开始会话,退出进程就是结束会话。对话历史是进程内的 messages[] 数组,Sub-agent 状态是进程内的 Map。这意味着它不需要序列化、不需要恢复、不需要处理数据损坏——所有关于持久化的复杂度被「进程即会话」这个设计选择一笔勾销。

OpenClaw 是 Gateway 架构——消息可能来自 Slack、Discord、Web 等不同渠道,两条消息之间可能间隔几小时,Gateway 进程随时可能重启。它必须把所有状态写到磁盘(JSONL transcript + SessionEntry JSON),每次 run 从磁盘恢复。这带来了一整套 Claude Code 不需要面对的问题:sanitizeSessionHistory(反序列化后校验修复)、原子写入(防崩溃损坏)、Gateway RPC 同步(磁盘与服务端的一致性)。

这个根本差异——内存优先 vs 磁盘优先——是后续所有设计选择的源头。


最精彩的分歧:怎么丢弃状态

Context 压缩是两个框架工程量最大的模块,也是State Management哲学差异体现得最淋漓尽致的地方。

Claude Code 的六层压缩是一个「渐进妥协」的过程。 它最珍视的资产是 Prompt Cache——静态系统提示跨组织共享缓存,每次命中都省钱省延迟。所以压缩的前三层(Time-Based / Cached / API MC)都在不破坏缓存的前提下尽量释放空间。只有到了 L4(Session Memory)才不得不重建 Context、让缓存失效。这种「能不动就不动」的渐进策略,本质上是在缓存命中率和可用空间之间做精细的 trade-off

OpenClaw 的五步压缩是一个「层层设防」的过程。 它不在乎缓存(Gateway 架构下没有稳定的缓存可言),但它极度在乎不丢信息。所以压缩的第一步不是压缩本身,而是 Memory Flush——先把重要信息写到磁盘上。压缩之后再补注入 AGENTS.md 中的 Session Startup 和 Red Lines——确保行为约束不被摘要吞掉。最后还保存检查点,支持回滚。这是典型的防御性编程:每一步都在防范前一步可能出的问题。

一个有意思的观察:Claude Code 压缩失败时的策略是熔断(连续 3 次失败后停止尝试,源码注释说不加熔断器全球每天浪费 25 万次 API 调用);OpenClaw 的策略是兜底(模型回退 + 检查点回滚)。前者是「止损」思维,后者是「总有办法」思维。


最意外的分歧:状态注入的通道数量

Claude Code 有三条状态注入通道:System Prompt(会话级缓存)、Tool Definitions(偶尔变化)、以及 Attachment 系统(每 turn 重算 30+ 类动态 Context)。Attachment 系统是 Claude Code State Management中最独特的设计——它以 <system-reminder> 标签包裹,合并进 user message,承载了 Skill 列表、文件变更、工具 Delta、任务提醒、token 用量等几乎所有需要每 turn 更新的信息。

OpenClaw 没有等价机制。它的动态信息主要通过 Bootstrap 文件(启动时加载)和工具结果回灌来传递。这意味着 OpenClaw 的 LLM 在 turn 之间感知到的「世界变化」比 Claude Code 少——比如文件被其他工具修改了,Claude Code 通过 changed_files attachment 主动通知模型,OpenClaw 需要模型自己去检查。

这个差异让我意识到:State Management不仅是「管理什么信息」的问题,也是「用几条通道、以什么频率送达」的问题。 Claude Code 的三通道设计让不同变化频率的信息走不同的路径——稳定的走缓存通道,频繁变化的走 Attachment 通道——这比把所有信息都塞进同一个通道更精细。


最实用的分歧:Memory 怎么召回

Claude Code 每个 turn 自动用 Sonnet 并行预取最相关的 5 个Memory 文件——100% 召回率,不依赖模型「记得要搜索」。代价是每 turn 一次 Sonnet 调用,但对 Anthropic 来说边际成本极低。

OpenClaw 的 memory_search 是一个被动工具——LLM 必须主动决定调用它。如果模型没意识到需要检索 Memory,就不会触发。这在成本上更友好(按需调用),但引入了「模型可能忘记搜索」的风险。

这反映了一个更深层的哲学差异:Claude Code 信任模型的判断能力(用 Sonnet 选 Memory、用 YOLO 分类器判权限),因此愿意在State Management流程中嵌入更多的模型调用;OpenClaw 信任配置和规则的可预测性(用策略管道过滤工具、用显式工具调用检索 Memory),因此偏好确定性的工程方案。


最值得关注的共识

两个独立演化的框架在 Skill 暴露机制上几乎完全一致——都用 SKILL.md(Markdown + YAML frontmatter)定义、都用 <available_skills> XML 列出摘要、都让 LLM 根据 description 判断后通过 Read 工具按需加载全文、都没有用 Embedding/RAG 做 Skill 选择。

这种趋同不是巧合,而是约束条件限定了解空间:Skill 数量通常在 10-50 个,1% Context 预算(~8K 字符)足以列出全部摘要;LLM 理解自然语言 description 的能力已经足够好,不需要向量检索;Markdown 文件人类可读可编辑,天然适合版本控制。在这些约束下,当前的方案已经是一个收敛解

类似的共识还包括:压缩都用 LLM 生成摘要(目前没有更好的有损压缩方案)、工具结果都作为消息回灌(Chat API 标准范式)、MCP 都用标准 SDK。


总结

回到开头那句话:Claude Code 用模型解决问题,OpenClaw 用工程解决问题。

Claude Code 能用 Sonnet 选 Memory、用 YOLO 判权限、用 Attachment 每 turn 注入 30+ 类动态Context,因为它是 Anthropic 自家产品,调用模型的边际成本极低,且单用户 CLI 场景下这些额外调用带来的延迟可以接受。

OpenClaw 用 7 层策略管道过滤工具、用 Memory Flush + 检查点保护压缩安全、用磁盘持久化 + 原子写入保证可恢复,因为它服务多模型多渠道的多用户场景,每次额外的模型调用都是成本,而可预测性和可审计性比灵活性更重要。

两者都不是「更好」的方案——它们是在不同约束条件下的最优解。理解这些约束条件,比记住具体的设计选择更有价值。