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.md 和 SECURITY.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/ 目录下有四个子项目:macos、ios、android、shared(跨平台 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 管理 ui、packages/*、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 import module from "node:module" ;if (module .enableCompileCache && !process.env .NODE_DISABLE_COMPILE_CACHE ) { try { module .enableCompileCache (); } catch { } } await installProcessWarningFilter ();if (await tryImport ("./dist/entry.js" )) { } else if (await tryImport ("./dist/entry.mjs" )) { } 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 process.title = "openclaw" ; installProcessWarningFilter ();normalizeEnv ();enableCompileCache ();if (!ensureExperimentalWarningSuppressed ()) { if (!tryHandleRootVersionFastPath (process.argv ) && !tryHandleRootHelpFastPath (process.argv )) { 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 } ); 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 export async function runCli (argv : string [] = process.argv ) { const normalizedArgv = normalizeWindowsArgv (argv); loadDotEnv ({ quiet : true }); normalizeEnv (); ensureOpenClawCliOnPath (); assertSupportedRuntime (); if (await tryRouteCli (normalizedArgv)) { return ; } enableConsoleCapture (); const { buildProgram } = await import ("./program.js" ); const program = buildProgram (); const primary = getPrimaryCommand (parseArgv); await registerCoreCliByName (program, ctx, primary, parseArgv); await registerSubCliByName (program, primary); if (!shouldSkipPluginRegistration) { const { registerPluginCliCommands } = await import ("../plugins/cli.js" ); registerPluginCliCommands (program, loadConfig ()); } await program.parseAsync (parseArgv); }
第四层:网关启动 当命令是 gateway run 时,Commander 路由到 src/cli/gateway-cli/run.ts:
1 2 3 4 5 6 7 8 9 10 import { startGatewayServer } from "../../gateway/server.js" ;const config = loadConfig ();const port = resolveGatewayPort (config);const auth = resolveGatewayAuth (config);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 export default defineConfig ([ { entry : "src/index.ts" }, { entry : "src/entry.ts" }, { entry : "src/cli/daemon-cli.ts" }, { entry : "src/infra/warning-filter.ts" }, { entry : "src/plugin-sdk/index.ts" , outDir : "dist/plugin-sdk" }, { entry : "src/plugin-sdk/account-id.ts" , outDir : "dist/plugin-sdk" }, { entry : "src/extensionAPI.ts" }, { entry : ["src/hooks/bundled/*/handler.ts" , "src/hooks/llm-slug-generator.ts" ] }, ]);
值得注意的几点:
src/index.ts 和 src/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-md、bootstrap-extra-files、command-logger、session-memory 四个。
所有入口都设置 platform: "node" 和 NODE_ENV: "production"。
系列文章预告 系列第 1 篇,后续文章:
项目概览与架构全景 (本文)
网关核心:WebSocket 服务与消息路由
渠道抽象层:如何统一 30+ 消息平台
AI 代理运行时:从 prompt 到 tool call
插件系统:设计、加载与生命周期
安全模型:审计、策略与信任边界
媒体管线:图片、音频、视频的处理链路
CLI 与终端 UI:Commander、clack 与 TUI
原生应用:macOS/iOS/Android 的 Swift 与 Kotlin 架构
构建、测试与发布:从 tsdown 到 npm publish
本文基于 OpenClaw v2026.3.2 源码分析。项目仓库:github.com/openclaw/openclaw