
OpenClaw 架构源码深度解析:Gateway、Agent、Skill、Memory 四大模块完全拆解
从零读懂一个 26 万 Star 的 AI Agent 框架是如何设计的
📑 目录
- 一、引言:OpenClaw 为什么值得源码级学习?
- 二、OpenClaw 整体架构概览
- 三、Gateway:消息调度与路由中心
- 四、Agent:决策与推理引擎
- 五、Skill:技能系统与行为约束
- 六、Memory:三层记忆架构
- 七、Channel:适配器模式的多渠道接入
- 八、Java 侧的思考:哪些可以复用,哪些需要重写
- 九、总结
一、引言:OpenClaw 为什么值得源码级学习?
自 2026 年 1 月开源以来,OpenClaw(曾用名 Clawdbot / Moltbot)迅速成为 AI 领域的现象级产品,GitHub 星标突破 26 万。它的核心价值在于将大语言模型的推理能力与本地系统操作深度结合,实现了从“对话式 AI”到“行动式 AI”的跨越。
OpenClaw 不仅仅是一个简单的消息转发器,而是一个具备完整会话管理、并发控制、记忆检索以及丰富工具支持的复杂 Agent 运行时环境。
对于想要自建 Agent 系统的开发者来说,OpenClaw 的源码是一座值得反复研读的宝库——它用 TypeScript/Node.js 实现了一套完整的“Gateway-Agent-Skills-Memory”四层架构,设计清晰、模块解耦、可扩展性强。
本文将深入 OpenClaw 的源码,拆解四大核心模块的设计与实现。
二、OpenClaw 整体架构概览
2.1 四层架构设计
OpenClaw 采用分层架构设计,各模块通过标准化接口通信,形成完整的处理链路:
核心组件说明:
| 组件 | 职责 | 关键特征 |
|---|---|---|
| Gateway | 消息调度和路由中心 | 统一接入 HTTP/WebSocket,负责鉴权、路由、限流 |
| Agent | 决策和推理引擎 | 接收用户意图,调用 LLM 做理解与推理,调度 Planner |
| Planner | 任务规划器 | 对 LLM 生成的步骤做强规则校验,拦截危险操作 |
| Skill | 具体功能执行模块 | 封装完整业务逻辑,是可复用、可测试的原子能力 |
| Memory | 持久化上下文管理 | 三层存储架构,支持混合检索 |
| Tool | 工具执行层 | 真正与数据库、API、第三方平台交互的入口 |
2.2 源码仓库目录结构
克隆 OpenClaw 仓库后,顶层目录结构如下:
openclaw/
├── .agent/workflows/ # 内置 Agent 工作流描述
├── .agents/ # 多 Agent 默认配置
├── .pi/ # Agent Runtime 配置(历史遗留命名)
├── apps/ # 可独立部署的应用(macOS App 等)
├── extensions/ # 浏览器插件等扩展
├── packages/ # 内部共享包(TypeScript 类型等)
├── skills/ # 社区 Skills(每个子目录含一个 SKILL.md)
│ ├── weather/SKILL.md
│ ├── github/SKILL.md
│ ├── notion/SKILL.md
│ └── ... # 50+ 个 Skills
├── src/ # Gateway 主体源码(TypeScript/Node.js)
│ ├── gateway/ # Gateway 核心:server.ts、boot.ts
│ ├── agents/ # Agent Runtime
│ ├── sessions/ # Session 存储与管理
│ ├── channels/ # Channel 基础抽象
│ ├── slack/ # Slack 适配器(Bolt)
│ ├── telegram/ # Telegram 适配器(grammY)
│ ├── discord/ # Discord 适配器(discord.js)
│ ├── whatsapp/ # WhatsApp 适配器(Baileys)
│ ├── memory/ # 记忆系统
│ ├── security/ # 安全、白名单、审计
│ ├── routing/ # 消息路由
│ ├── providers/ # 模型 Provider(Anthropic、OpenAI 等)
│ ├── cron/ # Cron 定时任务
│ ├── cli/ # CLI 命令路由与实现
│ ├── web/ # Web 控制台后端
│ ├── entry.ts # 应用主入口
│ └── runtime.ts # 运行时初始化
├── ui/ # Web 控制台前端(React/Vite)
├── test/ # 测试:单元、集成、E2E
├── Dockerfile # 主容器镜像
├── docker-compose.yml
└── package.json
⚠️ 容易混淆的地方:
src/gateway/是一个目录(而非单文件gateway.ts),下面包含server.ts、boot.ts、server-*.ts等多个文件。
三、Gateway:消息调度与路由中心
3.1 Gateway 的核心职责
Gateway 是 OpenClaw 的中枢神经系统,承担三大核心职能:
- 协议适配:支持 WebSocket、HTTP 等主流通信协议,通过 WebSocket 服务器(
ws://127.0.0.1:18789)建立控制通道,同时提供 HTTP 接口(http://:18793)供外部调用 - 流量控制:通过令牌桶算法实现 QoS 保障
- 安全审计:记录所有进出请求的元数据,配合白名单和权限控制机制
Gateway 的核心设计思想是:所有消息渠道、AI 会话、工具调用都通过一个统一的本地 WebSocket 服务进行调度。这种“本地优先”的设计让 OpenClaw 可以脱离云端独立运行。
3.2 Gateway 启动流程源码解析
Gateway 的启动流程可以分为以下几个关键步骤:
关键源码文件:
src/entry.ts:应用主入口,负责启动整个系统src/runtime.ts:运行时初始化,加载配置和插件src/gateway/server.ts:WebSocket/HTTP 服务器的核心实现src/gateway/boot.ts:Gateway 启动引导逻辑
3.3 消息路由与事件分发
Gateway 采用三级路由机制确保消息高效流转:
消息归一化的核心数据结构:
// 所有渠道消息统一归一化为 MsgContext
interface MsgContext {
channel_id: string; // 渠道标识
sender_id: string; // 发送者 ID
content: string; // 消息内容
timestamp: number; // 时间戳
session_id: string; // 会话标识
metadata: { // 渠道特有信息(扩展字段)
platform?: string;
// Slack 的 Block Kit、Discord 的 embed 等
};
}
Gateway 使用 TypeBox(TypeScript-first schema 库)定义 WebSocket 协议(握手、请求/响应、服务端事件),这些 schema 驱动运行时验证、JSON Schema 导出。
四、Agent:决策与推理引擎
4.1 Lobster Loop:OpenClaw 的 Agent 执行循环
OpenClaw 将智能体循环命名为 “Lobster Loop”(龙虾循环) ,它脱胎于学术界的 ReAct 框架,在工程实践中演化为 Think(思考)→ Act(执行)→ Observe(观察)→ Reflect(反思) 的四段式闭环。
核心伪代码:
// Agent 主循环(简化版)
while (true) {
// 1. 把消息历史喂给 LLM
const response = await llm.complete(messages);
// 2. 模型说"我要调工具"
if (response.hasToolCalls()) {
const results = await executeTool(response.toolCalls);
// 把结果追加到消息历史
messages.push(toolResultMessage(results));
// 继续循环,让模型再想一轮
continue;
}
// 3. 模型说"我想清楚了,回复用户"
break;
}
关键洞察:每次 LLM 返回工具调用请求,不是终点,而是循环的一轮。工具结果被追加进消息历史,下一轮 LLM 拿到的上下文就包含了这次的执行结果,再决定下一步。
4.2 ReAct 范式的工程落地
ReAct(Reasoning + Acting)范式由普林斯顿大学与谷歌研究院于 2022 年联合提出(论文发表于 ICLR 2023)。其核心思想是:让 LLM 交替生成“推理轨迹”和“环境行动”,而不是分别单独进行。
OpenClaw 严格遵循 ReAct 范式,通过以下循环实现智能决策:
Planner 的作用:OpenClaw 的 Planner 是防止 LLM 幻觉进入生产系统的第一道防线。它接收 LLM 生成的步骤,做强规则校验——负责任务排序、依赖检查、边界约束,拦截非法、矛盾、危险操作。
4.3 循环终止条件
OpenClaw 的 Agent 循环有几个明确的终止条件:
| 终止条件 | 说明 | 触发场景 |
|---|---|---|
| 正常结束 | 模型不再输出 tool_use,直接返回文本 | 任务完成 |
| 最大轮数 | 达到最大工具调用轮数,强制截断 | 防止无限循环 |
| 错误放弃 | 工具执行报错,模型选择放弃 | 无法完成任务 |
| 上下文超限 | 上下文长度即将超限,触发压缩或截断 | 复杂任务调用了十几次工具 |
最后一个条件尤其值得注意——一个复杂任务调了十几次工具,每次工具返回几百行输出,很快就把 128K token 的窗口塞满了。OpenClaw 使用动态上下文管理来处理这个问题,我们将在 Memory 章节详细展开。
五、Skill:技能系统与行为约束
5.1 Skill 的本质
在 OpenClaw 中,Tool 和 Skill 是两个不同层次的概念:
- Tool:解决“Agent 能做什么”——具体的动作接口(如
exec、browser、read/write/edit) - Skill:解决“Agent 应该怎么做”——工具使用说明和任务流程约束
举例说明:
- 用户说:“帮我审查这个 PR。”
- Tool 只能提供动作:读取文件、执行测试、查看 diff、发送消息
- Skill 则提供流程:先查看 PR 变更范围 → 再判断是否需要运行测试 → 再检查新增逻辑、异常处理、边界条件 → 最后按 review 格式输出问题、风险和建议
5.2 SKILL.md 的结构与加载链路
每个 Skill 是一个包含 SKILL.md 的目录。SKILL.md 包含两部分:
- YAML Frontmatter:给 OpenClaw 看的元数据(
name、description等) - Markdown Body:给 Agent 看的指令(行为规则、示例等)
最小 Skill 示例:
---
name: hello-world
description: A simple skill that says hello.
---
# Hello World Skill
When the user asks for a greeting, use the echo tool to say: "Hello from your custom skill!"
Skill 注入 Agent 上下文的完整链路:
整个注入链路就三步:扫描目录 → 格式化 XML → 拼入 Prompt。
5.3 Skill 的加载路径与优先级
OpenClaw 不只从一个目录加载 Skill,而是有一套优先级体系。官方给出的加载顺序是:
- 内置 Skills:
skills/目录下的社区 Skills - 本地覆盖 Skills:用户自定义的 Skill,覆盖内置的同名 Skill
- per-agent Skill allowlist:每个 Agent 可以单独配置允许加载的 Skill 白名单
门控机制(Gating) :OpenClaw 支持通过 metadata.openclaw 配置 Skill 的启用条件,例如根据环境、配置和依赖二进制文件进行过滤。
六、Memory:三层记忆架构
6.1 为什么需要三层记忆?
在 OpenClaw 之前,AI 助手的记忆通常只有一层:会话上下文。今天聊完,明天它就不认识你了。
OpenClaw 的设计者借鉴了人的记忆是分层的这一思想,设计了三层记忆架构:
工作区目录结构:
~/.openclaw/workspace/
├── MEMORY.md # 长期记忆:偏好、决策、持久事实
├── memory/
│ ├── 2026-03-05.md # 今日日志(短期记忆)
│ ├── 2026-03-04.md # 昨日日志
│ └── ... # 历史日志
├── sessions/ # 会话存档(近端记忆)
├── USER.md # 用户身份
└── SOUL.md # Agent 人格设定
这套分层设计的核心思想是:模型不需要知道所有事,只需要知道此刻最相关的事。
6.2 存储层:SQLite + 向量索引
光有 Markdown 文件不够——要在大堆文本里快速找到相关内容,必须建索引。OpenClaw 使用 SQLite + 向量索引 的混合存储方案。
每个 Agent 对应一个独立的 SQLite 数据库,位于 ~/.openclaw/memory/{agentId}.sqlite。
核心表结构:
-- 文件元数据表:增量索引
CREATE TABLE files (
id INTEGER PRIMARY KEY,
path TEXT UNIQUE,
mtime INTEGER, -- 修改时间,用于增量索引
size INTEGER,
hash TEXT -- 内容哈希,去重用
);
-- 文本块表:存储分块内容与向量
CREATE TABLE chunks (
id INTEGER PRIMARY KEY,
file_id INTEGER,
start_line INTEGER,
end_line INTEGER,
text TEXT,
hash TEXT UNIQUE, -- 文本哈希,跨文件去重
embedding TEXT -- JSON 序列化的向量
);
-- 全文搜索(FTS5)
CREATE VIRTUAL TABLE chunks_fts USING fts5(
text,
content=chunks
);
-- 向量搜索(sqlite-vec)
CREATE VIRTUAL TABLE chunks_vec USING vec0(
embedding float[1536]
);
关键设计:
| 设计要点 | 说明 |
|---|---|
| 增量索引 | 通过 mtime 和 hash,只重新索引变更的文件 |
| 去重存储 | 相同文本块只存一次向量,节省空间 |
| 优雅降级 | 如果 sqlite-vec 扩展没装上,系统会回退到 JS 暴力计算 |
6.3 混合检索:BM25 + 向量搜索
OpenClaw 的记忆检索采用双路并行 + 结果合并的策略:
- BM25 全文检索:精准匹配关键词(适合查找具体术语)
- 向量检索:语义匹配(适合查找“意思相近”但用词不同的内容)
- 结果合并:两种检索结果按权重合并,返回最相关的记忆片段
默认 Embedding 提供商:OpenClaw 默认使用 OpenAI embeddings,也支持 Gemini、Voyage、Mistral、Bedrock、Ollama 等。
七、Channel:适配器模式的多渠道接入
OpenClaw 通过标准化的 Channel 适配器模式 实现与主流即时通讯工具的无缝对接。
核心设计思路:
定义一套统一的 Channel 协议,每个渠道实现一个适配器(Adapter),负责把该平台的消息格式“翻译”成系统内部统一的消息结构。上层 Gateway 只跟协议打交道,完全不关心底下接的是 Telegram 还是飞书。
每个 Channel 包含两部分:
| 组件 | 职责 |
|---|---|
| 消息监听器(Monitor) | 处理平台特定的 Webhook 机制和安全验证 |
| 协议适配器(Adapter) | 完成消息格式标准化转换 |
设计原则:组合优于继承——不要搞一个大接口让所有渠道都实现,而是把每种能力拆成独立的小接口,渠道按需组合。例如,iMessage 不需要群组能力就不实现群组相关接口。
国内渠道支持:OpenClaw 已支持飞书、钉钉、企业微信等国内主流办公平台。配置方式与其他 Channel 一致,通过 openclaw.json 配置对应的 Channel 适配器即可。
八、Java 侧的思考:哪些可以复用,哪些需要重写
OpenClaw 是 TypeScript/Node.js 实现的。在 Uni-MDP 的架构中,我们使用 Java + Spring AI 作为主技术栈。那么,OpenClaw 的哪些模块可以复用、哪些需要重写?
8.1 可以直接复用的设计
| 模块 | 复用方式 | 理由 |
|---|---|---|
| Channel 适配器模式 | 设计思路直接照搬 | 适配器模式是语言无关的设计模式 |
| Skill 机制 | SKILL.md 格式可复用 | Markdown 格式的技能描述与语言无关 |
| Memory 三层架构 | 设计思想直接借鉴 | 分层记忆是架构层面的设计 |
| ReAct 循环逻辑 | 算法思想可移植 | ReAct 是算法层面的设计 |
8.2 需要重写的模块
| 模块 | 重写方案 | 说明 |
|---|---|---|
| Gateway 核心 | Spring WebFlux + Reactor | OpenClaw 的 Gateway 基于 Node.js 事件循环,Java 侧用 WebFlux 实现响应式 |
| Agent Runtime | Java 实现 Lobster Loop | 将 TypeScript 的循环逻辑移植为 Java |
| Tool 执行层 | Java ProcessBuilder + Runtime | 文件操作、终端命令等用 Java 原生 API 实现 |
| Memory 存储 | Spring Data JPA + 向量数据库 | SQLite 可替换为 H2/PostgreSQL,向量检索可用 pgvector |
8.3 集成方案
方案一:REST API 调用(最快速)
将 OpenClaw 作为独立服务运行,Java 应用通过 REST API 调用其能力。适合快速验证,但增加了网络开销。
方案二:MCP 协议集成(最标准)
Spring AI 2.0 提供了 MCP Client 和 MCP Server 的 Boot Starter,可以将 OpenClaw 的工具通过 MCP 协议暴露给 Spring AI 应用。
方案三:Java 原生实现(最彻底)
参考 ClawRunr(OpenClaw 的 Java 版本,基于 Java 25 + Spring Boot + Spring AI 构建),将 OpenClaw 的核心能力用 Java 重新实现,深度集成到 Spring 生态中。
九、总结
OpenClaw 的架构设计体现了几个核心思想:
9.1 分层解耦
Gateway、Agent、Skill、Memory 四层各司其职,通过标准化接口通信。这种分层设计让每一层都可以独立演进。
9.2 本地优先
所有消息渠道、AI 会话、工具调用都通过一个统一的本地 WebSocket 服务(Gateway)进行调度。数据不上云,隐私有保障。
9.3 ReAct 工程化
将学术界的 ReAct 范式落地为生产级的 Lobster Loop,并增加了 Planner 作为安全防线。
9.4 记忆分层
三层记忆架构(短期/近端/长期)+ 混合检索(BM25 + 向量),在“记得住”和“不烧钱”之间找到了平衡。
9.5 适配器模式
Channel 适配器模式让 OpenClaw 可以接入任何消息平台。这种“对扩展开放,对修改封闭”的设计,是插件化架构的典范。
下一篇预告:我们将深入 Hermes 的源码,拆解学习循环、三层 Prompt 与 Skill 自改进机制。
敬请期待!🚀
📌 本文收录于专栏:从 OpenClaw 到 Hermes:自改进 Agent 完全指南

601

被折叠的 条评论
为什么被折叠?



