引言
OpenClaw(原Clawdbot)作为当前全球最炙手可热的开源AI Agent框架,其GitHub星标数已超越Linux和React,登顶全球榜首。它的爆火绝非偶然——这套架构完美解决了AI Agent落地的“最后一公里”问题,实现了从云端大脑到本地肢体的无缝协同。
本文将深入OpenClaw源码,从四层架构、插件化重构、三级记忆系统、Gateway-Pi执行链路四个维度,彻底拆解这套系统的设计哲学与实现细节。
一、整体架构:四层解耦设计
OpenClaw采用经典的四层解耦架构,从外到内依次是:交互层、网关层、智能体层、执行层。这种分层设计确保了各模块职责清晰、可独立演进。
┌─────────────────────────────────────────────────────────────┐
│ 交互层 (Channels) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ WhatsApp │ │ Telegram │ │ 飞书 │ │ iMessage │ ... │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 网关层 (Gateway) │
│ 路由 · 排队 · 调度 · 鉴权 · 协议转换 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 智能体层 (Agent) │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │会话管理器 │ │上下文组装器 │ │ 记忆系统 │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ ┌────────────┐ ┌────────────┐ │
│ │执行循环 │ │工具调用 │ │
│ └────────────┘ └────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 执行层 (Execution) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 本地节点 │ │ 远端节点 │ │ 技能 │ │ 沙箱 │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────────────────┘
1.1 交互层:抹平所有IM差异
交互层的核心职责是协议适配。OpenClaw内置支持8个核心通道(Telegram、WhatsApp、Discord等),并通过插件系统支持超过50个扩展通道。
源码中,每个通道都是一个独立的插件,必须实现统一的ChannelPlugin接口:
export type ChannelPlugin = {
id: ChannelId; // 通道唯一标识
meta: ChannelMeta; // 通道元信息
capabilities: ChannelCapabilities; // 能力声明
config: ChannelConfigAdapter; // 配置管理
// 可选实现
outbound?: ChannelOutboundAdapter; // 发送消息
pairing?: ChannelPairingAdapter; // 配对逻辑
messaging?: ChannelMessagingAdapter; // 消息处理
// ...
}
这种设计的精妙之处在于:核心模块不面向任何具体IM编程,只面向接口编程。无论未来出现什么新的IM工具,只要实现这套接口,就能无缝接入OpenClaw生态。
1.2 网关层:系统的控制中枢
Gateway是整个OpenClaw的核心服务,作为一个常驻的Node.js进程,它承担着:
-
路由:根据消息来源分配给对应的会话 -
排队:实现“车道式队列”(Lane Queue),默认串行、显式并行 -
调度:管理定时任务(Heartbeat) -
鉴权:验证请求合法性 -
协议转换:将不同通道的消息统一成内部格式
网关层的核心实现在src/gateway/server.py中,关键代码片段:
# gateway/dispatcher.py
def dispatch_task(payload):
# 提取意图,过滤无用的对话历史
intent = extractor.analyze(payload.content)
# 匹配最合适的执行节点
node_id = registry.get_active_node(payload.affinity)
return forward_to_node(node_id, intent)
Gateway还维护着节点的心跳机制(默认使用Redis),如果节点失联,指令会被正确路由到其他可用节点。
二、插件化重构:从单体到生态
2026年初,OpenClaw通过PR #661完成了重大插件化重构,这是架构演进的分水岭。
2.1 单体架构的技术债务
重构前,添加一个新模型提供商需要修改4个核心文件:
-
继承 BaseProvider抽象类 -
在 providers/index.ts手动注册 -
在 model-router.ts添加路由分支 -
更新配置Schema
路由文件充斥着大量的else-if分支,代码复杂度随提供商数量线性增长:
// 重构前的路由逻辑
exportclass ModelRouter {
async route(model: string, ...args) {
if (model.startsWith('anthropic/')) {
returnthis.anthropicProvider.call(...args);
} elseif (model.startsWith('openai/')) {
returnthis.openaiProvider.call(...args);
} elseif (model.startsWith('gemini/')) {
returnthis.geminiProvider.call(...args);
}
// ... 还有15+个else-if
}
}
2.2 插件化架构设计
重构后的架构核心是接口标准化+动态加载:
// packages/core/src/provider-interface.ts
export interface Provider {
readonly name: string;
readonly version: string;
chat(messages: Message[], options: ChatOptions): AsyncIteratorstring>;
estimateTokens(text: string): number;
getSupportedFeatures(): ProviderFeatures;
}
动态加载机制通过ProviderLoader实现:
export class ProviderLoader {
private providers = new Mapstring, Provider>();
async loadFromPackage(packageName: string): Promisevoid> {
constmodule = await import(packageName); // 动态导入
if (!this.validateProvider(module.default)) {
thrownewError(`Invalid provider: ${packageName}`);
}
const provider = newmodule.default();
this.providers.set(provider.name, provider);
}
}
重构后的路由逻辑从O(n)降为O(1):
export class ModelRouter {
async route(model: string, ...args) {
const [providerName] = model.split('/');
const provider = this.loader.getProvider(providerName);
if (!provider) throw new Error(`Provider not found: ${providerName}`);
return provider.chat(...args);
}
}
2.3 插件化的四大优势
-
依赖隔离:核心框架从45MB降至8MB -
并行开发:社区可独立开发插件,无需等待核心迭代 -
版本自治:各插件独立版本,可单独更新 -
安全增强:沙箱机制+权限声明,风险可控
三、记忆系统:三级存储架构
OpenClaw的记忆系统是其最惊艳的设计之一。它采用三级记忆架构,模拟人类记忆的分层特性。
3.1 工作区结构
每个Agent对应一个独立的工作区:
~/.openclaw/workspace/
├── MEMORY.md # 长期记忆
├── memory/
│ ├── 2026-03-10.md # 今日日志(短期)
│ └── 2026-03-09.md # 昨日日志
├── sessions/ # 会话存档(近端)
├── USER.md # 用户身份
└── SOUL.md # Agent人格设定
3.2 存储层:SQLite + 向量
每个Agent对应一个独立的SQLite数据库,表结构设计精巧:
-- 文件元数据
CREATETABLE files (
idINTEGER PRIMARY KEY,
pathTEXTUNIQUE,
mtime INTEGER, -- 修改时间,用于增量索引
hashTEXT -- 内容哈希,去重
);
-- 文本块存储
CREATETABLE chunks (
idINTEGER PRIMARY KEY,
file_id INTEGER,
textTEXT,
hashTEXTUNIQUE, -- 文本哈希,跨文件去重
embedding TEXT -- JSON序列化的向量
);
-- 全文搜索(FTS5)
CREATEVIRTUALTABLE chunks_fts USING fts5(text, content=chunks);
-- 向量搜索(sqlite-vec)
CREATEVIRTUALTABLE chunks_vec USING vec0(embedding float[1536]);
3.3 混合检索策略
OpenClaw的核心检索工具memory_search实现了BM25 + 向量的混合检索:
async function hybridSearch(query, options = {}) {
const vecWeight = 0.7; // 向量权重
const bm25Weight = 0.3; // BM25权重
// 分别检索(取并集)
const vectorResults = await vectorSearch(query);
const bm25Results = await bm25Search(query);
// 合并并计算综合得分
const allChunkIds = new Set([
...vectorResults.map(r => r.id),
...bm25Results.map(r => r.id)
]);
// 加权平均后排序返回
}
这套算法的关键在于并集而非交集——只要任一方法认为相关,就有机会进入候选池。
3.4 优雅降级
如果sqlite-vec扩展未安装,系统会自动回退到JS暴力计算:
try {
// 快速路径:数据库内计算余弦距离
returnawait db.all(`SELECT ... vec_distance_cosine(...)`);
} catch (err) {
// 回退路径:全量加载到内存暴力计算
const allChunks = await db.all("SELECT * FROM chunks");
return allChunks.map(chunk => ({
...chunk,
dist: cosineSimilarity(queryVector, JSON.parse(chunk.embedding))
})).sort((a, b) => a.dist - b.dist).slice(0, limit);
}
四、执行层:Gateway-Pi 架构
OpenClaw最硬核的部分是其云端大脑+本地肢体的设计。
4.1 三层执行链路
-
Orchestrator(大脑):云端部署,负责LLM推理和任务拆解 -
Gateway(协议桥):鉴权、流量整形、指令翻译 -
Pi-embedded(执行端):运行在本地设备,真正执行脚本
4.2 沙箱隔离机制
Pi-embedded实现了一套名为 “Cell Isolation” 的沙箱机制:
# packages/pi-embedded/runtime/executor.py
class ExecutionEngine:
def execute(self, skill_code):
# 环境快照
snapshot = self.take_snapshot()
# 在独立venv中运行
with self.isolated_venv() as venv:
# 动态安装依赖
self.install_dependencies(skill_code.dependencies)
# 执行技能
result = venv.run(skill_code)
# 恢复环境
self.restore_snapshot(snapshot)
return result
4.3 完整调用链追踪
以“查CPU温度并生成图表”为例,完整调用链如下:
1. Orchestrator → 识别技能需求 → 生成JSON指令
2. Gateway → 验证签名 → 查找在线Pi节点 → Protobuf封装 → WebSocket发送
3. Pi-embedded → 接收消息 → 解包
4. Sandbox → 启动临时Python进程 → 挂载传感器权限
5. Skill Execution → 执行get_temp.py
6. Callback → 结果(图片二进制)原路返回
五、Agent核心配置
每个Agent的workspace中包含多个核心配置文件:
|
|
|
|---|---|
AGENTS.md |
|
SOUL.md |
|
TOOLS.md |
|
IDENTITY.md |
|
USER.md |
|
HEARTBEAT.md |
|
MEMORY.md |
|
源码中通过loadWorkspaceBootstrapFiles方法加载这些文件:
// src/agents/workspace.ts:498-555
export async function loadWorkspaceBootstrapFiles(dir: string) {
const entries = [
{ name: "AGENTS.md", filePath: path.join(resolvedDir, "AGENTS.md") },
{ name: "SOUL.md", ... },
{ name: "TOOLS.md", ... },
// ...
];
// 动态检测MEMORY.md
}
六、架构设计的优缺点
6.1 核心优势
-
零运维:SQLite单文件,无需复杂数据库 -
数据私有:全本地存储,不上云 -
可审计:记忆透明,Markdown文件可读 -
增量索引:只处理变更文件,效率高 -
优雅降级:从向量→BM25→纯文本,逐级回退 -
插件生态:60+官方技能,社区持续贡献
6.2 现存挑战
-
Token消耗偏高:记忆系统是主要原因 -
向量检索不懂关系:能找到个体但推不出关系 -
维护成本线性增长:文件越多,索引维护越复杂 -
长连接抖动:WebSocket 1006错误常见 -
小白门槛:虽零运维,但需懂文件结构
七、实战建议
7.1 定期记忆体检
长期记忆文件会随时间膨胀,建议每月手动过一遍MEMORY.md,删过时、并重复。
7.2 教会Agent分类
在系统提示词中引导分类:
-
“我喜欢/习惯” → preferences.md -
“我要做一个” → projects.md -
“解决了” → learnings.md
7.3 善用Heartbeat
openclaw cron add --name "记忆维护"
--cron "0 3 *"
--system-event "运行记忆整理:合并相似项,删除低价值项,生成摘要"
7.4 显式限定搜索范围
memory_search({ query: "...", scope: ["learnings.md"] })
结语
OpenClaw的架构设计给我最大的启发是:AI的记忆和执行不应该是黑盒。用Markdown存真相,用SQLite建索引,用BM25+向量做检索,用Gateway-Pi做执行——这套组合拳既保证了功能强大,又让一切透明可控。
在这个所有AI都想“记住你”的时代,OpenClaw让你能随时打开文件、看清它记住了什么、知道它在哪执行、怎么执行。这种清醒的设计哲学,或许正是它能够超越Linux和React,登顶全球的原因。
参考资料
-
OpenClaw三级记忆系统实现揭秘 -
2026年OpenClaw插件化重构技术解析 -
OpenClaw核心源码解读:从Gateway到Pi-embedded -
不会写代码也能懂:OpenClaw四层架构图解 -
吃龙虾咯!万字拆解OpenClaw的架构与设计 -
关于OpenClaw,你需要了解的:核心架构、运作原理 -
OpenClaw Architecture Deep Dive 2025


Post a reply