整体架构流程

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.mdmemory/ 目录)

检索层:

  • 向量搜索: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 }
      ]
    }
  }
}

预批准的安全命令包括:jqgrepcutsortheadtail 等。

黑名单阻止的危险构造:

  • 命令替换:$(...)
  • 重定向:>
  • 链式执行:||&&(部分情况)
  • 子 shell:(...)

设计哲学是:给予用户所允许的最大自主权。不是一刀切地禁止,而是让用户自己定义安全边界。

其他值得关注的细节

动态系统提示词: 不是静态模板,而是根据可用工具、技能、内存召回、用户身份、时区等动态构建。这意味着同一个 Agent 在不同上下文下会表现出不同的能力边界。

子智能体: 智能体可以生成子智能体(但子智能体不能再向下生成),通过 session_send 通信,父智能体可以轮询子智能体状态。只允许一层嵌套,这个限制很务实——避免了递归生成导致的失控。

上下文压缩: 上下文接近限制时,系统会将重要事实保存到内存,然后对历史进行分块摘要、合并为连贯摘要、替换旧消息。这保证了长对话不会因为上下文溢出而丢失关键信息。

写在最后

OpenClaw 的架构给出了一个很实在的参考:不追求复杂的分布式设计,用 JSONL + Markdown + SQLite 就能撑起一套可用的 Agent 系统。对于想搭建自己 Agent 工作流的开发者,"串行优先、语义抽象、极简存储"这三条原则值得在动手之前先想清楚。比起一开始就设计一套完美的并发架构,不如先让单线程跑通,再根据实际瓶颈决定哪里需要优化。