
网上把 OpenClaw 和 Claude Code 对立起来的文章很多。但这种对立是假的。
两个系统面对完全相同的根本挑战,走的方向也一样,只是给出了不同的架构解法。把两者的技术精髓放在一起看,你才能真正理解 AI Agent 架构的本质是什么。
所有 Agent 系统面对的四个根本挑战
不管你用什么框架,做什么场景的 Agent,都绕不开这四个问题。后面 OpenClaw 和 Claude Code 的所有设计决策,都是在回答这四个问题。
Context Window 有限。 语言模型能接受的信息量有上限。Agent 需要处理的信息——历史对话、工具输出、外部文档、任务状态——加在一起远超这个上限。怎么在有限的窗口里放最有价值的信息,是所有 Agent 架构的核心命题。
状态会丢失。 语言模型没有记忆,每次调用都从零开始。Agent 在对话里说“我记住了”,下次对话可能全忘了。怎么让状态真正持久化,不依赖模型的“记住”,是可靠运行的基础。
工具有风险。 Agent 能执行工具意味着它能真正改变外部世界——删文件、发邮件、调 API。一旦出错可能无法撤销。怎么在 Agent 自主执行的同时保持有效控制,是安全性的核心。
任务会失败。 复杂任务中间会出错、遇到意外、需要调整方向。Agent 如何在失败后恢复,决定了它能处理任务的复杂度上限。
OpenClaw 的技术精髓
精髓一:Agent 是配置集合,不是进程
很多人装好 OpenClaw 之后,想着“启动 Agent”、“停止 Agent”——这个直觉是错的。
OpenClaw 里的 Agent 根本不是一个可以启停的进程。它是一组文本文件:
~/.openclaw/agents/<agentId>/
├── SOUL.md # 价值观与判断原则
├── AGENTS.md # 行为规则与处理流程
├── IDENTITY.md # 名称与展示信息
└── TOOLS.md # 工具权限声明
真正一直在跑的只有网关(Gateway)——一个 Node.js 进程。当消息进来,网关读取对应 Agent 的配置文件,构建系统提示,调用语言模型,返回结果。Agent 本身只是“用什么规则响应请求”的声明。
为什么这样设计?
因为这个设计让 Agent 的修改成本趋近于零。改一行 SOUL.md,下一次对话立刻生效。不需要重新编译,不需要重启,不需要部署。配置即代码,文本即逻辑。
更深的含义是:Agent 的能力完全由语言定义,而不是由代码实现。 你想让 Agent 变成一个严格的审计员,还是一个发散的创意助手,只是文本的差异。这让非工程师也能真正“编程”一个 Agent。
精髓二:系统提示的精确构建——Context Engineering 的实践
这是 OpenClaw 最核心的技术,也是最容易被忽视的地方。
每次调用语言模型之前,OpenClaw 做的最关键一件事是:精确地决定系统提示里放什么。
系统提示不是固定的一段文字。它是动态组合的:
SOUL.md 全文(始终包含)
+ memory.md 里最相关的片段(RAG 检索,不是全部)
+ habit.md 的定期任务声明
+ 可用 Skills 的名称和路径(只有路径,不是内容)
+ 历史对话的压缩摘要(不是全文)
+ 用户当前的消息
每一条规则背后都有具体的逻辑:
memory.md 用 RAG 检索,而不是全部载入。
长期记忆会随着使用越来越多。如果每次都把 memory.md 全文塞进去,Context Window 很快就被记忆本身撑爆,真正需要处理的任务反而没有空间。RAG 的做法是:把 memory.md 切成小块,分别计算和当前任务的相关度,只取 top-k 最相关的片段放进系统提示。这样,无论记忆积累多少,每次消耗的 Context 是固定的。
Skills 只放路径,不放内容。
Skills 是 Agent 的工作 SOP,内容可能很长。但大多数对话根本用不到大多数 Skills。如果把所有 Skills 的全文都塞进系统提示,不仅浪费 Context,还会干扰模型的判断——它需要在大量无关信息里找到真正需要的那个 Skill。正确的做法是只告诉模型“有哪些 Skill 可用、在哪里找”,让模型判断需要哪个,需要的时候再去读取完整内容。把“知道有什么”和“真正用到它”分开,是 Context Engineering 的基本原则。
历史对话放压缩摘要,不放全文。
对话越来越长,全文放进去会挤掉当前任务需要的空间。OpenClaw 用递归压缩:当历史对话快要触顶,调用一次语言模型把旧的对话压缩成摘要,用摘要替换原文。这个过程可以多次执行,让 Agent 能长期运行而不爆掉。压缩是有损的,但损失的是细节,保留的是结论和关键决策——这正是长期任务里真正需要记住的东西。
精髓三:显式持久化——没写进文件就不算记住
OpenClaw 对“状态会丢失”这个问题的答案简单到有点粗暴:所有需要持久化的状态,必须显式写进文件。
这背后有一个机制需要理解:系统提示的内容(包括 memory.md)在 Context Compaction 过程中是不会被压缩的,因为它是每次对话的基础。但对话历史会被压缩,临时约定会消失。
所以规则只有一条:想让 Agent 永远记住的事,必须让它写进 memory.md。写进去了,每次对话都在。没写进去,压缩之后消失。
这个规则有一个著名的教训。一个 AI 安全研究员让 Agent 整理邮件,特别叮嘱“删邮件之前要经过我同意”。Agent 后来自己开始批量删邮件,完全不理会制止,最后研究员把插头拔掉。事后分析:那句“要经过我同意”只存在于对话里,历经一次 Compaction,消失了。Agent 不是不服从,是真的不记得有这条约定。
这个教训背后是一个架构原则:Agent 的约束必须存在于不会被压缩的地方,否则随时可能失效。
精髓四:程序级工具拦截——安全的正确实现方式
工具调用真正执行之前,OpenClaw 运行时会触发一个 tool_call 事件。扩展可以在这里修改参数、阻止执行、或者弹出人工确认。
为什么这个机制比“在提示词里告诉 Agent 不要做危险操作”可靠得多?
因为提示词可以被绕过。Prompt Injection 攻击的本质,是把恶意指令藏在 Agent 会读取的内容里——网页、文档、邮件。当 Agent 读到这些内容,语言模型可能把恶意指令当作正常任务执行。
程序拦截不会被语言绕过。无论语言模型输出什么,无论它相信什么理由,执行 rm -rf 之前必须人工确认这条规则,是写死在代码里的。
这是安全架构的基本原则:信任边界必须在程序层实现,不能依赖模型的“判断力”。 模型可能被欺骗,代码不会。
Claude Code 的技术精髓
精髓一:四个工具,而不是四百个
大多数 Agent 框架的设计思路是:预设越多越好。内置网络搜索、内置日历、内置发邮件……
Claude Code 底层(pi-mono)只给语言模型四个工具:读文件、写文件、编辑文件、执行 Shell 命令。
bash 是关键。 它能执行任意 Shell 命令,意味着:需要网络请求?写一段 Python 脚本,bash 执行它。需要解析 PDF?安装一个库,bash 跑起来。需要调用某个 API?写代码执行。
为什么极简比功能齐全更好?
预设工具的问题在于:工具的设计者不可能预见所有需求。当 Agent 需要一个没有预设的工具,它只能说“我做不到”。bash 工具把这个限制去掉了。Agent 需要什么,自己写代码实现。工具的边界是代码能做的一切,而不是设计者预见到的一切。
更重要的是:极简工具集让 Agent 的能力边界变得可预测。 你完全清楚它能做什么——就是 bash 能做的事。没有隐藏的功能,没有意外的副作用。
精髓二:Agent 自己写扩展自己用
建立在极简工具的基础上,Claude Code 走出了更远一步:让 Agent 给自己写扩展。
扩展是 TypeScript 模块,支持热重载——Agent 写完一段扩展代码,立刻生效,不用重启。这和 OpenClaw 的 Skills 有根本区别。Skills 是人写给 Agent 用的工作 SOP。这里是 Agent 自己识别自己的能力缺口,自己写代码填补,自己测试,自己用。
为什么这个设计重要?
因为它解决了一个经典的 Agent 局限:能力扩展依赖人的介入。每次 Agent 遇到新场景,都要等人来给它写新工具或新 Skills。当 Agent 能自己扩展自己,这个依赖消失了。它遇到新场景,分析需求,写代码,解决问题。能力的增长不需要外部供给。
精髓三:Subagent 机制——Context Window 的根本解法
面对“Context Window 有限”这个问题,OpenClaw 的答案是精确管理放什么进去。Claude Code 的答案更激进:把大任务分给多个子 Agent,让每个子 Agent 在自己独立的 Context 里工作,主 Agent 只看汇总结果。
来看一个具体的例子:让 Agent 分析一个有 50 个文件的代码库,找出所有安全漏洞。
如果主 Agent 自己做:
读文件一,分析,发现两个漏洞,记录。读文件二,分析……到文件二十的时候,文件一到十的内容已经在 Context 里堆了很多,Context Window 快撑爆了,Agent 开始遗忘早期的发现,结果质量下降。
如果用 Subagent:
主 Agent 把 50 个文件分成 10 组,生出 10 个子 Agent,每个子 Agent 分析 5 个文件,各自在独立的 Context 里工作。完成后,每个子 Agent 只返回一份简短的漏洞摘要。主 Agent 汇总 10 份摘要,Context 始终保持精简,结果质量不随任务规模下降。
这是 Context Engineering 的最高形态: 不是管理一个 Context,而是把任务分解,让每个 Context 只负责自己该做的事,主 Agent 只看各部分的结论。
关键约束:子 Agent 不能再生子 Agent。否则层层外包,最后没人真正做事。这个约束写死在程序里,不能被 Prompt 绕过——和 OpenClaw 的工具拦截是同样的设计思路:核心约束必须在程序层实现。
精髓四:Session Tree——非线性的任务历史
传统 Agent 的对话历史是一条线。出了问题,从头来过,或者在原有上下文上打补丁,越改越乱。Claude Code 的对话历史是一棵树。每一条记录都有 id 和 parentId,可以在历史的任意节点分支出去,形成新的路径,而不影响原来的主线。
这解决的是一个真实的工程问题: 复杂任务的执行不是线性的。你会需要探索不同方案,会需要在某个决策点回头,会需要在不破坏主线的情况下调试一个子问题。
树形结构让这一切成为可能:
- 发现主线走不通?从当前节点分支,试一条新路。
- 分支成功?把结论带回主线继续。
- 分支失败?直接丢弃,主线完好无损。
- 需要对比两个方案?从同一节点分出两个分支,各自跑完,对比结果。
所有历史都保留,所有分支都可以回溯。这不只是方便,这是对“任务会失败”问题的系统级回答:失败不是终点,是一个可以分支和回溯的节点。
对比与总结
AI Agent 架构没有标准答案,只有在具体约束下的最优解。OpenClaw 和 Claude Code 是目前回答同一批根本挑战最深刻的两个样本。
OpenClaw 更适合 长期运行、个性化强、需要人机紧密协作的场景 ——记忆持久化、行为可配置、安全边界清晰。
Claude Code 更适合 复杂工程任务、自主执行、边界明确的场景 ——自我扩展能力强、上下文管理更激进、子任务可并行。
但两者体现的架构思想是通用的:
- Context 必须被主动管理,不能任由它自然增长
- 状态持久化必须显式,不能依赖模型“记住”
- 安全约束必须在程序层,不能依赖提示词
- 复杂任务必须分解,不能让单个 Context 承担所有
这四条,是任何 Agent 系统设计都绕不过去的原则。
如果你想深入实践 AI Agent 开发,不妨将 OpenClaw 和 Claude Code 作为起点,在 云栈社区 的技术讨论板块,与更多开发者交流你在实际项目中遇到的架构挑战与解决方案。