整体架构流程
OpenClaw 的请求处理链条分为六个阶段:
- Channel Adapter:处理不同消息渠道的输入,标准化消息格式、提取附件
- Gateway Server:核心协调器,将消息路由到正确的会话
- Agent Runner:选择模型、组装系统提示词、管理上下文窗口
- LLM API Call:流式调用,支持多提供商抽象
- Agentic Loop:工具调用循环,直到返回最终文本或达到最大轮次(默认约 20 轮)
- Response Path:将响应返回给用户,持久化会话
整条链路的设计目标很明确:每一层做好自己的事,向下传递标准化的数据。
Lane-based Command Queue:重新思考并发
多智能体场景下,传统的 async/await 方式会带来一堆麻烦——日志交错难以阅读、共享状态的竞态条件、调试时根本理不清执行顺序。
OpenClaw 的解决方案是引入 Lane(通道)抽象:
- 每个会话有专属 Lane
- 默认串行执行,只有显式标记的低风险任务才允许并行(比如 cron jobs)
- 心智模型从「需要锁什么?」转变为「什么可以安全并行?」
这个设计思路和 Cognition 在「Don't Build Multi-Agents」一文中的观点高度一致:序列化应该是默认架构,而不是出了问题后的补救措施。对于独立开发者来说,这个原则尤其重要——先让系统跑通,再考虑哪里值得并行优化。
内存系统:简单到让人意外
OpenClaw 的内存系统没有用任何花哨的方案:
存储层:
- 会话历史:JSONL 文件(每行一个 JSON 对象)
- 长期记忆:Markdown 文件(
MEMORY.md或memory/目录)
检索层:
- 向量搜索:SQLite
- 关键词搜索:FTS5(SQLite 扩展)
- 混合搜索策略:语义匹配 + 精确匹配
写入方式:
- 没有专门的 memory-write API
- 智能体直接使用标准文件写入工具写 Markdown
几个值得注意的特点:没有记忆合并,没有定期压缩,旧记忆与新记忆权重相等(不做遗忘曲线),新会话开始时自动生成上一次对话的摘要。
这套方案的好处是实现成本极低,调试也方便——打开文件就能看到智能体"记住了什么"。不需要额外维护一套复杂的记忆管理系统。
浏览器交互:语义快照而非截图
这可能是整个架构中最有洞见的设计。OpenClaw 不用截图来理解网页,而是使用可访问性树(ARIA)的文本表示:
- button "Sign In" [ref=1]
- textbox "Email" [ref=2]
- textbox "Password" [ref=3]
- link "Forgot password?" [ref=4]
- heading "Welcome back"
对比一下两种方案的差距:
| 截图方案 | 语义快照 | |
|---|---|---|
| 大小 | ~5 MB | <50 KB |
| Token 成本 | 高(视觉模型) | 极低 |
| 元素定位 | 需要坐标计算 | 直接引用 ref |
核心洞见很简洁:浏览网页本质上不是视觉任务。 对于大多数自动化场景来说,页面的语义结构比像素信息更有用,成本也低得多。
安全机制
采用白名单 + 黑名单的组合策略:
白名单(用户可配置):
{
"agents": {
"main": {
"allowlist": [
{ "pattern": "/usr/bin/npm", "lastUsedAt": 1706644800 }
]
}
}
}
预批准的安全命令包括:jq、grep、cut、sort、head、tail 等。
黑名单阻止的危险构造:
- 命令替换:
$(...) - 重定向:
> - 链式执行:
||、&&(部分情况) - 子 shell:
(...)
设计哲学是:给予用户所允许的最大自主权。不是一刀切地禁止,而是让用户自己定义安全边界。
其他值得关注的细节
动态系统提示词: 不是静态模板,而是根据可用工具、技能、内存召回、用户身份、时区等动态构建。这意味着同一个 Agent 在不同上下文下会表现出不同的能力边界。
子智能体: 智能体可以生成子智能体(但子智能体不能再向下生成),通过 session_send 通信,父智能体可以轮询子智能体状态。只允许一层嵌套,这个限制很务实——避免了递归生成导致的失控。
上下文压缩: 上下文接近限制时,系统会将重要事实保存到内存,然后对历史进行分块摘要、合并为连贯摘要、替换旧消息。这保证了长对话不会因为上下文溢出而丢失关键信息。
写在最后
OpenClaw 的架构给出了一个很实在的参考:不追求复杂的分布式设计,用 JSONL + Markdown + SQLite 就能撑起一套可用的 Agent 系统。对于想搭建自己 Agent 工作流的开发者,"串行优先、语义抽象、极简存储"这三条原则值得在动手之前先想清楚。比起一开始就设计一套完美的并发架构,不如先让单线程跑通,再根据实际瓶颈决定哪里需要优化。