OpenClaw 设计解析(一):项目概览与整体架构

最近 OpenClaw 多次刷屏,有人称赞也有人吐槽,那么我也来一探究竟,从源码设计角度,看看到底是个怎么回事。学习其好的设计,对于令人诟病的安全问题,也尝试看看有没有解决方案,或者更好的最佳实践。

首篇这篇文章将尝试回答四个问题:

  1. OpenClaw 从代码结构上到底是什么
  2. 一条消息或一次任务是怎么穿过整个系统的
  3. 这套架构背后的主要工程取舍是什么
  4. 后面几篇文章分别展开哪一层

1. OpenClaw 不是单个 Agent,而是一套本地优先的 Agent Gateway

如果只看名字,很容易把 OpenClaw 理解成“一个聊天机器人”或者“一个 coding agent”。
可以把它描述成:

OpenClaw 是一套运行在自有设备上的 Agent Gateway。它把多种入口、多种通道、多种模型与工具执行统一到一个控制平面里。

这个定义里有 4 个关键词:

  • Gateway:它不是把每个通道、每个客户端、每个工具都做成独立小程序,而是让大多数能力汇聚到同一个运行时核心
  • Agent:它不只是收消息、回消息;中间有完整的 LLM tool loop、会话持久化、上下文治理和长期记忆
  • 本地优先VISION.md 的主线很明确:运行在自己的设备、自己的通道、自己的规则之下
  • 单操作员信任边界SECURITY.md 默认模型是 personal assistant / trusted operator,不是多租户强隔离平台

先把边界列出来:

  • 不是托管式 SaaS 平台
  • 不是把 session 当成租户边界的共享总线
  • 它也不是只有一个 CLI 命令入口的单体工具

可以把它理解成:一个统一运行时,承接多入口、多通道、多工具、多种上下文来源。

2. 先看整体:系统是怎么分层的

如果把当前仓库压缩成一张图,大致可以画成下面这样:

flowchart TB subgraph Entry["入口层"] E1["CLI / TUI"] E2["macOS / iOS / Android / Web UI"] E3["Telegram / Slack / Discord / WhatsApp / ..."] E4["Webhook / Cron / Heartbeat / System Events"] end E1 --> G E2 --> G E3 --> G E4 --> G G["Gateway / 控制平面<br/>HTTP + WebSocket<br/>认证 · RPC · 队列 · session 路由"] G --> C["多通道接口<br/>ChannelPlugin · 身份归一化 · access control"] G --> A["Agent 运行时<br/>Pi session · tool loop · event stream"] G --> P["插件注册面<br/>manifest · PluginRegistry · hooks · commands"] C --> A P --> A A --> M["上下文与记忆<br/>workspace files · transcript · pruning · compaction · memory plugin"] A --> T["工具层<br/>fs / exec / browser / channel tools / plugin tools"] A --> U["媒体管线<br/>image / audio / video / link understanding"] A --> L["模型 Provider"] T --> X["宿主机或沙箱"] U --> L S["安全层(贯穿各层)<br/>dangerous tool policy · sandbox · pairing · audit · external content"] -.-> G S -.-> A S -.-> T S -.-> C

这张图里更需要注意的不是“模块很多”,而是 职责是分层的

  • 入口层负责把外部世界接进来
  • Gateway负责统一控制面
  • Agent 运行时负责真正的推理与执行循环
  • 插件、记忆、安全不是外围附件,而是贯穿主流程的能力

换句话说,OpenClaw 的复杂度不只是“支持很多功能”,而是:

它把“接入、路由、执行、记忆、扩展、安全”五件事放进了同一个系统里。

3. 一条消息是怎么穿过整个系统的

如果从运行时角度看,一次用户请求或一次系统触发,大致会经历下面这条路径:

sequenceDiagram participant I as 入口<br/>通道 / CLI / 定时器 participant G as Gateway participant R as 路由与 session participant A as Agent 运行时 participant T as 工具 / 模型 participant M as transcript / memory I->>G: 入站消息或触发事件 G->>R: 解析 sessionKey、权限与目标 agent R->>A: 加载 workspace、上下文、工具与插件钩子 A->>T: 发起 prompt / tool loop T-->>A: 模型回复 / tool result A->>M: 写入 transcript / memory / 索引 A-->>G: 最终回复或运行事件 G-->>I: 回写到原入口

顺着这条链路看,可以看到 3 件事:

第一,所有入口最终都会汇聚到同一个 Agent 执行面。

  • 用户在 Telegram 发来一条消息
  • 本地 CLI 执行一次 openclaw agent
  • Cron 触发一个计划任务
  • Heartbeat 定时唤醒某个 agent

