OpenClaw 源码深度解析(一):项目概览与架构全景

系列第 1 篇。内容:OpenClaw 是什么、设计理念、整体架构、启动流程。

OpenClaw 是什么

一句话概括:OpenClaw 是一个开源的多通道 AI 网关(Multi-channel AI Gateway),用 TypeScript 编写,运行在你自己的设备上。

它的核心能力包括:

  • 接入 30+ 消息渠道 —— WhatsApp、Telegram、Discord、Slack、iMessage、Signal、Matrix、IRC、Microsoft Teams、Feishu(飞书)、Line、Zalo、Nostr、Twitch 等
  • 提供 macOS、iOS、Android 原生客户端,外加 Web UI 和终端 TUI
  • 内置 52 个技能(skills)和 40 个扩展插件(extensions)
  • 支持主流模型提供商,通过 mcporter 桥接 MCP 协议

OpenClaw 是一个本地优先的 AI 代理编排系统,可以在你的电脑上实际执行任务。

项目演化史

VISION.md 里记录了项目历史:

OpenClaw started as a personal playground to learn AI and build something genuinely useful: an assistant that can run real tasks on a real computer. It evolved through several names and shells: Warelay → Clawdbot → Moltbot → OpenClaw.

项目改过几次名:Warelay → Clawdbot → Moltbot → OpenClaw。

核心设计理念

VISION.mdSECURITY.md 整理出五个设计原则:

1. 本地优先(Local-first)

“It runs on your devices, in your channels, with your rules.”

OpenClaw 网关运行在你自己的机器上,不依赖第三方托管服务。数据不离开你的设备(除非你主动连接外部模型提供商)。

2. 隐私安全(Single-operator trust model)

安全模型的核心假设是”单操作者”—— 运行 OpenClaw 的人就是信任边界的唯一主体。这意味着强默认值(secure defaults)加上显式的控制旋钮(explicit knobs),而不是牺牲能力换安全。src/security/ 下有 28 个文件专门处理审计、DM 策略、密钥比较、路径扫描等安全逻辑。

3. 多平台覆盖

一套核心代码,覆盖 macOS/iOS/Android 原生应用、Web UI、终端 TUI,外加 40 个渠道扩展。apps/ 目录下有四个子项目:macosiosandroidshared(跨平台 Swift 包)。

4. 可扩展(Plugin system)

核心保持精简(lean core),可选能力通过插件分发。VISION.md 明确说:

Core stays lean; optional capability should usually ship as plugins.

插件通过 npm 包分发,新技能优先发布到 ClawHub(clawhub.ai),而不是塞进核心。

5. 终端优先(Terminal-first by design)

“OpenClaw is currently terminal-first by design. This keeps setup explicit: users see docs, auth, permissions, and security posture up front.”

这样安全决策始终对用户可见。

整体架构

OpenClaw 的整体架构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
          ┌──────────────────────────────────────────┐
