OpenClaw 底层实现深度解析(二):一个本地优先 Agent Runtime 是怎么跑起来的
OpenClaw 的工具系统不是给模型一段“你可以执行 bash”的说明就结束了。它把工具做成了typed、policy-controlled、provider-visible 的一等公民。
OpenClaw 底层实现深度解析:一个本地优先 Agent Runtime 是怎么跑起来的
本文基于 OpenClaw 官方文档与公开仓库整理,重点不是“怎么安装”,而是“它为什么这样设计、底层是如何工作的”。
很多人第一次看到 OpenClaw,会把它理解成“接入 WhatsApp/Telegram 的聊天机器人”。
这个理解只对了一半。
从工程实现看,OpenClaw 的本质并不是一个 Bot,而是一个本地优先的 Agent Runtime:它把多渠道消息接入、会话状态、Prompt 构建、工具调用、设备节点、长期记忆和自动化任务,统一收敛到一个长期运行的 Gateway 上,再由 Agent Loop 驱动每次推理与执行。
如果要先给出一句结论,可以这样概括:
OpenClaw = Gateway 控制面 + Agent Loop 执行面 + Workspace / Skills / Memory 上下文系统 + Typed Tools / Nodes 行动系统。
1. 为什么 OpenClaw 的核心不是聊天,而是 Gateway
OpenClaw 的第一性原理不是“回复消息”,而是统一管理一切入口与执行状态。
官方架构文档里,Gateway 是一个单实例、长期运行的守护进程,负责:
- 持有所有消息渠道连接
- 暴露统一的 WebSocket 控制接口
- 接收 CLI、桌面端、Web UI、自动化任务、节点设备的控制请求
- 管理会话、路由、事件流、健康状态、任务触发与节点连接
1.1 渠道接入和智能执行必须解耦
WhatsApp、Telegram、Slack、Discord 这些渠道的协议、登录方式、消息模型都不一样。
如果每个渠道各自维护一套 Agent 逻辑,会立刻出现几个问题:
- 会话状态无法统一
- 多端控制难以同步
- 自动化任务与人工对话无法共享上下文
- 一个渠道的事件无法自然驱动另一个渠道的动作
所以 OpenClaw 把渠道适配层和Agent 执行层明确切开:
这样设计后,所有外部事件都先变成统一的内部命令,再交给同一套 Agent 运行时处理。
1.2 Gateway 是状态一致性的唯一真源
OpenClaw 官方文档反复强调:一个主机只应有一个 Gateway。
原因不是部署习惯,而是状态一致性。
因为以下资源都天然需要集中管理:
- WhatsApp 等连接状态
- 会话历史
- 设备配对状态
- 自动化任务
- Agent 路由绑定
- 流式事件分发
这和传统 Web 服务的“无状态副本横向扩容”不一样。
OpenClaw 更接近一个本地控制平面:它不是先追求分布式扩展,而是先保证“这台机器上的智能体系统是自洽的”。
2. Agent Loop 才是真正的执行核心
OpenClaw 最关键的底层机制,是官方文档里定义的Agent Loop。
一轮真实执行大致是这样:
- 接收一条消息或命令
- 解析
session / agent / workspace - 组装
system prompt和上下文 - 选择模型与认证配置
- 进入模型推理
- 如果模型触发工具,就执行工具
- 持续发出流事件
- 持久化结果,更新会话状态
文档中把这条链路概括为:
intakecontext assemblymodel inferencetool executionstreaming repliespersistence
这套设计的核心价值,是把“LLM 推理”从一次函数调用,升级成了带状态、可中断、可观察、可恢复的运行流程。
2.1 为什么它一定要做成“Loop”而不是“一次回答”
因为 Agent 和 ChatBot 的根本区别,在于推理不是终点,行动才是终点。
如果系统只做一次模型调用,那么它最多只能:
- 给你一段文本
- 生成一段建议
但 OpenClaw 需要支持的是:
- 读文件
- 跑命令
- 调浏览器
- 查记忆
- 跨会话发消息
- 调节点设备能力
- 在任务链中持续输出中间过程
这要求运行时必须具备:
- 多阶段控制流
- 工具结果回灌模型
- 中间状态事件化
- 超时与中止控制
- 执行结束后的持久化
所以 Agent Loop 本质上是在做一件事:
把大模型从“文本补全器”提升为“带外设和状态的执行引擎”。
2.2 OpenClaw 为什么强调“真实 run”
官方文档专门把 Agent Loop 称为“real run”或“authoritative path”,这说明它不是外围封装,而是系统的唯一可信执行链路。
这意味着:
- CLI 调用 agent,走这条链路
- 渠道自动回复,走这条链路
agent.wait也是围绕这条链路等待结束事件- 工具流、助手文本流、生命周期流,都从这条链路发出
这类设计的工程收益很直接:
所有入口共享同一语义,不会出现“Web 上这样跑,CLI 上那样跑”的双轨实现。
3. 串行化不是保守,而是 Agent 系统的刚需
如果只看产品表面,很多人会觉得“多消息并发处理”理所当然。
但 OpenClaw 的队列系统恰恰反过来:同一 session 串行,不同 session 并行。
官方队列文档提到,它用了一个 lane-aware FIFO queue:
- 先按
session:<key>做串行化 - 再进入全局 lane 控制总体并发
- 默认保证同一个 session 同一时刻只有一个 active run
3.1 为什么必须按 session 串行
因为 Agent 不是无状态聊天,它会操作共享资源:
- 会话历史文件
- 工具调用结果
- CLI
stdin session metadatamemory flush时机- 运行中的
tool stream
如果同一会话里同时并发两个 run,会立刻出现经典竞态条件:
- 两次推理拿到不同版本的历史
- 两个工具同时修改同一文件
- 后发消息先完成,覆盖先发消息状态
- 模型基于旧上下文决策,产生逻辑冲突
所以 OpenClaw 的选择非常工程化:
让“会话内一致性”优先于“单会话吞吐量”。
这其实更接近数据库事务的思想,而不是纯 Web 并发的思想。
3.2 它不是低并发,而是“有边界的并行”
OpenClaw 不是全局串行。
它允许不同 session 并行,并通过全局 lane 控制最大并发数。
这说明它的并发模型是:
- 局部强一致:单 session 串行
- 全局可扩展:多 session 并行
- 后台任务隔离:如
cron、subagent可走不同 lane
这类模型非常适合 Agent 系统,因为 Agent 的正确性主要取决于局部状态是否一致,而不是单条请求的 TPS。
4. Prompt 不是模板,而是运行时组装出来的执行环境
OpenClaw 的 system prompt 不是一段固定人格文本,而是每次运行动态拼装的执行环境描述。
官方文档给出的组成项包括:
- 工具列表与说明
- 安全提醒
- Skills 列表
- 工作目录
- 本地文档位置
- 注入的 workspace 文件
- 沙箱说明
- 日期与时区
- OpenClaw 自更新控制信息
这背后有一个很重要的设计判断:
Prompt 在 OpenClaw 里不是“提示词”,而是运行时 ABI。
这里的 ABI 可以理解为“模型理解当前系统能力边界的协议面”。
4.1 为什么每次都重新组装 Prompt
因为 Agent 的有效行为依赖运行时条件,而这些条件是动态变化的:
- 当前工具是否被允许
- 当前运行是否在沙箱内
- 当前工作区是什么
- 哪些 skills 可用
- 当前时间、时区是什么
- 哪些 bootstrap 文件应注入
- 当前模型和 provider 是谁
如果这些信息不在 Prompt 里显式声明,模型就只能靠猜。
而 Agent 系统里,“让模型猜”几乎总是坏设计。
4.2 Workspace 文件注入的原理与意义
OpenClaw 会把一些工作区文件注入到 system prompt 所在的上下文中,例如:
AGENTS.mdSOUL.mdTOOLS.mdIDENTITY.mdUSER.mdBOOTSTRAP.mdMEMORY.md
这一步的本质,不是“方便读取文件”,而是把行为约束前置成系统条件。
也就是说,这些文件不是普通知识库,而更像:
- 角色设定
- 工作区规则
- 操作规范
- 长期偏好
- 当前项目的局部制度
这种做法的优点很明显:
- 行为规则和代码解耦
- 不同 agent 可用不同 workspace 形成不同行为边界
- 修改行为不需要改 runtime,只需改 bootstrap 文件
- 便于用户用自然语言重塑 agent
但代价也同样明确:
- 这些文件每轮都消耗 tokens
MEMORY.md过大时会显著挤压上下文窗口- Prompt 设计质量会直接影响执行质量
所以官方文档特别提醒:这些文件要保持精简。
5. Context 和 Memory 为什么必须分开
这是 OpenClaw 非常成熟的一点:它没有把“上下文”和“记忆”混成一个概念。
5.1 Context 是当前窗口,Memory 是磁盘上的事实
官方 Context 文档明确指出,Context 包含:
system prompt- 对话历史
- 工具调用与工具结果
- 附件内容
它直接受模型上下文窗口限制。
而 Memory 文档明确指出,Memory 的源事实在磁盘上,默认是 Markdown 文件:
memory/YYYY-MM-DD.mdMEMORY.md
也就是说:
- Context 决定这次模型“看见什么”
- Memory 决定系统“长期记住什么”
5.2 为什么要把记忆落到文件,而不是只做向量库
这是 OpenClaw 很实用主义的选择。
文件型记忆的优点:
- 可读
- 可手工编辑
- 可版本管理
- 可备份
- 可审计
- 不依赖特定向量存储后端
向量检索在这里不是“真相来源”,而是索引层。
真正的 source of truth 仍然是 Markdown 文件。
这和很多 Agent 框架完全相反。后者往往把“记忆”做成一堆 embedding chunk,最后人根本不知道系统到底记住了什么。
OpenClaw 则把“可见、可控、可修改”放在第一位。
5.3 预压缩记忆刷新为什么重要
官方 Memory 文档还提到一个细节:
当会话接近 auto-compaction 时,OpenClaw 会触发一次 silent turn,提醒模型把值得长期保存的信息写入 Memory。
这背后的原理是:
- LLM 当前窗口迟早会满
- 历史压缩不可避免会损失局部细节
- 如果不在压缩前把 durable facts 外化到磁盘,记忆会随上下文消失
所以这个 memory flush 机制,本质上是在解决一个 Agent 系统的经典问题:
如何把“瞬时上下文中的重要事实”升级成“长期状态中的稳定事实”。
6. Tools 为什么是一等公民,而不是 shell 旁路
OpenClaw 的工具系统不是给模型一段“你可以执行 bash”的说明就结束了。
它把工具做成了typed、policy-controlled、provider-visible 的一等公民。
官方文档里,工具被分成多个组:
group:runtimegroup:fsgroup:sessionsgroup:memorygroup:webgroup:uigroup:automationgroup:messaginggroup:nodes
6.1 为什么 Typed Tools 比 shell 指令更适合 Agent
如果只给模型 shell 权限,会有几个天然问题:
- 参数边界不清晰
- 权限控制粗粒度
- 结果结构化差
- 不同 provider 间行为难以稳定
- 很难做精确审计和流式反馈
而 typed tools 的优势是:
- 参数 schema 明确
- 输出结构稳定
- 可以做
allow / deny / profile控制 - 工具能力可以按
agent / provider / sandbox分层授权 - 更容易以事件形式回传进度和结果
这相当于把“模型调用工具”从 prompt 技巧,升级成运行时协议能力。
6.2 工具权限控制体现了 OpenClaw 的安全哲学
OpenClaw 允许通过配置做:
- 全局
allow / deny - agent 级别
allow / deny - sandbox 策略
- tool profile 预设
这说明它的安全模型并不是“绝对禁止”,而是:
把能力暴露给模型,但通过显式策略决定暴露多少。
这种思路非常适合自托管 Agent,因为用户通常需要可操作性,而不是一个完全阉割的助手。
7. Multi-Agent 的本质不是多角色,而是多隔离执行域
官方 Multi-Agent 文档对“一个 agent”定义得非常严格。
每个 agent 都有自己的:
- workspace
agentDir- 会话存储
- 认证配置
- skills
这说明 OpenClaw 里的多 Agent,不是“换一个 system prompt”这么简单,而是完整的运行时隔离单元。
7.1 为什么 Agent 必须隔离状态
如果多个 agent 共用以下资源:
- 会话历史
- auth profiles
- workspace 规则
- memory 文件
- session store
就会产生严重污染:
- 人格规则互相覆盖
- 认证配置串用
- 不同联系人共享上下文
- 会话和工具权限边界模糊
所以 OpenClaw 的设计其实非常接近轻量级多租户系统:
每个 agent 是一个独立租户,只共享 Gateway 控制面,不共享执行状态。
7.2 路由绑定让不同渠道映射到不同“大脑”
多 Agent 路由的意义在于:
- 不同频道可对应不同 workspace
- 不同联系人可绑定不同 agent
- 同一主机可同时运行多个独立智能体
- 多个 WhatsApp / Telegram 账户也能共存
这使 OpenClaw 不再是“一个助手服务所有场景”,而是“一个 Gateway 承载多个隔离智能体”。
8. Nodes 机制让 OpenClaw 从本地助手升级为设备调度系统
OpenClaw 的另一个关键实现,是 Nodes。
官方文档里,Node 是一个通过 WebSocket 以 role: node 连接到 Gateway 的外设或 companion device,可以暴露命令能力,例如:
canvas.*camera.*device.*notifications.*system.*
8.1 为什么 Nodes 很关键
如果没有 Nodes,Agent 的执行边界就基本被锁死在 Gateway 所在机器。
而有了 Nodes 之后,OpenClaw 的能力边界会扩展成:
- 这台 Mac 能干什么
- 那台 Linux 服务器能干什么
- 那部手机能拍什么、看什么、通知什么
- 哪台设备可代理浏览器或运行系统命令
从架构上看,这意味着 OpenClaw 已经不是“本机 Bot”,而是一个设备能力总线。
8.2 Node 为什么仍然不取代 Gateway
文档特别强调:Node 是外设,不是 Gateway。
消息仍然落在 Gateway,不落在 Node。
原因很简单:
- 消息渠道状态要集中维护
- 会话与路由要集中维护
- Node 是能力提供者,不是控制中枢
这是一种非常清晰的主从模型:
- Gateway:控制面 + 状态面
- Node:能力面
这种分层保证了系统不会演变成难以管理的分布式混战。
9. OpenClaw 的“原理”到底是什么
如果把上面的工程细节再抽象一层,OpenClaw 实际上解决了 Agent 系统里的 4 个根问题。
9.1 问题一:大模型没有稳定运行时
LLM 天然只会“生成下一个 token”,并不知道:
- 当前在哪个工作区
- 能用哪些工具
- 哪些权限被允许
- 哪个会话是当前上下文
- 哪些内容应该长期记住
OpenClaw 的原理,就是给 LLM 外挂一个稳定运行时语义层:
- Gateway 负责环境统一
- Prompt 负责能力声明
- Session 负责状态边界
- Tools 负责行动接口
- Memory 负责长期外化
- Queue 负责一致性
9.2 问题二:对话式接口天然缺少状态治理
纯聊天系统容易出现:
- 历史失控增长
- 多消息乱序
- 重要事实丢失
- 工具结果不可追踪
OpenClaw 用以下机制治理状态:
- session lane 串行化
- stream event 可观察化
- memory 文件化
- compaction 前 flush
- 多 agent 隔离
9.3 问题三:工具调用如果不协议化,就无法产品化
“让模型自己写 shell”可以 demo,但很难变成稳定产品。
OpenClaw 通过 typed tools + policy system,把工具能力变成平台原语,因此:
- 更可控
- 更可审计
- 更可扩展
- 更容易跨 provider 迁移
9.4 问题四:Agent 如果不能连接现实设备,就只能停留在聊天层
Node 系统解决的是“模型如何接触真实世界能力”的问题。
它让 Agent 不止能说,还能:
- 在别的机器执行命令
- 使用本地浏览器
- 接管摄像头、画布、通知等能力
- 通过设备配对建立受控外设网络
10. 一句话收束:为什么 OpenClaw 值得研究
OpenClaw 真正值得研究的地方,不在于它“又接了一个聊天渠道”,而在于它把 Agent 系统里最难落地的几件事拼成了一个闭环:
- 用 Gateway 统一入口和状态
- 用 Agent Loop 统一执行语义
- 用 Queue 保证 session 一致性
- 用 Prompt 组装运行时 ABI
- 用 Memory 把长期状态外化到磁盘
- 用 Typed Tools 提供结构化行动能力
- 用 Multi-Agent 实现隔离
- 用 Nodes 把能力边界扩展到多设备
所以从底层原理上说,OpenClaw 更像:
一个面向个人和小团队场景的、本地优先、事件驱动、状态可见、工具可控的 Agent 操作层。
它表面上是聊天入口,骨子里却是一个轻量级 AI Runtime。
参考资料
更多推荐



所有评论(0)