这些入口看上去差异很大,但在运行时最后都会落到类似的执行路径: 确定 session → 组装上下文 → 调模型 → 执行工具 → 写回会话。

第二,OpenClaw 的核心不是“发请求给模型”,而是“维护一次可持续的回合执行”。

后面的 05-Agent运行时06-上下文记忆 其实都在讲这件事:

  • Pi 负责 session、tool loop、transcript、auto-compaction
  • OpenClaw 负责工具装配、历史裁剪、memory flush、长期记忆召回

这里说的不是单次 chat completion,而是一个带状态的执行回路

第三,系统内部很多层都是为“同一个回合”服务的。

例如:

  • 通道层负责把不同平台消息归一化
  • Gateway 负责把它们映射到某个 session
  • Agent 运行时负责真正执行
  • memory 和 transcript 负责把这次执行留存下来
  • 安全层负责限制这次执行的能力范围

所以 OpenClaw 的代码结构会比“普通聊天机器人”更厚。

4. 这套系统主要由哪几个子系统组成

当前系列下的其他文章,基本把 OpenClaw 拆成了 7 个关键子系统。

子系统 它解决的问题 这一层主要内容 对应文章
CLI 命令怎么启动、路由、诊断和维护 三层 fast path、懒加载、doctor 自动修复 02-CLI
Gateway 统一控制平面怎么工作 HTTP + WebSocket、认证、lane 队列、会话缓存 03-Gateway
多通道 不同消息平台怎么统一接入 ChannelPlugin、身份归一化、7 层绑定路由 04-多通道架构
Agent 运行时 LLM 和工具循环怎么跑 Pi 集成、工具装配、策略管线、事件流、subagent 05-Agent运行时
上下文记忆 session、上下文窗口、长期记忆怎么协同 transcript、pruning、compaction、memory plugin 06-上下文记忆
插件系统 外部能力怎么接入核心运行时 manifest-first、PluginRegistry、Hook、slot 07-插件系统
安全模型 系统默认防线和边界在哪里 trusted operator、dangerous tools、sandbox、审计 08-安全模型

从这个表里也能看出:

OpenClaw 不是围绕“模型调用”展开的,而是围绕“一个长期运行的本地 Agent 系统”展开的。

模型只是其中一层;控制面、上下文、通道、插件和安全同样是主角。

5. 这套架构背后的几个关键取舍

如果只看功能列表,很容易把 OpenClaw 理解成“大而全”。
从源码和系列文章看,它更接近几组明确的工程取舍。

5.1 用 Gateway 统一控制面,而不是让每个入口各自跑逻辑

这样做的收益很直接:

  • 客户端、消息通道、Webhook、Cron 可以复用同一套会话与执行逻辑
  • 认证、审批、日志、审计、队列都能集中处理

代价也同样明显:

  • 很多职责会汇聚到同一个运行时核心
  • Gateway 会同时背负网络入口、控制平面和任务调度的复杂度

所以 03-Gateway 里重点讲的不是“怎么开一个 WebSocket 服务”,而是为什么它要成为全系统的中枢

5.2 用统一接口处理平台差异,但不假装这些平台完全一样

04-多通道架构 里主要在讲一件事:
OpenClaw 并没有追求“所有通道完全同构”,而是提供了一层 ChannelPlugin 接口 + 能力声明

收益是:

  • Telegram、Slack、Discord、WhatsApp、Signal 等都能接入同一个系统
  • 路由、身份映射、权限控制可以统一处理

代价是:

  • 每个平台的线程、消息模型、配对方式都还需要单独适配
  • 某些平台没有官方 API 时,只能走更脆弱的实现路径

也就是说,这套接口是为了降低接入成本,不是为了抹平所有平台差异。

5.3 把 Pi 当执行引擎,把 OpenClaw 当策略层

05-Agent运行时06-上下文记忆 里有一个共同点:它们都在强调分工:

  • Pi 负责 session、tool loop、transcript persistence、auto-compaction
  • OpenClaw 负责模型解析、工具装配、上下文裁剪、memory flush、事件消费

这类分层的收益是:

  • OpenClaw 不需要自己重写一套 Agent 引擎
  • 上层仍然可以深度改造 prompt、history、tool policy 和 compaction 策略

代价是:

  • 运行时行为要同时理解 Pi 和 OpenClaw 两层
  • 某些上下文问题会表现为“Pi 做引擎,OpenClaw 做补丁式治理”

读代码时,如果没先看清两层职责边界,就容易迷路。

5.4 核心保持精简,把可选能力外移到插件

