10 · 设计复盘:OpenClaw 为什么这样设计
把 Gateway、Agent Loop、Workspace、Memory、Session、Channel、Automation 与 Security 收束成一张架构图。
前 9 篇讲的是零件。这一篇讲整机。
OpenClaw 的核心不是“更会聊天”,而是把一个 AI Agent 放进可运行、可审计、可限制、可恢复的本地系统里。它用 Gateway 管入口,用 Session 管当前上下文,用 Workspace 管长期工作环境,用 Memory 管跨会话事实,用 Tool policy 和 Sandbox 管能力边界,用 Heartbeat / Cron / Webhooks 把时间和外部事件接进来。
这套设计的底层目标很朴素:
让 Agent 能长期运行,但仍然可理解;让 Agent 能做事,但仍然可限制;让 Agent 能记住你,但不制造隐藏状态。
1. 一张图看完整系统
flowchart LR
U[User / external system] --> C[Channel / Webhook / CLI]
C --> G[Gateway]
G --> R[Routing]
R --> S[Session key]
S --> L[Agent Loop]
W[Workspace files] --> X[Context assembly]
M[Memory files + search] --> X
X --> L
L --> P[Model]
P --> T[Tools]
TP[Tool policy] --> T
SB[Sandbox / elevated] --> T
T --> L
L --> O[Reply / persistence]
O --> C
HB[Heartbeat] --> G
CR[Cron] --> G
BK[Background tasks ledger] --> G
按官方文档拆开:
| 模块 | 官方定位 | 复盘时看什么 |
|---|---|---|
| Gateway | 长期运行的控制面,维护消息平台连接,提供 typed WebSocket API,默认监听 127.0.0.1:18789 | 入口和控制面是否集中可审计 |
| Channel | 入站消息和出站投递,模型不选择 channel | 路由是否确定 |
| Session key | 决定消息进入哪段上下文,也决定并发 lane 和部分运行姿态 | 是否串上下文 |
| Agent Loop | intake、context assembly、model inference、tool execution、streaming replies、persistence | 一次 run 是否可观察 |
| Workspace | Agent 的工作目录和人格/指令文件所在处 | 不要误当成硬沙箱 |
| Memory | workspace 里的 Markdown 文件和索引 | 不要误当成模型隐藏状态 |
| Tool policy | 决定哪些工具能被调用 | 能力边界是否明确 |
| Sandbox | 决定工具在哪里运行 | 运行环境是否隔离 |
| Elevated | sandboxed exec 的出沙箱机制,只影响 exec | 是否存在高风险逃逸口 |
| Heartbeat / Cron / Webhooks | 三类不同触发机制 | 时间和外部事件是否分清 |
| Tasks | 后台工作台账 | 不要误当成调度器 |
2. 系统不变量
理解 OpenClaw,先记这几条不变量:
- Gateway 是控制面:Messaging channels、Control UI、CLI、Nodes、WebChat 都围绕 Gateway;clients 和 nodes 通过 WebSocket 接入。不要把某个聊天渠道当成系统核心。
- Agent Loop 按 session 串行:一次 run 是 intake -> context assembly -> model inference -> tool execution -> streaming replies -> persistence。同一 session 要避免互踩。
- Workspace 是工作环境:工具相对路径以 workspace 为默认 cwd。Workspace 不是安全边界。
- Memory 没有隐藏层:模型只“记得”写入磁盘的内容,memory search 只是帮它检索材料。不要以为模型自动保留所有历史。
- Context 不是 Memory:Context 是本次 run 发给模型的全部输入,受窗口限制。不是存了 memory 就等于本轮一定看见。
- Security 默认是个人 operator boundary:shared Gateway 不等于敌对多租户安全边界。陌生用户或客户要拆 Gateway、credentials、OS user 或 host。
OpenClaw 的设计不是把 AI 变神秘,而是把每次运行拆成可解释的控制面、上下文、工具和持久化链路。
3. 取舍一:长驻 Gateway,而不是每个平台各跑一套
OpenClaw 选择单个长期运行的 Gateway 来管理平台连接。
得到的是:
- WhatsApp、Telegram、Slack、Discord、Signal、iMessage、WebChat 等入口统一接入。
- CLI、macOS app、web UI、automations 走同一套 Gateway API。
- 健康状态、presence、heartbeat、cron、agent run 都能在一个控制面观察。
付出的代价是:
- Gateway 是关键进程,挂了就影响所有 channel。
- 配置和日志集中在
~/.openclaw,权限管理必须严谨。 - 非 loopback 暴露会扩大攻击面。
适用边界很简单:个人助理、小团队、单 operator boundary 适合共享一个 Gateway;敌对多租户或客户共享 runtime 时应该拆 Gateway。
4. 取舍二:嵌入式 Agent Loop,而不是黑盒外包
OpenClaw 不是简单把消息转给一个外部聊天 API。它有自己的 embedded agent runtime 和 agent loop。
这让 OpenClaw 能控制:
- session resolution;
- model 和 auth profile 选择;
- skills snapshot;
- prompt assembly;
- tool execution;
- streaming;
- compaction retry;
- transcript persistence;
- hooks;
- timeout 和 cancellation。
得到的是可观察、可插拔、可约束。代价是系统概念变多:Agent Loop、Session、Context、Tool policy、Hooks 都需要理解。
这个取舍的实际意义:
OpenClaw 不是“把消息发给模型”,而是“把一次模型运行纳入本地 runtime 管理”。
5. 取舍三:Workspace 文件,而不是隐藏配置面板
Workspace 里放的是 Agent 可读、可修改、可迁移的工作材料:
| 文件/目录 | 放什么 | 不放什么 |
|---|---|---|
AGENTS.md | 操作规则和记忆使用方式 | persona 细节 |
SOUL.md | persona、边界、语气 | 工具授权 |
USER.md | 用户信息 | 凭据 |
IDENTITY.md | Agent 名字和身份 | 运行配置 |
TOOLS.md | 工具使用约定 | 工具是否可用的硬授权 |
HEARTBEAT.md | 心跳检查清单 | 长脚本和 secrets |
BOOT.md | Gateway startup 时可运行的短清单 | 长期记忆 |
BOOTSTRAP.md | 首次启动 ritual | 常驻规则 |
memory/ | daily notes | raw chat dump |
MEMORY.md | curated long-term memory | 临时噪音 |
skills/ | workspace highest-precedence skills | 全局 managed skills |
得到的是透明和可迁移:
- 读文件就能看到 Agent 的规则和记忆。
- 私有 git repo 就能做备份和回滚。
- 迁移 workspace 比迁移数据库更直观。
代价是:
- Workspace 必须当作私密记忆处理。
- 不该把 secrets、raw chat dumps、
~/.openclaw里的配置和 credentials 提交进去。 - Workspace 不是 sandbox,安全隔离要另配。
6. 取舍四:磁盘 Memory,而不是模型隐藏状态
OpenClaw 的长期记忆不是“模型自己会记住”,而是写入 workspace 文件。
官方 Memory 体系的关键件包括:
MEMORY.md:durable facts、preferences、decisions。memory/YYYY-MM-DD.md:daily notes。DREAMS.md:optional review diary and dreaming summaries。memory_search:semantic + keyword retrieval。memory_get:exact file / line range read。- memory flush:compaction 前的 silent turn。
得到的是:
- 人能检查、编辑、删除。
- Git 能追踪记忆变化。
- Memory 和 Context 分离,降低“当前窗口塞爆”的风险。
代价是:
- Agent 必须真的把重要信息写入文件。
- Memory 质量取决于写入和整理。
- 需要检索时要用
memory_search或结构化 wiki 插件,而不是假设所有历史自动可见。
正确心智模型:
Context 是现在看见什么;Memory 是以后还能找回什么。
7. 取舍五:确定性路由,而不是 AI 自己分发
Channel Routing 文档强调:模型不选择 channel,host config 决定路由。
多 Agent 路由也类似:Exact peer、thread parent、guild roles、guild、team、account、channel、default agent,按固定顺序匹配。
得到的是:
- 消息不会因为模型判断失误发给错误 Agent。
- 审计时可以从配置倒推消息流向。
- 安全规则能和路由规则绑定。
代价是:
- 需要配置 bindings。
- 用户要知道在哪个 channel 或 thread 找哪个 Agent。
- 配错路由时,系统会稳定地错,需要人修配置。
这就是 OpenClaw 的一个核心立场:
AI 负责生成内容,规则负责系统秩序。
8. 取舍六:Session 生命周期,而不是无限聊天
Session 管的是当前对话桶。它有 sessionKey 和当前 sessionId,transcript 以 JSONL 存在磁盘。
生命周期规则包括:
- Daily reset 默认在 Gateway host 本地时间凌晨 4 点后换新 session。
- Idle reset 可选。
/new和/reset手动换新 session。- Daily 和 idle 同时配置时,先到期的生效。
- 旧 transcript 不等于删除,memory 不等于 reset。
得到的是:
- 上下文不会无限增长。
- transcript 和当前运行状态分开。
- compaction、pruning、session cleanup 有明确对象。
代价是:
- 新手会误以为 reset 等于失忆。
- 重要事实必须进入 memory 或 workspace 文件,不能只停留在旧 session 里。
9. 取舍七:Context 有预算,而不是全量塞进去
Context 受模型窗口限制,OpenClaw 要构建 system prompt、注入 workspace files、带 conversation history、工具结果和附件。
为了不让 prompt 失控,OpenClaw 提供:
/status看窗口占用;/context list看注入内容;/context detail看更细的大小贡献;- compaction 总结长对话;
- pruning 从本次模型输入里移除旧工具结果,但不改 transcript;
- context engine 插件接口。
得到的是可控成本和可解释的上下文组成。
代价是你不能说“Agent 应该看到所有东西”。它只能看到这次 run 被装进 context 的东西。
10. 取舍八:Heartbeat、Cron、Webhook 分开
OpenClaw 没把所有自动化都塞进一个“任务系统”。
三者边界:
| 机制 | 边界 | 适合什么 |
|---|---|---|
| Heartbeat | 周期性主会话 turn | inbox、calendar、notifications 这类近似时间检查 |
| Cron | Gateway scheduler | 精确时间、一次性提醒、isolated background run |
| Webhook | 外部 HTTP 事件入口 | GitHub、监控、邮件推送这类外部系统触发 |
Tasks 只负责记录后台工作:Cron executions、subagents、ACP runs、CLI operations 会创建 Task;Heartbeat、普通聊天、直接 slash command 不会因为“发生了”就自动变成 Task。
得到的是概念清晰。代价是新手一开始要分清“触发机制”和“台账”。
11. 取舍九:Sandbox、Tool policy、Elevated 分开
这三个词必须分清:
- Sandbox 控制工具在哪里运行。
- Tool policy 控制哪些工具能被调用。
- Elevated 控制 sandboxed exec 是否能出沙箱到 host。
官方规则里,deny 永远优先,allow 非空时其他工具都 blocked。/exec 不能覆盖被 deny 的 exec。Elevated 不授予额外工具,也不覆盖 tool allow/deny。
得到的是精准控制:
- 私人 Agent 可以 full access。
- 家庭/团队 Agent 可以 sandbox + read-only。
- 公共 Agent 可以 no filesystem/shell。
代价是配置复杂。但安全领域里,复杂度比“所有人都拿 root 权限”更可接受。
12. 取舍十:多 Agent 是边界,不只是分工
多 Agent 不是把一个人拆成多个聊天窗口。官方多 Agent 模型里,一个 Agent 是 workspace、agentDir、session store、模型/工具/权限配置的 scope。
拆 Agent 的理由:
- persona 不同;
- workspace 不同;
- credentials 不同;
- sandbox/tool policy 不同;
- session store 不同;
- channel bindings 不同。
不该拆的理由:
- 只是同一个 Agent 的临时后台任务;
- 只是想并行分析一个问题;
- 只是想让主 Agent 派一个子任务。
后者更适合 sub-agent 或 Cron isolated run。
13. 取舍十一:Hooks 和 Plugins 开扩展口
OpenClaw 有两类 hook:Internal hooks 位于 Gateway 事件脚本层,典型例子是 /new、/reset、/stop、agent:bootstrap、gateway:startup;Plugin hooks 位于 Agent/tool/gateway pipeline 内部扩展点,典型例子是 before_tool_call、before_prompt_build。
得到的是可扩展:
- reset 时写 memory;
- bootstrap 前注入文件;
- tool call 前做 policy;
- plugin install 前做扫描;
- message dispatch 前后做处理。
代价是 hook/plugin 代码也进入 trust boundary。安装 plugin 等于给 Gateway 增加代码能力,不能当普通配置看。
14. 什么时候应该重新设计
OpenClaw 当前设计很适合个人助理、工作室、小团队、自托管自动化。约束变了,取舍也要变。
需要拆更硬边界的场景:
- 陌生用户共享一个 Agent:shared authority 风险太高。
- 客户数据不能混在一个 Gateway:Gateway 不是敌对多租户边界。
- Agent 有写生产系统的能力:工具后果不可只靠 prompt 控制。
- 浏览器 profile 有真实后台登录态:cookie 和登录态就是权限。
- 合规要求每个部门单独审计 credentials:凭据和日志需要独立台账。
这些场景下优先:
- 分 Gateway;
- 分 credentials;
- 分 OS user;
- 分 host 或 VPS;
- 公共入口只给 sandboxed + messaging-only tools;
- 关闭 elevated;
- 关闭 host browser control;
- 打开 strict browser SSRF policy;
- 用
openclaw security audit --deep做基线检查。
不要用一句“我们配置了 prompt 防御”来替代系统边界。
15. 一句话解释每个核心概念
你可以用这组句子自测:
- Gateway:所有 channel、client、node、automation 进入 OpenClaw 的控制面。
- Channel:把不同消息平台标准化,并把回复送回确定目标。
- Agent:带 workspace、session store、模型和工具边界的执行主体。
- Agent Loop:一次消息变成回复和动作的完整运行链路。
- Workspace:Agent 的工作目录和长期文件环境,不是安全沙箱。
- Memory:写在磁盘上的长期事实和检索索引,不是模型隐藏记忆。
- Context:本次 run 实际发给模型的全部输入。
- Session:当前对话桶,决定历史、并发和当前 transcript。
- Compaction:把长对话压成摘要,保留可继续运行的上下文。
- Heartbeat:周期性主会话检查。
- Cron:Gateway 精确调度器。
- Webhook:外部系统主动触发 OpenClaw 的入口。
- Task:后台工作的状态台账。
- Tool policy:哪些工具可被调用。
- Sandbox:工具运行位置和文件系统边界。
- Elevated:sandboxed exec 的出沙箱开关。
- Hook:在特定 Gateway 或 Agent 生命周期点插入逻辑。
如果你能不用看前文解释这些概念之间的关系,这个理解系列就完成了。
16. 给 Agent 的架构复盘任务
把这段发给 OpenClaw Agent,做一次只读架构审计:
请只读复盘当前 OpenClaw 部署架构,不要修改文件。
要求:
1. 运行 openclaw status、openclaw gateway status,说明 Gateway bind、port、remote/local mode。
2. 运行 openclaw sessions --json,总结当前 session 类型、活跃度、store path。
3. 运行 /context list 或 openclaw agent 侧可用命令,说明 workspace bootstrap 和主要 context 来源。
4. 检查 workspace 文件:AGENTS.md、SOUL.md、TOOLS.md、USER.md、IDENTITY.md、HEARTBEAT.md、MEMORY.md、memory/。
5. 检查 channels 配置,说明 DM policy、group policy、mention gating、context visibility。
6. 运行 openclaw sandbox explain --json,总结 sandbox、tool policy、elevated gates。
7. 检查 heartbeat、cron、webhook、tasks 配置和最近状态。
8. 输出一张文字版架构图:入口 -> Gateway -> route -> session -> agent loop -> tools -> persistence。
9. 标出三个最可能导致误用的边界,并给出最小修复建议。17. 系列完成自检
到这里,你应该能回答:
- 为什么 OpenClaw 要用 Gateway 做控制面?
- 为什么 Agent Loop 需要按 session 串行?
- Workspace 为什么不是 sandbox?
- Memory 和 Context 的边界是什么?
- 为什么 Channel routing 不能交给模型猜?
- 为什么 reset 不等于失忆?
- 为什么 Heartbeat、Cron、Webhook、Tasks 不能混成一个概念?
- 为什么 tool policy 比 prompt 防御更硬?
- 什么场景必须拆 Gateway 或 host?
- 你自己的 OpenClaw 部署里,最危险的入口在哪里?
过关标准:能从入口、路由、session、context、workspace、memory、tools、sandbox、automation、安全边界十个角度复述 OpenClaw 的设计取舍。
18. 接下来去哪
回到 OpenClaw 总览
从系列总览重新选择官方教程或深度理解路径。
09 · Channel 与安全
回到安全边界,继续核对入口、工具、沙箱、日志和 Gateway 暴露面。
官方教程:Gateway 架构
对照官方架构页继续看 Gateway、Agent runtime 和控制面。