│ Clients 客户端层 │
│ macOS App · iOS · Android · Web UI · TUI │
└────────────────────┬─────────────────────┘
│ WebSocket / HTTP
┌────────────────────▼─────────────────────┐
│ Gateway 网关核心 │
│ src/gateway/ (server.impl.ts) │
│ 认证 · 路由 · 会话管理 · 端口锁 │
└──┬──────────┬──────────┬─────────────────┘
│ │ │
┌────────────▼┐ ┌─────▼─────┐ ┌─▼──────────────┐
│ Channels │ │ Agents │ │ Tools │
│ 消息渠道层 │ │ AI 代理 │ │ 工具 & 技能 │
│ │ │ │ │ │
│ WhatsApp │ │ 运行时 │ │ 52 skills/ │
│ Telegram │ │ 沙箱 │ │ MCP (mcporter) │
│ Discord │ │ 认证档案 │ │ hooks │
│ Slack │ │ schema │ │ plugins │
│ iMessage │ │ │ │ │
│ Signal │ │ │ │ │
│ +35 more │ │ │ │ │
└──────────────┘ └───────────┘ └─────────────────┘
│ │ │
┌────────────▼──────────▼──────────▼─────────────────┐
│ Extensions 扩展层 │
│ extensions/* (40 个插件包) │
│ matrix · msteams · voice-call · memory · lobster… │
└────────────────────────────────────────────────────┘

数据流是双向的:用户从某个消息渠道(比如 Telegram)发一条消息,经过 Gateway 路由到对应的 Agent,Agent 调用 Tools/Skills 执行任务,结果原路返回。

技术栈选择

package.json 版本号 2026.3.2,有 157+ 个 npm scripts、59 个运行时依赖。核心技术栈:

领域 选型 备注
语言 TypeScript (ESM, strict) 严格模式,避免 any
运行时 Node 22+ 同时保持 Bun 兼容
包管理 pnpm monorepo pnpm-workspace.yaml 管理 uipackages/*extensions/*
构建 tsdown Rust 实现的 TypeScript 打包器,多入口配置
测试 Vitest + V8 覆盖率 70% 行/分支/函数/语句覆盖率门槛
Lint Oxlint (type-aware) Rust 实现,替代 ESLint
格式化 Oxfmt Rust 实现,替代 Prettier
类型检查 TypeScript 5.9 + tsgo tsgo 是 TypeScript 的原生 Go 实现预览版
CLI 框架 Commander + @clack/prompts 终端交互体验

Oxlint、Oxfmt 都是 Rust 实现(Oxc 项目),tsdown 底层也是 Rust(Rolldown),类型检查用了 tsgo(TypeScript 团队的 Go 原生实现)。工具链整体在往原生编译语言方向迁移。

为什么选 TypeScript

VISION.md 的说法:

OpenClaw is primarily an orchestration system: prompts, tools, protocols, and integrations. TypeScript was chosen to keep OpenClaw hackable by default. It is widely known, fast to iterate in, and easy to read, modify, and extend.

OpenClaw 的核心工作是把 prompts、tools、protocols、integrations 串起来,TypeScript 适合这类编排逻辑:生态成熟、类型安全、上手门槛低。

目录结构速览

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
openclaw/
├── src/ # 核心源码(2470+ 个 TS 文件,不含测试)
│ ├── gateway/ # WebSocket/HTTP 网关服务
│ ├── agents/ # AI 代理运行时、沙箱、认证档案、工具
│ ├── channels/ # 通道抽象层(allowlists、transport、plugins)
│ ├── cli/ # CLI 入口、参数解析、命令路由
│ ├── commands/ # 具体 CLI 命令实现
│ ├── plugins/ # 插件系统运行时
│ ├── security/ # 安全审计(28 个文件)
│ ├── routing/ # 消息路由
│ ├── media/ # 媒体管线(图片、音频、视频处理)
│ ├── media-understanding/ # 媒体理解(视觉、音频分析)
│ ├── providers/ # 模型提供商抽象
│ ├── hooks/ # 生命周期钩子(含 bundled hooks)
│ ├── sessions/ # 会话管理
│ ├── memory/ # 记忆系统
│ ├── config/ # 配置管理
│ ├── infra/ # 基础设施(env、dotenv、错误处理、端口管理)
│ ├── terminal/ # 终端 UI(表格、主题、颜色)
│ ├── tui/ # 终端用户界面
│ ├── tts/ # 文本转语音
│ ├── telegram/ # Telegram 渠道实现
│ ├── discord/ # Discord 渠道实现
│ ├── slack/ # Slack 渠道实现
│ ├── signal/ # Signal 渠道实现
│ ├── imessage/ # iMessage 渠道实现
│ ├── whatsapp/ # WhatsApp 渠道实现
│ ├── web/ # WhatsApp Web 提供者
│ ├── plugin-sdk/ # 插件 SDK
│ ├── i18n/ # 国际化
│ └── ... # 更多子模块
├── extensions/ # 40 个扩展插件(workspace 包)
├── apps/ # 原生应用
│ ├── macos/ # macOS 菜单栏应用
│ ├── ios/ # iOS 应用
│ ├── android/ # Android 应用
│ └── shared/ # 跨平台 Swift 包
├── ui/ # Web UI(Lit + Vite)
├── skills/ # 52 个内置技能
├── docs/ # 文档(Mintlify,含 zh-CN、ja-JP)
├── packages/ # 共享包
├── patches/ # pnpm 补丁
└── blog/ # 博客文章

一些数据:

  • src/ 下有 2470+ 个非测试 TypeScript 文件
  • extensions/ 下有 40 个插件包
  • skills/ 下有 52 个内置技能
  • package.json 里有 157+ 个 npm scripts

启动流程

运行 openclaw gateway run 时的调用链:

第一层:openclaw.mjs — 引导入口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// openclaw.mjs
import module from "node:module";

// 启用 Node.js 编译缓存,加速后续启动
if (module.enableCompileCache && !process.env.NODE_DISABLE_COMPILE_CACHE) {
try {
module.enableCompileCache();
} catch {
// Ignore errors
}
}

// 安装警告过滤器,保持引导阶段与 TypeScript 运行时一致
await installProcessWarningFilter();

// 尝试加载构建产物
if (await tryImport("./dist/entry.js")) {
// OK
} else if (await tryImport("./dist/entry.mjs")) {
// OK
} else {
throw new Error("openclaw: missing dist/entry.(m)js (build output).");
}

这个文件只做三件事:启用编译缓存、过滤警告、加载 dist/entry.js

第二层:src/entry.ts — 重生守卫与快速路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// src/entry.ts(简化)
process.title = "openclaw";
installProcessWarningFilter();
normalizeEnv();
enableCompileCache();

// 重生守卫:确保 ExperimentalWarning 被抑制
if (!ensureExperimentalWarningSuppressed()) {
// 快速路径:--version 和 --help 不需要加载完整 CLI
if (!tryHandleRootVersionFastPath(process.argv)
&& !tryHandleRootHelpFastPath(process.argv)) {
// 正常路径:加载完整 CLI
const { runCli } = await import("./cli/run-main.js");
await runCli(process.argv);
}
}

ensureExperimentalWarningSuppressed() 检查当前进程是否已经带了 --disable-warning=ExperimentalWarning 标志。如果没有,它会重新 spawn 一个带该标志的子进程,然后让父进程退出。通过 OPENCLAW_NODE_OPTIONS_READY 环境变量防止无限递归。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 重生守卫的核心逻辑
function ensureExperimentalWarningSuppressed(): boolean {
if (isTruthyEnvValue(process.env.OPENCLAW_NODE_OPTIONS_READY)) {
return false; // 已经重生过,不再重复
}
process.env.OPENCLAW_NODE_OPTIONS_READY = "1";
const child = spawn(
process.execPath,
[EXPERIMENTAL_WARNING_FLAG, ...process.execArgv, ...process.argv.slice(1)],
{ stdio: "inherit", env: process.env }
);
// 父进程等待子进程退出,不继续执行 CLI
return true;
}

快速路径(fast path)则是另一个性能优化:--version 只需要读一个版本号,--help 只需要构建 Commander 程序,都不需要加载完整的配置、插件和网关逻辑。

第三层:src/cli/run-main.ts — 命令路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// src/cli/run-main.ts
export async function runCli(argv: string[] = process.argv) {
const normalizedArgv = normalizeWindowsArgv(argv);
loadDotEnv({ quiet: true }); // 加载 .env 文件
normalizeEnv(); // 规范化环境变量
ensureOpenClawCliOnPath(); // 确保 CLI 在 PATH 上
assertSupportedRuntime(); // 检查 Node 版本

if (await tryRouteCli(normalizedArgv)) {
return; // 快速路由命中
}

enableConsoleCapture();
const { buildProgram } = await import("./program.js");
const program = buildProgram(); // 构建 Commander 程序

// 注册核心命令和插件命令
const primary = getPrimaryCommand(parseArgv);
await registerCoreCliByName(program, ctx, primary, parseArgv);
await registerSubCliByName(program, primary);

// 注册插件 CLI 命令
if (!shouldSkipPluginRegistration) {
const { registerPluginCliCommands } = await import("../plugins/cli.js");
registerPluginCliCommands(program, loadConfig());
}

await program.parseAsync(parseArgv); // Commander 接管
}

第四层:网关启动

当命令是 gateway run 时,Commander 路由到 src/cli/gateway-cli/run.ts

1
2
3
4
5
6
7
8
9
10
// src/cli/gateway-cli/run.ts
import { startGatewayServer } from "../../gateway/server.js";

// 加载配置、解析端口、解析认证模式
const config = loadConfig();
const port = resolveGatewayPort(config);
const auth = resolveGatewayAuth(config);

// 启动 WebSocket 网关服务
await startGatewayServer({ config, port, auth, ... });

startGatewayServer 的实现在 src/gateway/server.impl.ts(第 195 行),它负责创建 WebSocket 服务、初始化路由、加载渠道和插件。

完整的启动链路如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
openclaw.mjs
│ 启用编译缓存,加载 dist/entry.js

src/entry.ts
│ 重生守卫(添加 --disable-warning)
│ 快速路径:--version / --help 提前返回

src/cli/run-main.ts → runCli()
│ 加载 .env,规范化环境变量
│ 构建 Commander 程序,注册核心 + 插件命令

src/cli/gateway-cli/run.ts
│ 加载配置,解析端口和认证模式

src/gateway/server.impl.ts → startGatewayServer()
│ 创建 WebSocket 服务
│ 初始化路由、渠道、代理
└─ 网关就绪,开始接收连接

构建产物

tsdown.config.ts 定义了 8 个构建入口,每个入口生成独立的产物:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// tsdown.config.ts
export default defineConfig([
{ entry: "src/index.ts" }, // 库导出(供外部包 import)
{ entry: "src/entry.ts" }, // CLI 运行时入口
{ entry: "src/cli/daemon-cli.ts" }, // 守护进程 CLI
{ entry: "src/infra/warning-filter.ts" }, // 警告过滤器(引导阶段用)
{ entry: "src/plugin-sdk/index.ts", // 插件 SDK
outDir: "dist/plugin-sdk" },
{ entry: "src/plugin-sdk/account-id.ts", // 插件 SDK 账号模块
outDir: "dist/plugin-sdk" },
{ entry: "src/extensionAPI.ts" }, // 扩展 API
{ entry: ["src/hooks/bundled/*/handler.ts", // 内置 hook 处理器
"src/hooks/llm-slug-generator.ts"] },
]);