这点在 VISION.md07-插件系统 里都很明确:

  • core 尽量 lean
  • 通道、记忆、认证桥接、工具增强、后台服务都尽量走插件

收益:

  • 核心代码不必无限膨胀
  • 新能力可以按插件节奏演进
  • memory 这类能力可以替换实现

代价:

  • 插件不是低权限沙盒,而是 trusted code
  • 系统的真实能力边界,不只取决于 core,也取决于装了什么插件

所以插件系统的重点不是“动态 import TypeScript”,而是如何在不把核心做成一团的前提下,给运行时持续加能力

5.5 安全目标是“分层防护”,不是“多租户强隔离”

这是第一篇最需要先讲清楚的边界。

SECURITY.md08-安全模型 都明确说明:

  • 默认信任模型是 personal assistant / trusted operator
  • sessionKey 不是租户边界
  • sandbox 是可选的,而且默认关闭
  • prompt injection 风险没有被“解决”,只是被多层缓解

这带来一个很现实的判断:

  • 如果把它用于个人助手、同一信任边界内的小团队,它的设计是自洽的
  • 如果把它直接当成 adversarial multi-tenant 平台,就会高估它的隔离能力

这里可以把 OpenClaw 描述成:

它实现的是围绕单操作员边界的分层防护,而不是面向对抗性多租户场景的强隔离系统。

6. 系列文章该怎么读

如果把当前系列下的 8 篇文章连起来,它们其实对应的是同一张图的不同部分:

flowchart TB A["01 整体"] subgraph Main["主阅读链"] direction LR B["02 CLI"] --> C["03 Gateway"] --> D["04 多通道"] --> E["05 Agent 运行时"] --> F["06 上下文记忆"] end subgraph Cross["补充主题"] direction LR G["07 插件系统"] --- H["08 安全模型"] end A --> B A -.-> G A -.-> H

如果你想按“系统是怎么跑起来的”顺序读,可以这样走:

  1. 02-CLI
    • 先看本地入口和命令调度
  2. 03-Gateway
    • 再看控制平面和会话管理
  3. 04-多通道架构
    • 然后看消息如何从外部平台进入系统
  4. 05-Agent运行时
    • 再看真正的 LLM + tool loop
  5. 06-上下文记忆
    • 再看这个 loop 如何跨回合延续
  6. 07-插件系统
    • 最后看能力是怎么持续长出来的
  7. 08-安全模型
    • 再回头看系统边界和风险控制

如果你更关心某个专题,也可以直接跳转:

  • 想看“为什么命令行很多但启动不慢” → 02-CLI
  • 想看“为什么一个 Gateway 能接这么多入口” → 03-Gateway
  • 想看“为什么 WhatsApp、Telegram、Slack 能用一套接口” → 04-多通道架构
  • 想看“Agent 为什么能持续运行,不只是单轮问答” → 05-Agent运行时
  • 想看“上下文记忆到底怎么设计,不只是一个 RAG” → 06-上下文记忆
  • 想看“插件为什么不只是动态 import” → 07-插件系统
  • 想看“这套设计的安全边界到底在哪” → 08-安全模型

7. 读这个仓库时,可以先这样理解

简单说,就是:

OpenClaw 不是“一个会调模型的程序”,而是“一个把入口、路由、执行、记忆、扩展和安全绑在一起的本地 Agent 系统”。

这句话展开以后,对应 5 个阅读关键词:

  • 控制平面
    • Gateway 统一承接入口、认证、RPC、队列和会话
  • 执行引擎
    • Pi 负责会话循环,OpenClaw 负责策略和装配
  • 状态延续
    • transcript、pruning、compaction、memory plugin 共同决定上下文
  • 能力外置
    • 通道、记忆、认证桥接、工具增强大量通过插件接入
  • 边界意识
    • 安全前提是单操作员模型,而不是默认多租户隔离

带着这 5 个关键词再看后面的代码,会更容易看出主线。

8. 小结

作为系列第一篇,这里不想把 OpenClaw 写成“功能很多”的目录清单,而更想把它压缩成一个技术判断:

OpenClaw 不只是某一个单独模块,而是把多入口接入、统一控制面、Agent 执行循环、上下文治理、插件扩展和安全边界放进了同一个可持续运行的系统里。

后面的文章拆成 7 个子题,也是沿着这张图展开的:
每一篇其实都在解释这张整体图里的一个部分,而不是孤立地解释某个文件或某个函数。

下一篇从最外层入口开始,先看 02-CLI
为什么一个有 40+ 命令的 CLI,仍然要花很多心思在 fast path、懒加载和重解析上。