值得注意的几点:

  • src/index.tssrc/entry.ts 是两个不同的入口。index.ts 是库导出,供其他包通过 import { ... } from "openclaw" 使用;entry.ts 是 CLI 入口,包含进程管理逻辑。
  • plugin-sdk 单独输出到 dist/plugin-sdk/,这样插件开发者可以通过 openclaw/plugin-sdk 路径导入。
  • 内置 hooks 使用 glob 模式 src/hooks/bundled/*/handler.ts 匹配,目前包括 boot-mdbootstrap-extra-filescommand-loggersession-memory 四个。
  • 所有入口都设置 platform: "node"NODE_ENV: "production"

系列文章预告

系列第 1 篇,后续文章:

  1. 项目概览与架构全景(本文)
  2. 网关核心:WebSocket 服务与消息路由
  3. 渠道抽象层:如何统一 30+ 消息平台
  4. AI 代理运行时:从 prompt 到 tool call
  5. 插件系统:设计、加载与生命周期
  6. 安全模型:审计、策略与信任边界
  7. 媒体管线:图片、音频、视频的处理链路
  8. CLI 与终端 UI:Commander、clack 与 TUI
  9. 原生应用:macOS/iOS/Android 的 Swift 与 Kotlin 架构
  10. 构建、测试与发布:从 tsdown 到 npm publish

本文基于 OpenClaw v2026.3.2 源码分析。项目仓库:github.com/openclaw/openclaw