OpenClaw学习笔记
2025 年 11 月 24 日,一个名为 OpenClaw 的开源项目在 GitHub 上悄然创建。四个月后,它的 Star 数突破 343,000,成为近年来增速最快的非聚合类开源项目之一,超过了 React、Vue 和 Tailwind CSS 在同等时间段内的增长速度。这条陡峭的增长曲线背后,是一个清晰的价值主张:让每个人都能在自己的设备上运行一个完全属于自己的 AI 助手。
OpenClaw 的一句话定位是 "Your own personal AI assistant. Any OS. Any Platform. The lobster way. "。这句话的核心不在于功能描述,而在于哲学立场——本地优先(Local-First)不是一个功能选项,而是整个系统的设计前提。在 AI 助手普遍依赖云端服务的 2025 年,这个立场击中了开发者群体中日益强烈的数据主权(Data Sovereignty)诉求。
"The lobster way" 不只是一句口号。龙虾(Lobster)意象贯穿了整个项目:工作流编排工具命名为 Lobster,社区成员自称 lobster,甚至 GitHub 上的口号 "EXFOLIATE! EXFOLIATE!"(蜕皮!蜕皮!)暗示项目的激进重构和快速迭代哲学——龙虾通过周期性蜕壳实现生长,OpenClaw 通过频繁的破坏性变更实现架构进化。
从工程视角看,OpenClaw 的核心技术栈——TypeScript ESM、pnpm monorepo、230 条 Plugin SDK 导出路径、24 个消息渠道接入——构成了一个在单一代码仓库中管理 AI Agent 平台全生命周期的案例研究。无论是 Rust/Go 工具替代传统 JS 工具链(oxfmt 替代 Prettier、oxlint 替代 ESLint、tsdown 替代 webpack)、TypeScript 原生 Go 编译器预览集成、还是 Docker 多阶段构建中对 QEMU 交叉编译的优雅降级处理——这些工程细节比功能特性更能说明项目的技术深度。
项目采用 MIT 协议,赞助商包括 OpenAI、NVIDIA、Vercel、Blacksmith 和 Convex——一家云端 AI 公司赞助一个本地优先的开源竞争者,这本身就是值得深思的战略信号。本文基于 OpenClaw 官方仓库(github.com/openclaw/openclaw)v2026.4.1 的实际代码,从仓库结构、插件架构、渠道系统、Agent 运行时、内存系统、安全模型到多端原生应用,进行完整的技术剖析。所有代码引用均来自一手数据,不依赖二手社区资料。
在深入代码之前,先建立全局视角。OpenClaw 的架构可以用四层模型概括:最上层是 Gateway(控制平面),以 WebSocket 服务(默认 ws://127.0.0.1:18789)承载会话管理、配置下发、Cron 调度、Webhook 和健康检查,同时托管 Control UI(Lit 3 + Vite)和 Canvas 宿主(A2UI)。第二层是 Agent / Pi Runtime(智能体运行时),基于 @mariozechner/pi-agent-core@0.64.0,以 RPC 模式运行,支持工具流(Tool Streaming)和块流(Block Streaming),接入 25+ 模型提供者并具备 Auth 轮换和 Failover 能力。第三层是 Channels + Skills(渠道与技能层),覆盖 24 个消息平台,通过 Plugin SDK 的 230 条契约路径与核心交互,ClawHub 市场和 before_install 安全钩子管控技能安装,Browser、Canvas、Nodes、Cron、Sessions 等一等工具也位于此层。最底层是 Memory(记忆层),由 memory-core 的 13 个子模块组成,以本地 Markdown 文件持久化、sqlite-vec 向量搜索和 LanceDB 为存储后端,承载用户可编辑偏好与长期上下文。
Gateway 是唯一的控制平面入口,所有客户端(CLI、Web UI、macOS App、iOS/Android 节点)都通过 WebSocket 连接到 Gateway。Agent 运行时以 RPC 模式挂载在 Gateway 下,接收来自各渠道的消息,调用模型和工具,将结果路由回发送者所在的渠道。Skills 和 Channels 通过 Plugin SDK 的 230 条导出路径与核心交互,Memory 层则为 Agent 提供跨会话的长期记忆能力。
这四层的每一层都有严格的边界约束。Gateway 层通过 src/gateway/protocol/schema.ts 定义类型化 WebSocket 协议,Agent 层通过 Pi 的 RPC 接口暴露能力,Plugin SDK 是扩展与核心之间唯一合法的导入面,Memory 层通过 13 个细粒度子模块避免单体耦合。下文将逐层展开。
OpenClaw 并非从零开始。在当前命名之前,它先后经历了 MoltBot 和 ClawdBot 两个阶段。这段历史在代码库中留有痕迹:package.json 的 scripts 字段至今保留着 "moltbot:rpc" 命令,指向与 "openclaw:rpc" 完全相同的实现。文档域名 docs.molt.bot 也仍以 301 重定向的方式指向当前的 docs.openclaw.ai。
项目由奥地利开发者 Peter Steinberger(GitHub: @steipete)主导,其在仓库中拥有 14,756 个提交,远超第二贡献者(1,690 个)。Steinberger 此前以 iOS SDK 生态的贡献著称,转型为 AI Agent 平台开发者,并将高频迭代、激进重构的风格延续到了 OpenClaw 的开发中。
OpenClaw 采用日历版本(Calendar Versioning)而非语义版本(Semantic Versioning)。版本格式为 vYYYY.M.D(例如 v2026.4.1),直接反映发布日期。当同一天有多个发布时,追加补丁后缀 vYYYY.M.D-N。
发布频道分为三层,通过 npm dist-tag 映射:
| 频道 | npm dist-tag | Tag 格式 | 适用场景 |
| stable | latest | vYYYY.M.D | 生产环境,默认安装 |
| beta | beta | vYYYY.M.D-beta.N | 预发布验证,macOS App 可能缺席 |
| dev | dev | main 分支头 | 开发调试,按需发布 |
切换频道使用 openclaw update --channel stable|beta|dev。Beta 发布时,npm 版本号必须携带 -beta.N 后缀,不能使用不带后缀的版本号配合 --tag beta 发布,否则版本名会被消耗掉——这是仓库 AGENTS.md 中明确记录的发布守则。
截至本文写作时,最新的 stable 版本为 v2026.3.31(2026-03-31 发布)。该版本包含 六项破坏性变更(Breaking Changes),密度之高反映了 OpenClaw 激进的迭代风格:
- Nodes/exec 重构:移除了 CLI 和 Agent nodes 工具中重复的 nodes.run shell 封装器,所有节点 shell 执行统一走 exec host=node 路径。节点特有能力保留在 nodes invoke 和专用的 media/location/notify 操作上。
- Plugin SDK 遗留路径弃用:弃用旧版 provider 兼容子路径以及旧版 bundled provider setup 和 channel-runtime 兼容垫片(compatibility shims),发出迁移警告。当前文档化的 openclaw/plugin-sdk/* 入口加上本地 api.ts / runtime-api.ts 桶文件是唯一的前进路径。
- 插件安装安全收紧:内建的危险代码(dangerous-code)critical 级发现和安装时扫描失败现在默认拒绝(fail closed)。此前能成功安装的部分插件现在需要显式指定 --dangerously-force-unsafe-install 标志才能继续。
- Gateway 认证收紧:trusted-proxy 模式拒绝混合共享令牌配置;本地直连回退(local-direct fallback)要求使用配置的令牌,不再隐式认证同主机调用者。
- 节点命令门控:节点命令在节点配对获批(node pairing approved)之前保持禁用状态。仅完成设备配对不再足以暴露声明的节点命令。
- 节点事件信任面缩减:节点发起的运行(node-originated runs)现在在缩减的受信表面(reduced trusted surface)上执行,依赖更广泛 host/session 工具访问权限的通知驱动或节点触发流程可能需要调整。
这种"每个版本都可能有 Breaking Changes"的策略与日历版本号的选择相呼应——既然不提供语义化的兼容性承诺,那就用发布日期明确标识每一次快照。对于使用者,官方建议锁定到特定版本号并在升级前阅读 CHANGELOG。
前一个重要版本 v2026.3.28(2026-03-29 发布)同样包含多项重要变更:
- xAI 深度整合:bundled xAI provider 迁移至 Responses API,新增原生 x_search(Grok 网页搜索工具),并在 openclaw onboard 中集成可选的 x_search 配置步骤。
- MiniMax 图像生成:新增 MiniMax image-01 模型的图像生成和图生图编辑能力,支持宽高比控制。
- Qwen 认证迁移:移除已弃用的 qwen-portal-auth OAuth 集成,迁移至 Model Studio API Key 模式。
- Plugins/hooks 审批机制:before_tool_call 钩子新增异步 requireApproval 能力,插件可以暂停工具执行并通过 Telegram 按钮、Discord 交互、/approve 命令等渠道提示用户审批。
- Microsoft Teams 升级:迁移至官方 Teams SDK,支持 1:1 对话的流式回复和 AI 标注。
- Gateway OpenAI 兼容性:新增 /v1/models 和 /v1/embeddings 端点,使 Gateway 可以被 OpenAI 兼容的第三方工具直接调用。
OpenClaw 是一个 pnpm workspace monorepo,根目录的核心布局如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
openclaw/ ├── src/ # 核心源码 │ ├── cli/ # CLI 命令入口与进度条 │ ├── commands/ # 各子命令实现 │ ├── gateway/ # Gateway 控制平面(含 protocol/ 子目录) │ ├── channels/ # 核心渠道实现 │ ├── routing/ # 消息路由 │ ├── plugins/ # 插件发现、加载、注册 │ ├── plugin-sdk/# 公开插件契约(唯一合法导入面) │ ├── infra/ # 基础设施(SQLite、文件锁等) │ └── media/ # 媒体处理管道 ├── apps/ │ ├── macos/ # SwiftUI + AppKit 菜单栏应用 │ ├── ios/ # Xcode + SwiftUI │ └── android/ # Kotlin + Gradle ├── extensions/ # 内部扩展(bundled plugin workspace tree) ├── packages/ # 共享包 ├── skills/ # 内置 Skills(随 npm 包分发) ├── ui/ # Web Control UI(Lit 3 + Vite) ├── docs/ # Mintlify 文档 ├── test/ # E2E 测试 └── scripts/ # 构建/发布/检查脚本(60+个) |
这棵目录树揭示了 OpenClaw 的工程哲学:核心尽量薄,边界尽量硬。src/ 存放所有 TypeScript 核心代码,extensions/ 存放内建扩展(bundled plugin workspace tree),apps/ 存放三个原生客户端。三者之间的导入关系是单向的:extensions/ 只能通过 openclaw/plugin-sdk/* 调用核心能力,apps/ 通过 Gateway WebSocket 协议与核心通信。任何反向依赖都会被 CI 的架构守卫脚本拦截。
extensions/ 是 bundled plugin workspace tree——即随 npm 包一起发布的内建扩展。Matrix、Zalo、ZaloUser、Voice Call 等渠道插件以及诊断遥测(diagnostics-otel)都存放在此。每个扩展是一个独立的 pnpm workspace 包,拥有自己的 package.json 和 openclaw.plugin.json 清单文件。扩展的运行时依赖必须声明在自身的 dependencies 中,不能添加到根 package.json(除非核心也使用了同一依赖)。而 workspace:* 在 dependencies 中是被禁止的(因为 npm install 无法解析 workspace 协议),openclaw 本身应放入 devDependencies 或 peerDependencies,运行时通过 jiti 别名解析 openclaw/plugin-sdk。
packages/ 存放的则是纯粹的共享库包,不含插件清单,不走插件加载管线。它们提供跨包复用的工具函数和类型定义。
skills/ 目录存放内置 Skills(Bundled Skills)——它们随 npm 包一起分发,安装后即可使用。与 ClawHub 上的第三方 Skill 不同,内置 Skill 不需要 clawhub install,也不走 before_install 安全检查管线。每个 Skill 由一个 SKILL.md 文件描述,该文件在 Agent 运行时被注入到系统提示中。
docs/ 使用 Mintlify 框架构建,部署在 docs.openclaw.ai。文档内部链接采用根相对路径(如 [Config](/configuration)),不带 .md 扩展名。文档支持中文翻译,中文版位于 docs/zh-CN/,由 scripts/docs-i18n 脚本自动生成,辅以术语表 docs/.i18n/glossary.zh-CN.json 和翻译记忆 docs/.i18n/zh-CN.tm.jsonl 保证术语一致性。
scripts/ 目录包含 60 多个独立脚本文件,加上 package.json 中的 198 个 npm scripts 入口,构成了 OpenClaw 极其精细的构建自动化体系。脚本按用途可分为以下几类:
- 构建脚本:tsdown-build.mjs(主构建入口)、runtime-postbuild.mjs(构建后处理)、bundle-a2ui.sh(Canvas A2UI 打包)、ui.js(Web UI 构建)
- 代码检查脚本:check-extension-plugin-sdk-boundary.mjs(扩展导入边界检查,三种模式)、check-plugin-extension-import-boundary.mjs(核心不得反向导入扩展内部)、check-no-pairing-store-group-auth.mjs(安全认证审计)
- 发布脚本:openclaw-npm-release-check.ts(发布前校验)、plugin-npm-release-plan.ts(插件发布计划)、openclaw-npm-postpublish-verify.ts(发布后验证)
- 平台脚本:package-mac-app.sh(macOS 打包)、ios-configure-signing.sh(iOS 签名)、build-release-aab.ts(Android AAB 构建)
- 测试脚本:test-parallel.mjs(并行测试编排器)、test-live.mjs(真实 API Key 测试)、8 个 e2e/*.sh Docker E2E 测试场景
- 运维脚本:committer(原子提交工具,取代手动 git add/commit)、restart-mac.sh(macOS Gateway 重启)、clawlog.sh(macOS 统一日志查询)
OpenClaw 的依赖控制极为精简。根 package.json 仅声明 47 个运行时依赖和 22 个开发时依赖。关键依赖的版本锁定如下:
| 依赖 | 版本 | 用途 |
| @mariozechner/pi-agent-core | 0.64.0 | Agent 运行时核心 |
| @agentclientprotocol/sdk | 0.17.1 | ACP 协议 SDK |
| @modelcontextprotocol/sdk | 1.29.0 | MCP 协议 SDK |
| matrix-js-sdk | 41.3.0-rc.0 | Matrix 渠道 |
| playwright-core | 1.58.2 | 浏览器控制 |
| sqlite-vec | 0.1.9 | 向量存储 |
| sharp | ^0.34.5 | 图像处理 |
| hono | 4.12.9 | HTTP 框架 |
| express | ^5.2.1 | 兼容层 |
| zod | ^4.3.6 | 运行时校验 |
| ws | ^8.20.0 | WebSocket |
| undici | ^7.24.6 | HTTP 客户端 |
开发依赖中最值得关注的是 @typescript/native-preview@7.0.0-dev.20260331.1——这是 TypeScript 官方的 Go 语言重写版预览,OpenClaw 已将其集成为 pnpm tsgo 命令。vitest@4.1.2 搭配 @vitest/coverage-v8 提供覆盖率检测,tsdown@0.21.7 取代 webpack/rollup 作为打包器,oxfmt@0.43.0 和 oxlint@1.58.0 则分别替代 Prettier 和 ESLint。这套工具链的选型思路清晰:用 Rust/Go 编写的原生工具替换 JavaScript 编写的传统方案,以获得数量级的性能提升。
所有带有 pnpm.patchedDependencies 的依赖必须使用精确版本号(不允许 ^ 或 ~ 前缀),且依赖补丁需要显式审批。此外,仓库明确规定"永远不要更新 Carbon 依赖"——这是一条写入 AGENTS.md 的硬性规则。
上一章给出了 src/ 的一级目录骨架。本章逐一展开每个子目录的内部设计,以代码结构和依赖关系为主线,解释 OpenClaw 核心源码的工程分层。
src/cli/ 是整个 OpenClaw 命令行工具的入口层。它不包含任何业务逻辑,只负责两件事:解析命令行参数并路由到 src/commands/ 中的具体实现,以及在终端渲染结构化进度反馈。
进度反馈的核心位于 src/cli/progress.ts。该模块同时使用两套机制:
第一套是 OSC 进度序列(Operating System Command Progress Sequences)。这是一组终端转义码,允许在支持 ConPTY 的 Windows Terminal、iTerm2 和部分 Linux 终端中直接在标题栏或标签页上显示百分比进度条。progress.ts 通过向 stdout 写入 \x1b]9;4;1;{percent}\x07 序列驱动操作系统级别的进度指示器,这使得即使终端窗口被最小化,用户仍可在任务栏中看到安装进度。
第二套是 @clack/prompts,一个轻量级的交互式终端 UI 库。OpenClaw 用它实现 onboard 向导中的步骤指示器、多选菜单和确认提示。@clack/prompts 的 spinner 与 OSC 进度可以并行工作——spinner 渲染在 stdout 的当前行,OSC 序列渲染在终端标题栏,两者互不干扰。
|
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 |
// src/cli/progress.ts 核心逻辑简化示意 import { spinner } from '@clack/prompts'; export function emitOscProgress(percent: number): void { process.stdout.write(`\x1b]9;4;1;${Math.round(percent)}\x07`); } export function clearOscProgress(): void { process.stdout.write(`\x1b]9;4;0;\x07`); } export async function withProgress<T>( label: string, task: (update: (pct: number) => void) => Promise<T> ): Promise<T> { const s = spinner(); s.start(label); const result = await task((pct) => { emitOscProgress(pct); s.message(`${label} (${pct}%)`); }); clearOscProgress(); s.stop(`${label} ✔`); return result; } |
src/commands/ 中的每个文件对应一个顶级 CLI 子命令。文件命名遵循 {command}.ts 模式,如 start.ts、stop.ts、update.ts、onboard.ts、config.ts、plugin.ts。
其中最复杂的是 onboard.ts,即首次运行向导。Onboard 向导的执行流程为:检测系统环境(Node.js 版本、平台、包管理器)→ 选择消息渠道(Telegram/Discord/Slack 等)→ 输入渠道凭据(Bot Token 等)→ 选择 AI Provider(OpenAI/Anthropic/Ollama 等)→ 输入 Provider API Key → 写入配置文件 ~/.openclaw/config.yaml → 执行首次 npm install --omit=dev 安装所选渠道的扩展依赖。整个流程由 @clack/prompts 驱动,每个步骤都有 spinner 和进度条反馈。
src/gateway/ 是 OpenClaw 的中枢。它在本地启动一个 WebSocket 服务(默认监听 ws://127.0.0.1:18789),充当所有渠道、插件、原生客户端和 Control UI 之间的 单一控制平面(Single Control Plane)。
目录结构大致如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
src/gateway/ ├── server.ts # WebSocket 服务器生命周期 ├── router.ts # 协议消息分发 ├── session.ts # 会话管理 ├── presence.ts # 在线状态 ├── config.ts # 运行时配置 Hot-reload ├── cron.ts # 定时任务调度 ├── webhooks.ts # 外部 webhook 接入 ├── auth.ts # 认证模型 ├── health.ts # /healthz, /readyz 端点 ├── openai-compat.ts # /v1/models, /v1/embeddings 兼容层 └── protocol/ ├── schema.ts # 协议 Schema 聚合入口 └── schema/ # 按领域拆分的 Schema 定义文件 ├── sessions.ts ├── nodes.ts ├── channels.ts └── ... |
protocol/ 子目录是 Gateway 的类型层。所有 WebSocket 消息都经由 protocol/schema.ts 聚合导出的 TypeScript 类型定义进行序列化和反序列化。schema/ 内的文件按领域组织(sessions、nodes、channels 等),每个文件导出请求/响应的 Zod Schema 或 TypeScript interface。这套 Schema 同时被用于 Swift codegen——macOS/iOS 原生应用中的 Gateway 客户端代码由构建脚本从这些 TypeScript 类型自动生成对应的 Swift struct。
Session 管理(session.ts)维护所有活跃会话的内存状态,包括会话 ID、关联渠道、关联 Agent、消息队列深度、最后活跃时间等。Presence(presence.ts)跟踪所有已连接客户端的在线状态,支持原生应用和 Web UI 实时显示哪些渠道处于在线。Cron(cron.ts)提供基于 cron 表达式的定时任务调度,用于周期性检查渠道连接状态和执行清理任务。Webhooks(webhooks.ts)为 Telegram webhook 模式和 Slack Events API 等需要 HTTP 回调的渠道提供端点注册。
src/channels/ 并非一个单一目录——OpenClaw 将核心渠道的代码分散在 src/ 下的多个一级目录中。具体映射关系为:
| 渠道 | 源码位置 | 底层依赖 |
| Telegram | src/telegram/ | grammY |
| Discord | src/discord/ | discord.js |
| Slack | src/slack/ | @slack/bolt |
| Signal | src/signal/ | signal-cli (Java 子进程) |
| iMessage | src/imessage/ | BlueBubbles HTTP API / 原生 imsg |
| src/web/ | Baileys (WhatsApp Web 协议) |
src/channels/ 本身作为聚合层存在,定义了所有渠道必须实现的 统一消息抽象接口和路由表。每个渠道目录内部的文件结构大致对称:一个 adapter 文件负责将平台 SDK 的事件映射为统一的 inbound 消息格式,一个 sender 文件负责将统一的 outbound 格式转换回平台特定的 API 调用。
消息路由引擎(src/routing/)是渠道系统和 Agent 运行时之间的中间层。它根据配置文件中的路由规则,将 inbound 消息分发到正确的 Agent 实例。路由维度包括:渠道类型、账号 ID、发送者 peer ID、群组 ID、消息内容匹配模式。多 Agent 场景下,路由引擎负责将不同渠道/账号/群组的消息隔离到不同 Agent 的会话中。
src/plugins/ 是插件系统的运行时宿主,不是插件本身。它包含四个核心模块:
Discovery:扫描 extensions/ workspace 和 ~/.openclaw/plugins/ 中已安装的 npm 包,查找包含 openclaw.plugin.json 清单文件的包。
Manifest Validation:用 Zod Schema 严格校验 openclaw.plugin.json 的结构。清单文件中的 id、channel.id、install.npmSpec 等字段必须符合预定义的格式。
Loader:对通过校验的插件执行动态 import(),加载其入口模块并调用约定的生命周期钩子。
Registry:维护全局插件注册表,记录每个已加载插件的类型、状态、能力声明。Registry 支持运行时热插拔——新安装的插件可以在不重启 Gateway 的情况下被 discovery → validate → load → register。
Contract Enforcement:通过 ESLint 规则在构建时确保插件只通过 openclaw/plugin-sdk/* 导入公开 API。任何直接引用 src/ 内部模块的插件都会在 CI 中被拦截。
src/plugin-sdk/ 是 OpenClaw 面向所有外部扩展的 唯一公开 API 面。package.json 的 exports 字段精确地声明了 230 条命名导出子路径,每一条都是一个稳定的契约。这 230 条子路径是插件开发的全部合法导入来源——没有例外。该目录的详细分析见下一章。
src/infra/ 封装与操作系统交互的底层能力。核心组件包括:基于 better-sqlite3 的本地持久化层(存储会话历史、插件状态、用户配置等),以及基于 proper-lockfile 的文件锁机制——确保同一台机器上不会出现两个 OpenClaw Gateway 实例同时操作同一个数据目录。SQLite 数据库文件默认位于 ~/.openclaw/data/openclaw.db。
src/media/ 实现了统一的媒体处理管道(Media Processing Pipeline)。当渠道接收到图片、音频、视频或文件消息时,该管道负责:下载原始媒体 → 格式检测 → 必要时进行转码(如 Opus → WAV 用于语音转文字)→ 存储到本地缓存 → 生成引用 URL 供 Agent 使用。管道设计为可插拔的,media plugin 可以注册自定义的 processor 处理特定 MIME 类型。
OpenClaw 的插件系统以 src/plugin-sdk/ 为核心,通过 package.json 的 exports 字段向外部暴露了 230 条精确的命名子路径。这是一个经过严格设计的 契约体系(Contract System)——它同时定义了插件能做什么和不能做什么。
package.json 的 exports 字段格式如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
{ "exports": { "./plugin-sdk/channel-types": "./src/plugin-sdk/channel-types.ts", "./plugin-sdk/channel-inbound": "./src/plugin-sdk/channel-inbound.ts", "./plugin-sdk/channel-reply-pipeline": "./src/plugin-sdk/channel-reply-pipeline.ts", "./plugin-sdk/channel-send-result": "./src/plugin-sdk/channel-send-result.ts", "./plugin-sdk/channel-dm-security": "./src/plugin-sdk/channel-dm-security.ts", "./plugin-sdk/provider-types": "./src/plugin-sdk/provider-types.ts", "./plugin-sdk/provider-registry": "./src/plugin-sdk/provider-registry.ts", "./plugin-sdk/memory-core-types": "./src/plugin-sdk/memory-core-types.ts", "./plugin-sdk/memory-core-store": "./src/plugin-sdk/memory-core-store.ts", "./plugin-sdk/plugin-manifest": "./src/plugin-sdk/plugin-manifest.ts", "./plugin-sdk/plugin-lifecycle": "./src/plugin-sdk/plugin-lifecycle.ts", "./plugin-sdk/runtime-config": "./src/plugin-sdk/runtime-config.ts", "./plugin-sdk/runtime-events": "./src/plugin-sdk/runtime-events.ts", "./plugin-sdk/media-types": "./src/plugin-sdk/media-types.ts", "./plugin-sdk/media-processor": "./src/plugin-sdk/media-processor.ts", "./plugin-sdk/speech-types": "./src/plugin-sdk/speech-types.ts", "./plugin-sdk/speech-engine": "./src/plugin-sdk/speech-engine.ts" // ... 共 230 条 } } |
这 230 条子路径按前缀可划分为以下类别:
| 前缀 | 数量(约) | 职责 |
| channel-* | ~45 | 渠道类型定义、inbound/outbound 消息、DM 安全策略、群组行为、分块策略 |
| provider-* | ~35 | AI Provider 接口、模型注册、能力声明、流式响应协议 |
| memory-core-* | ~20 | 内存系统核心类型、存储接口、向量索引 |
| plugin-* | ~25 | 插件清单格式、生命周期钩子、能力声明 |
| runtime-* | ~40 | 运行时配置、事件总线、日志、错误类型、会话上下文 |
| media-* | ~15 | 媒体类型、处理器接口、转码管道 |
| speech-* | ~10 | 语音识别/合成引擎接口 |
| 其他 (tool-*, skill-*, util-* 等) | ~40 | 工具/技能插件接口、通用工具类型 |
OpenClaw 的核心架构约束是:所有外部扩展(extensions/ workspace 中的包以及第三方 npm 包)只能从 openclaw/plugin-sdk/* 导入。不允许直接引用 src/ 内部模块,不允许使用相对路径跨越包边界,不允许引用未在 exports 中声明的路径。
这条规则通过四条自定义 ESLint 规则在 CI 中强制执行:
| Lint 规则 | 作用 |
| lint:extensions:no-plugin-sdk-internal | 禁止 extensions/ 中的代码导入 plugin-sdk 的内部实现文件(非 exports 声明路径) |
| lint:extensions:no-relative-outside-package | 禁止 extensions/ 中的代码使用相对路径引用包外部的文件 |
| lint:extensions:no-src-outside-plugin-sdk | 禁止 extensions/ 中的代码直接引用 src/ 下非 plugin-sdk 的任何模块 |
| lint:plugins:no-extension-imports | 禁止 src/ 核心代码反向引用 extensions/ 中的模块(防止反向依赖) |
这四条规则共同构成了一个严格的 依赖防火墙:核心代码和扩展代码之间的边界是单向的、受控的、可审计的。
OpenClaw 定义了五种插件类型,每种对应 plugin-sdk 中的一组子路径:
Channel Plugin(渠道插件):实现一个新的消息平台适配器。必须提供 channel-inbound 和 channel-reply-pipeline 的完整实现。清单文件中必须声明 channel.id。
Provider Plugin(Provider 插件):接入一个新的 AI 模型提供商。需实现 provider-types 中定义的接口,包括模型列举、Chat Completion 流、Embedding 等。
Tool Plugin(工具插件):为 Agent 添加新的可调用工具。通过 tool-* 子路径注册工具定义,包括 JSON Schema 参数描述和执行函数。
Skill Plugin(技能插件):预打包的复合能力(如 "搜索网页并总结"),可包含多个 tool 的编排逻辑。
Media Plugin(媒体插件):注册自定义的媒体处理器,处理特定 MIME 类型的文件。
每个插件的元数据由包根目录下的 openclaw.plugin.json 声明:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{ "id": "openclaw-channel-matrix", "version": "2026.4.1", "type": "channel", "channel": { "id": "matrix", "displayName": "Matrix", "supportsGroups": true, "supportsDM": true }, "install": { "npmSpec": "@openclaw/channel-matrix@latest" }, "minCoreVersion": "2026.3.1", "entrypoint": "./dist/index.js" } |
关键字段:id 是全局唯一标识符;channel.id 在 type 为 channel 时必须提供,用于路由表匹配;install.npmSpec 指定安装时使用的 npm 包标识符;minCoreVersion 声明兼容的最低 OpenClaw 核心版本。
src/plugin-sdk/ 内部有两个重要的 桶文件(Barrel File):api.ts 和 runtime-api.ts。
api.ts 聚合所有纯类型导出——接口定义、类型别名、枚举等。它是编译时依赖,不包含任何运行时代码。runtime-api.ts 聚合需要运行时实现的模块——工厂函数、注册器、事件发射器等。两者的分离确保了:如果插件只需要类型信息(如纯粹的 TypeScript 类型守卫),可以仅依赖 api.ts,不会引入任何运行时代码,保持 tree-shaking 友好。
插件安装通过 npm install --omit=dev 执行,只安装生产依赖。关键约束:插件的 package.json 中禁止使用 workspace:* 协议作为 dependencies——这是因为第三方插件安装在用户机器上时不处于 monorepo workspace 上下文中,workspace:* 会解析失败。CI 中有专门的检查脚本拦截此类违规。
v2026.3.31 是一个 Breaking Change 版本。此前,plugin-sdk 中保留了一组以 provider-compat-* 为前缀的遗留子路径,用于向后兼容早期 Provider 接口。v2026.3.31 正式移除了这些路径。依赖旧接口的第三方 Provider 插件必须迁移到新的 provider-* 子路径。迁移指南位于 docs/migration/v2026.3.31-provider-compat.md。
Gateway 是 OpenClaw 的核心运行时进程。它不是一个可选组件——所有渠道消息、Agent 调度、插件通信、原生客户端交互都经由 Gateway 路由。理解 Gateway 就是理解 OpenClaw 的运行时全貌。
Gateway 的设计哲学是 Single Local Control Plane——本地机器上只有一个 Gateway 实例运行,它是所有组件的通信枢纽。启动命令 openclaw start 实际上就是启动 Gateway 进程。Gateway 在 ws://127.0.0.1:18789(默认端口)上监听 WebSocket 连接,同时在同一端口提供 HTTP 端点。
所有组件都是 Gateway 的客户端:渠道适配器(Telegram bot、Discord bot 等)在内部通过 WebSocket 向 Gateway 报告 inbound 消息;Agent 运行时从 Gateway 接收任务并返回响应;原生应用(macOS、iOS、Android)通过 WebSocket 连接 Gateway 获取实时状态;Control UI(Web 界面)同样是一个 WebSocket 客户端。
Gateway 的 WebSocket 协议是完全类型化的。协议定义位于 src/gateway/protocol/schema.ts,它从 src/gateway/protocol/schema/ 目录中聚合导出所有子模块。每个子模块对应一个协议领域:
|
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 44 45 46 |
// src/gateway/protocol/schema/sessions.ts import { z } from 'zod'; export const SessionPatchRequest = z.object({ method: z.literal('sessions.patch'), params: z.object({ sessionId: z.string(), patch: z.object({ thinkingLevel: z.enum(['off','minimal','low','medium','high','xhigh']).optional(), activeAgent: z.string().optional(), queueMode: z.enum(['sequential','parallel']).optional(), }), }), }); export const SessionPatchResponse = z.object({ result: z.object({ sessionId: z.string(), applied: z.record(z.unknown()), }), }); // src/gateway/protocol/schema/nodes.ts export const NodeListRequest = z.object({ method: z.literal('node.list'), params: z.object({ filter: z.object({ type: z.enum(['channel','agent','plugin','tool']).optional(), status: z.enum(['online','offline','error']).optional(), }).optional(), }), }); export const NodeDescribeRequest = z.object({ method: z.literal('node.describe'), params: z.object({ nodeId: z.string() }), }); export const NodeInvokeRequest = z.object({ method: z.literal('node.invoke'), params: z.object({ nodeId: z.string(), action: z.string(), payload: z.unknown(), }), }); |
协议采用类 JSON-RPC 的请求/响应模式。核心方法包括:
| 方法 | 用途 |
| sessions.patch | 修改会话参数(thinking level、活跃 agent、队列模式等) |
| sessions.list | 列举所有活跃会话及其状态 |
| node.list | 列举所有已注册节点(渠道、Agent、插件、工具) |
| node.describe | 获取指定节点的详细信息和能力声明 |
| node.invoke | 向指定节点发送操作指令(如要求渠道发送消息、要求 Agent 执行任务) |
macOS/iOS 原生应用需要与 Gateway 通信。为保证 TypeScript 协议定义与 Swift 客户端代码的一致性,OpenClaw 在构建流程中包含一个 Swift codegen 步骤。构建脚本解析 src/gateway/protocol/schema/ 中的 Zod Schema,自动生成对应的 Swift Codable struct 和 enum。生成的代码位于 apps/macos/Generated/ 和 apps/ios/Generated/。这意味着协议变更只需修改 TypeScript Schema,Swift 侧自动同步,不存在手动同步遗漏的风险。
Gateway 支持三种认证模式,按优先级排列:
trusted-proxy:Gateway 信任来自特定代理(如 Nginx、Cloudflare Tunnel)的请求,依据代理注入的 HTTP 头进行身份识别。这是生产环境推荐模式。
local-direct:当 WebSocket 连接来自 127.0.0.1 时,跳过认证直接授权。这是本地开发和单机部署的默认行为。
gateway token:通过配置文件设置的静态 Token,客户端在 WebSocket 握手时通过 Authorization: Bearer <token> 头携带。用于远程访问场景。
v2026.3.31 引入了一个重要的安全变更:trusted-proxy 模式下,如果检测到多个客户端使用同一个 shared-token,Gateway 将拒绝连接。此前这种 "多人共享一个 token" 的配置虽然不推荐但能工作,新版本将其升级为硬性错误。这是因为 shared-token 场景下无法区分不同用户的会话,会导致消息路由混乱。
Gateway 在 HTTP 层暴露了一组 OpenAI 兼容端点:
/v1/models:返回当前配置的所有可用模型列表,格式兼容 OpenAI List Models API。这使得任何兼容 OpenAI API 的客户端(如 Cursor、Continue 等)可以直接将 OpenClaw Gateway 作为模型提供方。
/v1/embeddings:提供文本向量化接口,格式兼容 OpenAI Embeddings API。后端可路由到实际配置的 Embedding Provider(OpenAI、Ollama 本地模型等)。
健康检查端点遵循 Kubernetes 惯例:
/healthz:存活探针(Liveness Probe),只要 Gateway 进程在运行就返回 200。
/readyz:就绪探针(Readiness Probe),只有当至少一个渠道连接成功且 Agent 运行时已初始化时才返回 200。适用于负载均衡器判断节点是否可以接收流量。
Gateway 直接serve一个 Web 管理界面——Control UI。该 UI 使用 Lit 3(Web Components 框架)+ Vite(构建工具)开发,源码位于 ui/ 目录。构建产物在发布时嵌入 Gateway 的静态资源中,通过 HTTP 直接访问(默认 http://127.0.0.1:18789)。Control UI 本身也是一个 WebSocket 客户端,与 Gateway 保持长连接以实现实时状态更新。
Bridge Protocol(桥接协议)的规范文档位于 docs/gateway/bridge-protocol.md,它定义了原生应用与 Gateway 之间的通信约定——包括消息编码格式、心跳机制、重连策略、事件订阅模型。这份文档是原生应用开发者的核心参考。
OpenClaw 在 v2026.4.1 中支持 24 个消息渠道。渠道系统的核心工程挑战在于:如何将 24 个各具特色、API 风格迥异的消息平台,抽象为一套统一的 inbound/outbound 消息模型,同时保留每个平台的独特能力。
| 渠道 | 底层实现 | 类型 |
| Baileys (WhatsApp Web 逆向协议) | 核心渠道 (src/web/) | |
| Telegram | grammY | 核心渠道 (src/telegram/) |
| Slack | @slack/bolt | 核心渠道 (src/slack/) |
| Discord | discord.js | 核心渠道 (src/discord/) |
| Signal | signal-cli (Java 子进程) | 核心渠道 (src/signal/) |
| BlueBubbles (iMessage) | BlueBubbles HTTP API | 核心渠道 (src/imessage/),推荐方式 |
| iMessage (legacy imsg) | 原生 AppleScript/osascript | 核心渠道,已标记为遗留 |
| Google Chat | Google Chat API | 内置扩展 |
| IRC | irc-framework | 内置扩展 |
| Microsoft Teams | Teams SDK (v2026.3.28 升级后版本) | 内置扩展 |
| Matrix | matrix-js-sdk + @matrix-org/crypto-wasm | 内置扩展 (extensions/) |
| Feishu (飞书) | Feishu Open API | 内置扩展 |
| LINE | @line/bot-sdk | 内置扩展 |
| Mattermost | Mattermost REST API + WebSocket | 内置扩展 |
| Nextcloud Talk | Nextcloud Talk API | 内置扩展 |
| Nostr | nostr-tools | 内置扩展 |
| Synology Chat | Synology Chat Webhook | 内置扩展 |
| Tlon | Tlon API | 内置扩展 |
| Twitch | tmi.js | 内置扩展 |
| Zalo | Zalo Official Account API | 内置扩展 (extensions/) |
| Zalo Personal | Zalo Personal API (ZaloUser) | 内置扩展 (extensions/) |
| Voice Call | VoIP/SIP 集成 | 内置扩展 (extensions/) |
| WeChat (微信) | @tencent-weixin/openclaw-weixin (iLink Bot API) | 官方合作插件 |
| WebChat | Gateway 内置 WebSocket 聊天 | 核心渠道 |
渠道系统的类型契约由三个核心文件定义:
types.plugin.ts:面向插件开发者的公开类型。渠道插件必须实现的接口在此定义,包括 ChannelAdapter(渠道适配器)、ChannelSender(消息发送器)、ChannelConfig(渠道配置 Schema)。
types.core.ts:核心内部类型,不通过 plugin-sdk 导出。包含路由表条目、会话绑定关系、内部消息信封(Envelope)格式。
types.adapters.ts:适配器辅助类型,定义各平台 SDK 事件到统一 inbound 格式的映射接口。
统一消息抽象是渠道系统的核心设计。它由三个 plugin-sdk 子路径定义:
channel-inbound:定义所有渠道 inbound 消息的统一结构。无论消息来自 WhatsApp、Telegram 还是 Discord,经过渠道适配器处理后都被转换为相同的 InboundMessage 类型。该类型包含:channelId、peerId(发送者标识)、groupId(群组标识,DM 时为 null)、content(文本/媒体/混合内容)、replyTo(引用消息 ID)、timestamp、rawEvent(平台原始事件,用于渠道特定逻辑)。
channel-reply-pipeline:定义 Agent 响应经过的处理管道。管道阶段包括:内容格式化(Markdown → 平台特定格式)→ 长消息分块(per-channel chunking)→ 媒体附件处理 → 平台 API 调用。
channel-send-result:定义消息发送结果的统一结构,包括平台返回的消息 ID、发送状态(成功/失败/部分成功)、错误信息。
在群组场景中,Agent 默认不响应所有消息——这会导致群组中的噪声。OpenClaw 实现了 @提及门控(Mention Gating):只有当消息中包含对 Bot 的 @mention 时,Agent 才会处理该消息。这一行为可通过配置按渠道/群组覆盖为 always 模式(响应所有消息)。
回复标签(Reply Tags)解决了另一个群组问题:当多条消息同时进入时,Agent 的回复需要标记其对应的原始消息。在 Telegram 中这通过 reply_to_message_id 实现,在 Discord 中通过 Message Reference 实现,在 Slack 中通过 Thread TS 实现。渠道适配器负责将统一的 replyTo 字段映射为平台特定的回复机制。
长消息分块(Per-channel Chunking)是另一个平台差异处理点。Telegram 单条消息上限 4096 字符,Discord 为 2000 字符,WhatsApp 约 65536 字符。channel-reply-pipeline 中的分块阶段根据目标渠道的限制,将超长 Agent 响应拆分为多条消息,同时确保代码块、Markdown 列表等结构不被截断在中间。
私聊(DM)场景有独立的安全模型,由 channel-dm-security 子路径定义。核心是 dmPolicy 配置项,支持三种模式:
pairing:用户必须先发送配对码(Pairing Code)才能激活 DM 对话。配对码由 openclaw pair 命令生成,一次性使用。这是最安全的模式。
allowlist:只有 allowFrom 配置中列出的用户 ID/手机号才能发起 DM 对话。
open:任何人都可以直接发起 DM 对话。仅建议在可控环境(如内网部署)中使用。
WhatsApp:基于 Baileys 库,使用 WhatsApp Web 协议。首次连接需要扫描 QR 码完成登录,QR 码在终端中以 ASCII art 形式渲染,同时在 Control UI 中以图片形式展示。会话凭证持久化到本地文件系统,后续启动自动恢复。
Telegram:支持两种运行模式——长轮询(Long Polling,默认)和 Webhook 模式。Webhook 模式下,Gateway 注册一个公开 HTTPS 端点接收 Telegram 推送,延迟更低但需要公网可达的地址(通常通过 Cloudflare Tunnel 或 ngrok 实现)。grammY 框架提供了完整的 Bot API 类型安全封装。
Discord:支持原生 Slash Commands(/ask、/image 等)和纯文本命令两种交互模式。discord.js 提供了丰富的事件模型,OpenClaw 利用其 Message Component 能力实现了交互式按钮和选择菜单。
Microsoft Teams:v2026.3.28 版本对 Teams 集成进行了重大升级,迁移到新版 Teams SDK。新版本支持流式回复(Streaming Replies),Agent 的响应可以实时逐字显示在 Teams 对话中,并带有 AI 注释标签(AI Annotation),让用户明确知道当前回复来自 AI。
WeChat(微信):通过官方合作渠道实现,使用 @tencent-weixin/openclaw-weixin 包,底层接入 iLink Bot API。当前仅支持私聊消息,不支持群聊。v2.x 版本要求 OpenClaw 核心版本 ≥ 2026.3.22。
OpenClaw 的 Agent 运行时构建在 Pi Agent 之上。这不是一个自研的 Agent 框架,而是对外部库 @mariozechner/pi-agent-core@0.64.0 和 @mariozechner/pi-ai@0.64.0 的深度集成。Pi 生态还包括 pi-coding-agent(代码生成专用 Agent)和 pi-tui(终端 UI)。
Pi Agent 以 RPC 模式运行时,支持两种流式输出协议:
Tool Streaming(工具流):Agent 调用工具时,工具的执行过程和中间结果以流式方式返回。例如,Agent 调用搜索工具时,搜索结果的每一条都作为一个流事件推送,而不是等待所有结果返回后才一次性输出。
Block Streaming(块流):Agent 的文本响应以块为单位流式输出。一个 "块" 可以是一个段落、一个代码块或一个列表。块流比逐 token 流更适合消息渠道场景——渠道适配器可以在每个块完成时立即发送,而不是积累整个响应后发送,也避免了逐 token 发送导致的频繁 API 调用。
OpenClaw 的 Session 模型是理解消息路由的关键。每个 Agent 维护多个独立的会话(Session),会话之间完全隔离:
DM Session:与每个私聊用户的对话构成一个独立会话。会话由 (agentId, channelId, peerId) 三元组唯一标识。
Group Session:每个群组一个独立会话,由 (agentId, channelId, groupId) 三元组标识。群组会话与 DM 会话完全隔离——Agent 在群组中看不到同一用户的私聊历史,反之亦然。
会话的激活模式(Activation Mode)控制 Agent 何时响应:mention 模式下,只有 @mention 才触发响应;always 模式下,所有消息都触发响应。DM 会话默认为 always,群组会话默认为 mention。
队列模式(Queue Mode)控制并发消息的处理策略:sequential 模式下,消息严格按接收顺序逐条处理;parallel 模式下,多条消息可并行处理(适用于无状态的工具调用场景)。
Reply-back 路由确保 Agent 的响应被发送到正确的渠道和对话。当 Agent 通过工具调用触发了跨渠道操作时(如在 Telegram 对话中要求 Agent 向 Slack 频道发送消息),reply-back 路由负责将操作结果路由回发起请求的 Telegram 对话。
三个内置工具使 Agent 具备了 跨会话/跨 Agent 协调能力:
|
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 |
// sessions_list: 列举当前所有活跃会话 { name: 'sessions_list', description: 'List all active sessions with their channel, peer, and status', parameters: { filter: { type: 'object', properties: { channelId: { type: 'string' }, status: { enum: ['active', 'idle', 'archived'] } }} } } // sessions_history: 读取指定会话的历史消息 { name: 'sessions_history', description: 'Read message history from a specific session', parameters: { sessionId: { type: 'string' }, limit: { type: 'number', default: 50 } } } // sessions_send: 向指定会话发送消息(实现 Agent-to-Agent 通信) { name: 'sessions_send', description: 'Send a message to a specific session (enables agent-to-agent coordination)', parameters: { sessionId: { type: 'string' }, content: { type: 'string' } } } |
sessions_send 是多 Agent 协调的关键。Agent A 可以通过 sessions_list 发现 Agent B 的会话,通过 sessions_send 向 Agent B 发送指令或查询,Agent B 的响应会通过 reply-back 路由返回 Agent A 的会话上下文。
OpenClaw 支持在同一实例中运行多个 Agent,每个 Agent 有独立的配置和会话空间。路由规则在配置文件中定义,支持按渠道、账号、peer 三个维度将 inbound 消息分发到不同 Agent:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# config.yaml 多 Agent 路由示例 agents: - id: general-assistant provider: openai model: gpt-4o routes: - channel: telegram account: "@mybot" - channel: discord account: "bot-token-1" - id: coding-helper provider: anthropic model: claude-sonnet-4-20250514 routes: - channel: slack account: "workspace-1" peers: ["U12345678"] # 仅特定用户的消息路由到此 Agent |
每个 Agent 拥有独立的 workspace 和 session 存储,实现完全隔离。
每个 Agent 的运行时上下文由 ~/.openclaw/workspace/ 目录提供。该目录下的三个特殊文件会被自动注入到 Agent 的系统提示词中:
AGENTS.md:定义 Agent 的角色、行为准则和约束。这是 Agent 人格的核心定义文件。
SOUL.md:更细粒度的人格描述——语气、对话风格、知识领域偏好等。
TOOLS.md:工具使用指南,告诉 Agent 每个可用工具的使用场景和最佳实践。
这三个文件均为 Markdown 格式,用户可以自由编辑。修改后无需重启——Gateway 在每次会话消息处理前会检查文件的 mtime,如有变更则重新加载。
会话历史以 JSONL(JSON Lines)格式持久化到 ~/.openclaw/agents/<agentId>/sessions/*.jsonl。每个会话一个文件,每行一条消息记录。JSONL 格式的选择是经过考量的:它支持 append-only 写入(崩溃安全),支持按行增量读取(内存效率),且可以直接用标准文本工具检查。
长时间运行的会话会积累大量历史,导致 context window 溢出和延迟增加。OpenClaw 提供了两种应对机制:
Session Pruning(会话修剪):自动删除超过配置时间窗口(默认 7 天)的旧消息。修剪操作在会话被激活时触发,是懒惰式的。
Session Compaction(会话压缩):通过 /compact 命令手动触发。压缩过程调用 AI 模型将长历史总结为精简的上下文摘要,替换原始的逐条消息记录。压缩后的会话文件体积可缩减 80% 以上,同时保留关键上下文信息。
OpenClaw 暴露了对 AI 模型 "思考深度" 的精细控制。thinkingLevel 参数支持六个级别:
| 级别 | 行为 |
| off | 禁用扩展思考(Extended Thinking),直接生成响应 |
| minimal | 最小思考预算 |
| low | 低思考预算,适合简单任务 |
| medium | 中等思考预算,默认值 |
| high | 高思考预算,适合复杂推理 |
| xhigh | 极高思考预算,用于需要深度推理的场景 |
Thinking Level 可以在会话级别通过 sessions.patch 协议方法动态调整,也可以在配置文件中设置全局默认值。支持扩展思考的 Provider(如 Anthropic Claude)会根据级别调整思考 token 的预算上限。
v2026.3.31 引入的 idle-stream timeout 解决了一个实际运维问题:当模型流(Model Stream)长时间无新 token 输出时(例如模型服务端卡住或网络中断),Agent 会一直等待而不释放会话锁,导致该会话的后续消息全部堆积。idle-stream timeout 允许配置一个超时时间(默认 120 秒),当流在指定时间内无新数据时,Agent 会主动中断流并返回部分响应或错误消息。此超时时间可在配置文件中按 Provider 调整——使用本地 Ollama 模型时可能需要更长的超时。
AI 助手的个性化能力取决于记忆系统的深度。OpenClaw 的内存子系统 memory-core 是整个项目中模块拆分最细致的部分,由 13 个子模块组成,全部通过 plugin-sdk 导出。设计目标明确:所有记忆数据以本地 Markdown 文件和 SQLite 数据库的形式持久化,用户可直接编辑、可 Git 版本控制、可离线运行。
plugin-sdk 中与记忆相关的导出共 13 个路径,每个路径对应一个独立的编译单元:
| 导出路径 | 职责 |
| memory-core | 根模块,定义 MemoryStore 接口、MemoryEntry 类型、TTL 策略和序列化契约 |
| memory-core-engine-runtime | 引擎运行时,将内存操作绑定到当前 Agent 运行时生命周期 |
| memory-core-host-engine-embeddings | 嵌入引擎宿主:调度 Embedding 模型计算向量,管理批量嵌入队列 |
| memory-core-host-engine-foundation | 基础引擎宿主:提供 tokenizer 绑定、向量维度协商、距离度量选择 |
| memory-core-host-engine-qmd | QMD(Query-Memory-Document)引擎:将用户查询与记忆文档进行语义匹配 |
| memory-core-host-engine-storage | 存储引擎宿主:抽象底层存储后端(SQLite、LanceDB),提供统一 CRUD |
| memory-core-host-multimodal | 多模态记忆:处理图片、音频等非文本记忆条目的索引与检索 |
| memory-core-host-query | 查询宿主:构建语义搜索查询,合并关键词过滤与向量相似度 |
| memory-core-host-runtime-cli | CLI 运行时宿主:暴露 openclaw memory search 等终端命令 |
| memory-core-host-runtime-core | 核心运行时宿主:记忆系统的初始化、迁移和生命周期管理 |
| memory-core-host-runtime-files | 文件运行时宿主:监控 Markdown 记忆文件的变更并触发重新索引 |
| memory-core-host-secret | 密钥宿主:管理记忆存储的加密密钥与 SecretRef 解析 |
| memory-core-host-status | 状态宿主:报告索引进度、向量数量、最近查询延迟等运行指标 |
这种拆分方式遵循 OpenClaw 的插件架构原则:每个子模块可以被独立替换或禁用,核心系统只依赖 memory-core 根模块定义的接口,而不直接依赖任何具体存储后端。
OpenClaw 的记忆系统将用户偏好和长期上下文存储为本地 Markdown 文件,默认位于 ~/.openclaw/memory/ 目录。每个记忆文件是标准 Markdown,带有 YAML front-matter 元数据:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
--- type: preference created: 2026-03-15T08:22:00Z updated: 2026-04-01T14:30:00Z tags: [coding-style, language] --- # Coding Preferences - Preferred language: TypeScript with strict mode - Tab width: 2 spaces - Always use explicit return types - Prefer functional composition over class inheritance |
这种设计的核心优势在于三点:第一,用户可以直接用任何文本编辑器修改记忆内容,无需进入 OpenClaw 的界面;第二,记忆文件可以纳入 Git 版本控制,团队成员可以共享和同步偏好配置;第三,记忆内容完全离线可用,不依赖任何云端服务。memory-core-host-runtime-files 模块通过文件系统监听(fs.watch)检测 Markdown 文件的变更,自动触发重新索引流程——解析 front-matter、提取正文、计算嵌入向量、更新向量存储。
语义搜索依赖向量存储。OpenClaw 提供两个后端选项:
sqlite-vec(版本 0.1.9)是默认后端。它是 SQLite 的向量搜索扩展,以 npm 依赖 sqlite-vec@0.1.9 的形式声明在 package.json 中。sqlite-vec 将向量存储为 SQLite 表中的 BLOB 列,支持精确最近邻(Exact KNN)和基于量化的近似最近邻(ANN)搜索。对于个人使用场景——通常记忆条目在数百到数千量级——sqlite-vec 的精确 KNN 已经足够高效,查询延迟在亚毫秒级别。sqlite-vec 的优势与 OpenClaw 的本地优先哲学完全一致:单文件数据库,零外部依赖,可直接备份和迁移。
memory-lancedb 是第二个后端,同样通过 plugin-sdk 导出。LanceDB 是一个嵌入式向量数据库,底层使用 Lance 列式格式,支持 IVF-PQ 索引,适合记忆条目达到十万量级的场景。memory-core-host-engine-storage 模块通过统一的存储抽象层隔离这两个后端,上层代码无需感知底层实现差异:
|
1 2 3 4 5 6 7 8 |
// memory-core-host-engine-storage 抽象接口 export interface VectorStorageBackend { insert(entries: MemoryEntry[]): Promise<void>; search(query: Float32Array, topK: number, filter?: MemoryFilter): Promise<ScoredEntry[]>; delete(ids: string[]): Promise<void>; count(): Promise<number>; vacuum(): Promise<void>; } |
memory-core-host-engine-embeddings 管理嵌入计算的完整管道。当记忆文件被创建或修改时,该模块执行以下流程:
- 解析 Markdown 文件,将正文按段落分块(chunking),每块控制在 512 token 以内
- 调用当前配置的嵌入模型(Embedding Model)计算向量,默认使用提供者插件中配置的嵌入端点
- 将向量与元数据(来源文件路径、chunk 偏移、时间戳、标签)一起写入向量存储
- 维护一个增量索引:仅对变更的块重新计算嵌入,未修改的块保留原有向量
memory-core-host-engine-qmd(QMD 引擎)负责查询时的语义匹配。QMD 的全称是 Query-Memory-Document,它实现一个三阶段检索流程:先对用户查询计算嵌入向量,然后在向量存储中执行近似最近邻搜索获取候选集,最后用 BM25 关键词评分对候选集重排序(Re-ranking)。memory-core-host-query 模块负责构建查询对象,将语义相似度阈值、标签过滤、时间范围等条件组合为统一的查询描述符。
记忆系统是 OpenClaw 个性化能力的基石。Agent 运行时在处理每一轮对话时,都会通过 memory-core-engine-runtime 检索相关记忆并注入到系统提示词中。这个过程对用户透明,但直接影响 Agent 回复的个性化程度——它知道用户偏好的编程语言、代码风格、常用工具链,甚至过去对话中建立的项目上下文。
OpenClaw 的模型提供者(Model Provider)系统是其多模型支持能力的核心。通过 plugin-sdk 导出的提供者插件超过 25 个,覆盖主流商业 API、开源推理引擎和云平台网关。每个提供者是一个独立插件,遵循统一的注册、认证和模型目录协议。
每个提供者插件由四个核心文件组成:
| 文件 | 职责 |
| provider-entry.ts | 插件入口点,注册提供者到插件注册表,声明支持的功能特性(Feature Flags) |
| provider-auth.ts | 认证逻辑,实现 API Key 或 OAuth 流程 |
| provider-catalog-shared.ts | 模型目录,列出该提供者支持的所有模型及其能力标记(文本/图像/代码等) |
| provider-model-shared.ts | 模型共享配置,定义 token 限制、定价信息、上下文窗口大小等元数据 |
提供者插件通过 plugin-sdk 的导出路径注册。以 OpenAI 提供者为例,导出路径为 plugin-sdk/provider-openai,Anthropic 为 plugin-sdk/provider-anthropic,以此类推。
截至 v2026.4.1,plugin-sdk 导出以下提供者:
| 提供者 | 模型举例 | 认证方式 |
| OpenAI | GPT-4o, o3, o4-mini, Codex | API Key / OAuth |
| Anthropic (Claude) | Claude Sonnet 4, Opus 4 | API Key / OAuth |
| Google (Gemini) | Gemini 2.5 Pro, Flash | API Key |
| DeepSeek | DeepSeek-V3, DeepSeek-R1 | API Key |
| xAI (Grok) | Grok-3, Grok-3-mini | API Key |
| Ollama | 本地部署任意 GGUF 模型 | 无(本地) |
| Mistral | Mistral Large, Codestral | API Key |
| MiniMax | MiniMax-Text-01, image-01 | API Key |
| Moonshot(月之暗面) | Kimi | API Key |
| ModelStudio(通义千问) | Qwen-Max, Qwen-Plus | API Key |
| Qianfan(百度文心) | ERNIE-4.0, ERNIE-Speed | API Key |
| NVIDIA | Nemotron, Llama 3 NVIDIA | API Key |
| HuggingFace | Inference API 托管模型 | API Token |
| Together | Llama, Mixtral 等开源模型 | API Key |
| Venice | 隐私优先推理 | API Key |
| vLLM | 自托管 vLLM 实例 | 自定义 |
| SGLang | 自托管 SGLang 实例 | 自定义 |
| BytePlus(火山引擎) | 豆包大模型 | API Key |
| Cloudflare AI Gateway | Workers AI 代理 | API Token |
| Amazon Bedrock | Claude on Bedrock, Titan | AWS IAM |
| Anthropic Vertex | Claude on Vertex AI | GCP Service Account |
| Chutes | GPU 推理市场 | API Key |
| KiloCode | KiloCode 模型 | API Key |
| Kimi Coding | Kimi 代码模型 | API Key |
| OpenCode / OpenCode Go | 开源代码推理 | API Key |
认证子系统由四个模块组成:provider-auth-api-key(API Key 认证)、provider-auth-login(OAuth 登录认证)、provider-auth-result(认证结果封装)和 provider-auth-runtime(运行时认证状态管理)。
大多数提供者支持 API Key 单一模式,但 OpenAI 和 Anthropic 等主流提供者同时支持 OAuth 登录和 API Key 两种方式。OAuth 模式下,用户通过浏览器完成授权后,OpenClaw 获取 access token 并自动管理刷新流程。这种双模设计(Auth Rotation)允许用户在免费额度用完后无缝切换到自有 API Key,反之亦然。
合成认证(Synthetic Auth)通过 resolveSyntheticAuth 函数实现。当多个提供者共享同一底层认证(例如 Anthropic Vertex 使用 GCP 凭据,而不是 Anthropic 原生 API Key)时,合成认证将底层凭据转换为提供者期望的格式。实现位于认证运行时模块中:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// provider-auth-runtime 中的合成认证解析 export async function resolveSyntheticAuth( provider: ProviderId, secretStore: SecretStore ): Promise<AuthResult> { const secretRef = getProviderSecretRef(provider); const rawCredential = await secretStore.resolve(secretRef); // 根据提供者类型转换凭据格式 switch (provider) { case 'anthropic-vertex': return synthesizeVertexAuth(rawCredential as GCPServiceAccount); case 'amazon-bedrock': return synthesizeBedrockAuth(rawCredential as AWSCredentials); default: return { type: 'api-key', key: rawCredential as string }; } } |
SecretRef 是 OpenClaw 的凭据引用语义。凭据不以明文存储在配置文件中,而是通过 SecretRef 引用操作系统的密钥链(macOS Keychain、Windows Credential Manager、Linux Secret Service)。SecretRef 的格式为 secretref:<provider>:<key-name>,运行时由 memory-core-host-secret 模块解析为实际凭据值。
模型故障转移(Model Failover)是 OpenClaw 应对 API 速率限制和服务中断的核心机制(详见 docs.openclaw.ai/concepts/model-failover)。当主模型返回 429(Rate Limited)或 5xx 错误时,系统自动将请求路由到预配置的备选模型。故障转移配置在用户的 settings 文件中定义:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ "models": { "primary": "anthropic:claude-sonnet-4-20260514", "fallback": [ "openai:gpt-4o", "google:gemini-2.5-pro" ], "failover": { "maxRetries": 2, "retryDelayMs": 1000, "fallbackOnRateLimit": true, "fallbackOnServerError": true } } } |
故障转移逻辑在路由层(src/routing/)实现,对上层 Agent 运行时透明。路由层维护每个提供者的健康状态和速率限制窗口,在主模型不可用时按 fallback 列表顺序尝试备选模型。
v2026.3.28 版本对提供者系统引入了三项重要变更:
xAI 迁移至 Responses API:xAI 提供者从传统的 Chat Completions API 迁移到 Responses API 格式,同时启用 x_search 原生网页搜索功能。Grok 模型可直接在对话中调用 xAI 的搜索基础设施,无需额外的工具调用层。
MiniMax 图像生成:MiniMax 提供者新增 image-01 模型支持,通过 MiniMax 的图像生成 API 实现文生图能力。该功能作为提供者拥有的工具(Provider-owned Tool)注册,遵循 OpenClaw 的设计原则——提供者特有的工具和设置归属于提供者插件,而非核心系统。
通义千问认证变更:Qwen 的 portal auth 模式被移除,统一切换为 Model Studio API Key 认证。这是一次破坏性变更,已有的 portal auth 用户需要手动迁移到 API Key 模式。
OpenClaw 通过 plugin-sdk/github-copilot-login 和 plugin-sdk/github-copilot-token 两个导出模块支持 GitHub Copilot 账户登录。拥有 Copilot 订阅的用户可以直接使用 GitHub 账户认证,通过 Copilot 的基础设施访问底层模型(GPT-4o、Claude 等),无需单独配置每个提供者的 API Key。认证流程复用 GitHub 的 Device Flow OAuth,获取 Copilot token 后由 github-copilot-token 模块管理令牌刷新。
Agent Client Protocol(ACP)是 OpenClaw 定义的有状态 Agent 会话协议。ACP 的核心思想是将 AI Agent 的交互从特定的聊天界面中解耦出来,使其可以通过任意通信渠道(Discord、iMessage、终端等)启动和管理有状态的 Agent 工作会话。项目依赖 @agentclientprotocol/sdk@0.17.1 提供协议的核心类型和客户端实现。
ACPX(仓库 openclaw/acpx,1,834 stars)是 OpenClaw 的无头(Headless)ACP CLI 客户端。它允许用户从命令行创建、管理和交互 ACP 会话,无需图形界面。ACPX 的典型使用场景包括 CI/CD 管道中的 Agent 自动化、服务器端部署和脚本编排。
ACP 会话可以绑定到任意聊天渠道。通过 /acp spawn codex --bind here 命令,用户可以在当前渠道上下文中创建一个 ACP 会话。目前支持的绑定包括:
- Discord:通过 Discord Bot 渠道绑定,ACP 会话映射到 Discord 线程
- BlueBubbles:macOS 上的 iMessage 桥接,ACP 会话通过 BlueBubbles API 接入 iMessage
- iMessage:直接 iMessage 绑定(仅 macOS/iOS 平台)
ACP 的核心分层需要明确区分三个概念:聊天表面(Chat Surface)是用户交互的 UI 层,可以是 Discord 频道、终端窗口或 Web 界面;ACP 会话(ACP Session)是有状态的 Agent 交互上下文,维护对话历史、工作区状态和工具授权;运行时工作区(Runtime Workspace)是 Agent 实际执行操作的文件系统沙箱。一个聊天表面可以关联多个 ACP 会话,而每个 ACP 会话绑定到唯一的运行时工作区。
OpenClaw 集成了 Model Context Protocol(MCP),依赖 @modelcontextprotocol/sdk@1.29.0。MCP 定义了 AI 模型与外部工具之间的标准通信协议,OpenClaw 通过 MCP 桥接层将外部 MCP 工具服务器暴露给 Agent 运行时。
v2026.3.31 版本引入了 ACPX plugin-tools MCP 桥接的关键安全变更:MCP 工具默认关闭(explicit default-off),必须在配置中显式启用。这一变更源于信任边界加固(Trust Boundary Hardening)的安全考量——外部 MCP 工具服务器可能执行任意代码,默认启用会扩大攻击面。启用配置示例:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
{ "mcp": { "servers": { "filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"], "enabled": true } }, "trustPolicy": "prompt-per-tool" } } |
trustPolicy 支持三个级别:prompt-per-tool(每次工具调用需用户确认)、prompt-once(首次确认后自动信任)和 trust-all(完全信任,仅建议在受控环境中使用)。
对于 OpenAI 和 Codex 系列模型,OpenClaw 默认启用 apply_patch 工具。这是 OpenAI Codex 模型原生支持的代码编辑工具,直接通过 API 返回结构化的补丁指令(patch instruction),由 OpenClaw 的运行时执行文件修改。相较于让模型输出完整文件内容再做 diff,apply_patch 减少了输出 token 消耗,降低了大文件编辑时的错误率。apply_patch 的沙箱权限与 write 权限对齐——在非主会话的 Docker 沙箱中,apply_patch 的写入范围受到与普通文件写入相同的约束。
v2026.3.31 将三个主要 CLI 后端——Claude CLI、Codex CLI 和 Gemini CLI——的推理默认行为迁移到各自的 bundled plugin 中。通过 Plugin SDK 的 cli-backend 和 cli-runtime 导出路径,CLI 后端可以注册自定义的推理流、工具暴露和会话管理策略。这一迁移的意义在于解耦——核心不再硬编码 CLI 后端的行为,第三方插件可以通过相同的接口注册自定义 CLI 后端。
ACP 的深层价值体现在 Agent-to-Agent(A2A)通信能力上。OpenClaw 的 Session 工具集——sessions_list、sessions_history、sessions_send——允许一个 Agent 会话发现、查询和向另一个 Agent 会话发送消息。sessions_send 支持可选的 reply-back 模式(ping-pong 通信)和 announce 步骤,允许 Agent 之间进行结构化的协调对话。
在多 Agent 部署场景下(例如一个 Agent 负责客户对话,另一个 Agent 负责后端任务执行),A2A 通信避免了传统架构中需要外部消息队列的复杂性。所有通信都通过 Gateway 的 WebSocket 控制平面路由,Agent 之间共享同一个运行时基础设施但拥有隔离的会话上下文和工作区。
v2026.3.31 新增的 ACP 渠道绑定进一步扩展了这一能力:/acp spawn codex --bind here 可以将当前聊天表面直接绑定为 Codex 驱动的工作区,无需创建子线程。通过这种方式,用户可以在 Discord 频道中直接启动一个代码编写 Agent,Agent 的输出直接出现在对话流中。
OpenClaw 的媒体处理管道位于 src/media/ 目录,负责所有非文本内容的预处理、理解和生命周期管理。通过 plugin-sdk 导出三个核心模块:media-runtime(运行时管道调度)、media-understanding(媒体内容理解接口)和 media-understanding-runtime(理解模块的运行时绑定)。另有 web-media 导出处理 Web 渠道的媒体特化逻辑。
图像处理依赖 sharp@0.34.5——Node.js 生态中性能最高的图像处理库,底层使用 libvips。OpenClaw 使用 sharp 执行以下处理:
- 缩放(Resize):将用户上传的图像缩放到模型支持的最大分辨率,避免浪费 token 或超出 API 限制
- 格式转换:将 BMP、TIFF、WebP 等格式统一转换为 JPEG 或 PNG,确保所有提供者都能接收
- 元数据剥离:移除 EXIF 信息中的地理位置、设备信息等隐私数据
- 缩略图生成:为 UI 显示生成低分辨率预览
文件类型检测使用 file-type@22.0.0,通过魔数(Magic Number)而非文件扩展名判断文件类型,防止恶意文件伪装。
PDF 处理依赖 pdfjs-dist@5.6.205(Mozilla PDF.js 的 npm 发行版)。处理流程包括文本提取、页面渲染为图像(用于多模态模型的视觉理解)和结构化内容解析。对于大型 PDF,OpenClaw 实现分页处理策略——仅提取与当前对话上下文相关的页面范围,而非一次性加载整个文档。
音频和视频处理管道处理用户上传的多媒体文件或通过语音输入采集的音频流。音频处理包括格式转换(统一为 WAV/MP3)、采样率标准化和静音检测。转录(Transcription)钩子将音频输入转换为文本,集成到 Agent 的对话流程中——语音消息被自动转录后作为文本消息处理,Agent 可以选择性地以语音或文本方式回复。
视频处理采用关键帧提取策略:从视频中按固定间隔或场景变化检测提取关键帧,将其作为图像序列发送给多模态模型进行理解,避免处理完整视频流的高昂计算成本。
每个渠道(Channel)可独立配置媒体文件的大小上限。例如 Discord 渠道的配置:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "channels": { "discord": { "mediaMaxMb": 25 }, "web": { "mediaMaxMb": 100 }, "cli": { "mediaMaxMb": 500 } } } |
超过限制的文件在预处理阶段即被拒绝,不进入管道后续环节。临时文件(处理过程中的中间产物)遵循严格的生命周期管理:每个媒体处理任务创建独立的临时目录,处理完成后无论成功还是失败都会清理。media-runtime 模块维护一个临时文件注册表,进程退出时执行兜底清理(cleanup-on-exit),防止磁盘泄漏。
media-understanding 和 media-understanding-runtime 两个 SDK 导出路径定义了媒体内容理解的接口和运行时实现。媒体理解不仅仅是格式转换——它将图像、文档和音频转化为模型可以消费的结构化输入。对于图像,理解管道提取图中的文字(OCR)、识别对象和场景;对于 PDF,它生成页面摘要和结构化的段落索引;对于音频,它输出时间戳标注的转录文本。
多模态理解的输出格式遵循各模型提供者的要求。OpenAI 的 GPT-4o 和 Anthropic 的 Claude Sonnet 4 接受 base64 编码的图像嵌入消息体;Google Gemini 支持更大的媒体文件通过 File API 上传后引用。media-understanding-runtime 的职责是根据当前活跃的模型提供者,选择最优的编码和传输策略。
OpenClaw 集成了 @mozilla/readability@0.6.0(Mozilla 的可读性提取库)和 linkedom@0.18.12(轻量 DOM 实现),用于从网页内容中提取正文。当 Agent 使用浏览器工具访问网页时,原始 HTML 经 linkedom 解析后,Readability 算法提取核心正文内容,剥除导航栏、广告、侧边栏等噪声元素。提取后的纯文本进入 Agent 的上下文窗口,相比注入原始 HTML 大幅减少 token 消耗。
Markdown 渲染由 markdown-it@14.1.1 处理。Agent 输出的 Markdown 格式回复在发送到各渠道前,根据目标渠道的能力进行格式适配:Discord 原生支持 Markdown,Telegram 支持部分 Markdown 子集,WhatsApp 使用 WhatsApp 风格的文本格式化,而 SMS/iMessage 则退化为纯文本。
OpenClaw 的语音系统覆盖了从语音唤醒到语音合成的完整链路。plugin-sdk 导出三个语音模块:speech(公共接口)、speech-core(核心实现)和 speech-runtime(运行时绑定)。语音功能根据平台和交互模式分为四种形态。
Voice Wake(详见 docs.openclaw.ai/nodes/voicewake)是 macOS 和 iOS 平台的唤醒词功能。设备持续监听环境音频,检测到预设唤醒词后激活 Agent 会话。唤醒词检测在设备端本地运行,不向云端发送音频流——这与 OpenClaw 的本地优先原则一致。
唤醒后的消息转发通过 VoiceWakeForwarder 实现。用户语音经本地语音识别转为文本后,VoiceWakeForwarder 调用 OpenClaw 的 CLI 接口将文本传递给 Agent:
|
1 |
openclaw-mac agent --message "${text}" --thinking low |
VoiceWakeForwarder 的实现中需要特别处理 Shell 转义(Shell Escaping):用户语音转录文本可能包含引号、美元符号、反引号等 Shell 特殊字符,直接拼接到命令行会导致注入风险或解析错误。转发器对文本进行严格的 Shell 转义后再传递。--thinking low 参数指示 Agent 使用低延迟思考模式,优先响应速度而非推理深度,适配语音交互对实时性的要求。
Talk Mode(详见 docs.openclaw.ai/nodes/talk)是 Android 平台的持续语音对话模式。与 Voice Wake 的"唤醒→单次交互"模式不同,Talk Mode 维持一个持续开放的语音通道——用户和 Agent 可以进行多轮语音对话,无需每轮重新唤醒。Talk Mode 使用 VAD(Voice Activity Detection,语音活动检测)自动判断用户发言的起止,实现自然的对话节奏。
macOS 平台还提供 Push-to-Talk 模式,以系统级覆盖层(Overlay)的形式运行。用户通过长按快捷键激活麦克风输入,松开后结束录音并发送。这种模式适合在桌面工作流中快速提问,无需切换到 OpenClaw 的窗口。覆盖层使用 AppKit 的 NSPanel 实现,设置为浮动在所有窗口之上。
语音合成(TTS,Text-to-Speech)采用双层策略。首选方案是 ElevenLabs 的 API,提供高质量、低延迟、多语言的语音合成。当 ElevenLabs 不可用(网络离线或未配置 API Key)时,系统自动回退到平台原生 TTS:macOS 使用 AVSpeechSynthesizer,iOS 使用 AVSpeechSynthesizer(同一框架),Android 使用 android.speech.tts.TextToSpeech。
此外,OpenClaw 还集成了 node-edge-tts@1.2.10 作为第三层 TTS 后端。Edge TTS 调用 Microsoft Edge 浏览器的在线 TTS 服务,免费且支持多语言多音色,在无 ElevenLabs 订阅但有网络连接的场景下是实用的中间选项。
Voice Call 插件打包在 extensions/ 目录中,作为内置扩展随 OpenClaw 分发。它实现了完整的语音通话功能——用户可以像打电话一样与 Agent 进行实时语音对话,双向音频流通过 WebRTC 或平台原生音频框架传输。
语音通话的质量保证依赖 闭环测试(Closed-Loop Testing)。测试脚本通过 test:voicecall:closedloop npm script 执行,流程如下:自动生成测试文本 → TTS 合成为音频 → 音频作为输入馈送给语音通话管道 → Agent 处理并生成回复 → TTS 合成回复音频 → 转录回复音频为文本 → 对比原始文本与回复内容的语义一致性。这种端到端闭环消除了人工测试的不确定性,确保语音管道中每个环节(ASR → 推理 → TTS)都正常工作。
|
1 2 3 4 5 6 7 8 9 10 11 |
# 执行语音通话闭环测试 pnpm test:voicecall:closedloop # 测试流程: # 1. 生成测试 prompt # 2. TTS 合成输入音频 # 3. 注入音频到 voice call 管道 # 4. 等待 Agent 响应 # 5. 捕获 TTS 输出音频 # 6. ASR 转录输出 # 7. 断言:输出文本与预期语义匹配 |
整个语音系统体现了 OpenClaw 的多端一致性追求:同一个 Agent 可以通过唤醒词、持续语音、按键说话或语音通话四种方式接收语音输入,通过 ElevenLabs、Edge TTS 或系统原生 TTS 三种方式输出语音回复,所有组合在各个平台上的行为保持一致。语音能力不是一个附加功能,而是与文本渠道同等地位的一等交互模式。
OpenClaw 的多端战略并非简单的 WebView 包装。macOS、iOS、Android 三个原生客户端各自承担着差异化的职责:macOS 应用是开发者的本地控制台与调试中心,iOS 应用是移动端的轻量节点(Node),Android 应用则面向最广泛的设备指令族群。三者通过 Gateway WebSocket 协议统一通信,实现跨平台的节点注册、指令派发与画布同步。
macOS 应用的源码位于 apps/macos/,采用 SwiftUI + AppKit 混合架构,以菜单栏常驻图标为交互入口。在 OpenClaw 内部词汇表中,macOS 应用的代号是 makeup(即 "mac app" 的谐音缩写)。
应用的核心功能涵盖以下几个层面:
Gateway 健康监控:菜单栏图标实时反映 Gateway 进程状态,包括连接数、内存占用与心跳延迟。点击图标弹出的面板提供一键重启入口。Gateway 的重启必须通过 OpenClaw Mac 应用本身或 scripts/restart-mac.sh 脚本执行,而非手动在 tmux 中操作——后者会绕过进程监控链,导致状态不一致。
语音唤醒与 Push-to-Talk 悬浮层:Voice Wake 持续监听唤醒词,PTT(Push-to-Talk)覆盖层以半透明悬浮窗的形式驻留桌面。两者共同构成语音交互的 macOS 原生入口。
WebChat 嵌入与调试工具:内嵌 WebChat 视图支持与 Gateway 的实时对话,同时暴露调试面板用于查看消息流、工具调用日志与 token 消耗。
SSH 隧道远程控制:macOS 应用可通过 SSH 隧道连接远程部署的 Gateway 实例,在本地菜单栏操控云端服务。
macOS 应用的状态管理已全面迁移至 Swift 5.9 引入的 Observation 框架,使用 @Observable 宏标记可观察类型,以 @Bindable 实现属性级的双向绑定。旧版 ObservableObject / @StateObject / @Published 模式已被显式弃用 — 任何残留的 legacy 用法都应迁移至新框架。Observation 框架的优势在于更细粒度的依赖追踪:SwiftUI 仅在被实际读取的属性发生变化时重新渲染视图,而非 ObservableObject 的整体通知模式。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
// 正确:Observation 框架 @Observable final class GatewayMonitor { var isConnected = false var latencyMs: Int = 0 var sessionCount: Int = 0 } // 错误:已弃用的旧模式,不要使用 // class GatewayMonitor: ObservableObject { // @Published var isConnected = false // } |
macOS 应用需要签名构建才能使系统权限在重新编译后持久化。未签名的开发构建在每次 rebuild 后都会触发 TCC(Transparency, Consent, and Control)权限重置弹窗。打包脚本位于 scripts/package-mac-app.sh,负责代码签名、公证(Notarization)与 DMG 封装。
macOS 节点模式(Node Mode)暴露的系统能力通过 TCC 权限映射管控:
| 节点命令 | 功能 | TCC 权限 |
| system.run | 执行本地命令,返回 stdout/stderr/exit code | needsScreenRecording 标志位 |
| system.notify | 发送用户通知 | notifications |
| canvas.* | 画布操作路由 | screen-recording |
| camera.* | 摄像头抓取 | camera |
macOS 应用的日志通过 scripts/clawlog.sh 脚本统一查询,底层使用 macOS 的 Unified Logging 系统,支持按子系统(subsystem)过滤。常见操作:
|
1 2 3 4 5 6 7 8 |
# 实时跟踪所有 OpenClaw 子系统日志 ./scripts/clawlog.sh --follow # 按类别过滤 ./scripts/clawlog.sh --category networking --tail 100 # 查看特定子系统 ./scripts/clawlog.sh --subsystem ai.openclaw.gateway |
iOS 应用源码位于 apps/ios/,是一个标准 Xcode 项目 + SwiftUI 工程。与 macOS 应用不同,iOS 应用的定位是作为 Gateway 的远程节点运行,通过 Bonjour 设备发现(Device Discovery)机制自动配对局域网内的 Gateway 实例,并通过 Gateway WebSocket 建立持久连接。
iOS 节点提供的核心能力:
Canvas Surface:在 iOS 设备上渲染 Agent 驱动的画布内容,支持触摸交互。
Voice Wake 转发:iOS 端的语音唤醒检测结果通过 WebSocket 转发至 Gateway,实现移动端的免触语音激活。
Talk Mode:长按说话的语音交互模式,音频流直接传输至 Gateway 进行识别与处理。
Camera Snap/Clip:支持拍照快照和短视频片段采集,供 Agent 的视觉能力使用。
Screen Recording:通过 ReplayKit 进行屏幕录制,将录制内容作为上下文发送给 Agent。
iOS 应用的版本号维护在两个位置:apps/ios/Sources/Info.plist 和 apps/ios/Tests/Info.plist,关键字段为 CFBundleShortVersionString(展示版本号)和 CFBundleVersion(构建号)。发版时两个文件必须同步更新。
Android 应用位于 apps/android/,使用 Kotlin + Gradle 构建。与 iOS 应用相比,Android 节点暴露了更丰富的设备指令族群(Device Command Families),充分利用 Android 平台的开放性。
应用 UI 组织为三个主要标签页:
| 标签页 | 功能 |
| Connect | 设备配对入口,支持设置码(Setup Code)和手动输入两种方式 |
| Chat Sessions | 会话列表与聊天界面 |
| Voice | 语音交互控制面板 |
Android 节点支持的设备指令族群是三端中最丰富的:
| 指令族 | 能力 |
| notifications | 读取/发送系统通知 |
| location | GPS 定位与地理围栏 |
| SMS | 短信读取与发送 |
| photos | 相册访问与照片上传 |
| contacts | 通讯录读写 |
| calendar | 日历事件管理 |
| motion | 加速度计、陀螺仪等传感器数据 |
| app update | 应用自更新管理 |
此外,Android 端同样支持 Canvas 渲染、摄像头采集与屏幕录制能力。
|
1 2 3 4 5 6 7 8 9 10 11 |
# 单元测试(Play Debug 变体) ./gradlew :app:testPlayDebugUnitTest # 第三方集成测试 ./gradlew :app:testThirdPartyDebugUnitTest # Kotlin 代码风格检查 ./gradlew :app:ktlintCheck :benchmark:ktlintCheck # 发布 AAB 构建 bun apps/android/scripts/build-release-aab.ts |
版本信息定义在 apps/android/app/build.gradle.kts 中的 versionName(展示版本)和 versionCode(数字递增版本)。
三个原生应用通过统一的 Gateway WebSocket 协议与 Gateway 通信。节点相关的核心命令包括:
| 命令 | 方向 | 功能 |
| node.list | Gateway → 客户端 | 枚举已连接的所有节点及其能力声明 |
| node.describe | Gateway → 节点 | 查询指定节点的详细能力描述与参数 schema |
| node.invoke | Gateway → 节点 | 在指定节点上执行命令并返回结果 |
macOS 平台的系统权限通过 TCC 框架管控,涵盖 screen-recording、notifications、camera、location 四项。每项权限与特定的节点命令能力绑定,应用会在首次调用时请求授权。
会话级别的权限提升通过 /elevated on|off 命令控制。开启后,当前会话获得完整的 bash 访问权限;关闭时回退到受限执行面。该命令是每个会话独立的,不影响其他并发会话。
v2026.3.31 引入了两项与节点安全相关的破坏性变更。第一,节点命令在设备配对(Device Pairing)完成后不再自动启用 — 必须经过显式的节点配对审批(Node Pairing Approval)后,节点命令才会暴露给 Agent。设备配对仅建立了 WebSocket 连接通道,而节点配对审批确认了用户对该设备能力暴露的授权意图。
第二,由节点端发起的运行(Node-originated Runs)被限制在缩减的可信执行面(Reduced Trusted Surface)上。即使节点本身拥有完整能力,从节点侧主动触发的执行流只能使用预定义的安全工具子集。
Live Canvas 是 OpenClaw Gateway 托管的 Agent 驱动可视化工作区。与传统的静态输出不同,Live Canvas 是持久性的交互画面 — Agent 可以在其上推送内容、重置状态、执行脚本、捕获快照。Canvas 的跨端渲染由原生应用(macOS、iOS SwiftUI、Android)各自实现,而画布操控逻辑通过 A2UI(Agent to UI)协议统一抽象。
A2UI 定义了 Agent 向 UI 层发送控制指令的协议规范。Canvas 宿主的 A2UI 实现位于 src/canvas-host/a2ui/ 目录。该实现会被打包为一个独立的 bundle,由 Gateway 在运行时加载并注入到 Canvas 宿主容器中。
bundle 的构建产物通过哈希文件 src/canvas-host/a2ui/.bundle.hash 进行版本追踪(自动生成,不应手动编辑)。构建命令有两种等价形式:
|
1 2 3 4 5 |
# 通过 pnpm script pnpm canvas:a2ui:bundle # 通过 shell 脚本 scripts/bundle-a2ui.sh |
A2UI bundle 的构建是整体 pnpm build 流水线的第一步。完整的构建管线为:
|
1 2 3 4 5 |
pnpm build # 等价于: # 1. pnpm canvas:a2ui:bundle # 2. tsdown-build.mjs # 3. runtime-postbuild.mjs |
A2UI 的 vendor 源码维护在 vendor/a2ui 目录,原生端的共享封装层位于 apps/shared/OpenClawKit/Tools/CanvasA2UI。
A2UI bundle 的构建在交叉编译环境下可能失败。典型场景是在 Apple Silicon 上通过 QEMU 构建 amd64 目标 — 这种情况下 A2UI 的构建步骤可能因 QEMU 对某些指令集的模拟不完整而崩溃。Dockerfile 中已对此做了防护处理:当 A2UI bundle 构建失败时,会创建一个存根(stub)文件代替,确保 Docker 镜像的整体构建不会中断。这意味着 QEMU 交叉编译产出的镜像可能不包含完整的 Canvas 功能。
Canvas 的操作模型由四个核心原语组成:
| 操作 | 语义 | 典型用途 |
| canvas.push | 向 Canvas 追加内容(HTML/JS/CSS 片段) | 增量构建 UI 界面 |
| canvas.reset | 清空 Canvas 并重新初始化 | 切换上下文或重置状态 |
| canvas.eval | 在 Canvas 上下文中执行任意 JavaScript | 动态交互逻辑、数据可视化 |
| canvas.snapshot | 捕获当前 Canvas 的视觉快照 | 记录状态、生成截图反馈 |
其中 canvas.eval 的安全定位需要特别说明。它被归类为 Operator 控制面(Operator Control Surface)— 意味着其安全性由部署运营方(Operator)负责,而非 OpenClaw 平台本身。Agent 通过 canvas.eval 可以执行任意 JavaScript 代码,这赋予了极大的灵活性,但也意味着 Operator 必须在自己的部署环境中建立相应的安全防线。
在多端架构中,Canvas 操作通过节点模式暴露。所有 canvas.* 调用都被路由为 node.invoke 指令发送到对应的端侧节点执行。这意味着 Agent 可以指定在特定设备(例如用户的 iPad 或 Android 手机)上渲染画布内容,实现跨设备的视觉工作流编排。
三个平台对 Canvas 的渲染实现各有差异:macOS 使用 WebKit 视图,iOS 使用 SwiftUI 原生视图层结合 WebKit 渲染,Android 使用 Android WebView。但上层的 A2UI 协议保证了 Agent 无需关心底层渲染差异。
A2UI 的 bundle 文件位于 src/canvas-host/a2ui/a2ui.bundle.js,其哈希值记录在 src/canvas-host/a2ui/.bundle.hash(自动生成,不应手动编辑)。构建命令为 pnpm canvas:a2ui:bundle 或 scripts/bundle-a2ui.sh。在 pnpm build 的完整构建管线中,A2UI bundle 作为第一步执行。
交叉编译是一个已知痛点。在 Apple Silicon 上构建 amd64 镜像时,A2UI bundle 可能因 QEMU 模拟环境的限制而失败。Dockerfile 对此做了优雅降级处理:bundle 失败时创建一个 stub 文件(包含注释 /* A2UI bundle unavailable in this build */),并同时清理 vendor/a2ui 和 apps/shared/OpenClawKit/Tools/CanvasA2UI 目录,确保构建不会因 A2UI 不可用而中断。CI 构建在原生架构上执行,因此不受此影响。
Canvas 的安全定位是理解其设计边界的关键。canvas.eval 允许 Agent 在 Canvas 中执行任意 JavaScript 代码,这在功能上等同于一个浏览器端的 eval()。OpenClaw 将此明确归类为 Operator 控制面——与浏览器自动化工具中的脚本执行类似,安全责任在于部署者而非平台。这种定位与 OpenClaw 的单用户、本地优先架构一致:在用户自己的设备上,Agent 本就拥有与用户相当的权限。但在多租户或公开部署场景中,Operator 必须评估 Canvas eval 带来的风险并做出适当限制。
Lobster 是 OpenClaw 生态中的工作流编排 Shell,独立仓库位于 openclaw/lobster(992 stars)。其定位口号是 "OpenClaw native workflow Shell" — 一个为 OpenClaw 原生设计的工作流执行环境。
Lobster 的核心抽象是类型化 JSON 管线(Typed JSON Pipelines)。与 Unix shell 的文本管道不同,Lobster 管线中流动的数据是带有类型约束的 JSON 结构。每个管线步骤声明其输入 schema 和输出 schema,Lobster 在管线组装阶段即可进行类型检查,而非等到运行时才暴露类型不匹配的问题。
管线架构是可组合的(Composable Pipeline Architecture):开发者可以将 OpenClaw 的 Skills 和 Tools 链接为多步骤工作流。每个步骤可以是一个 Skill 调用、一个 Tool 执行、一段自定义逻辑,或者一个嵌套的子管线。
关键的流控机制是审批门(Approval Gates)。管线中可以在任意步骤之间插入审批点,执行会暂停并等待指定审批人(人类或其他 Agent)的确认后才继续推进。这对于涉及敏感操作的自动化流程至关重要 — 例如在部署管线中,代码编译步骤自动执行,但推送至生产环境之前需要人工审批。
Lobster 对终端输出的视觉一致性有严格要求。色彩定义集中在 src/terminal/palette.ts 模块,该模块导出一套共享的终端颜色调色板(Terminal Color Palette)。所有面向终端的输出 — 包括 onboarding 引导流程、配置提示(config prompts)与 TTY UI 输出 — 都必须引用调色板中定义的颜色常量,严禁在代码中硬编码颜色值。
|
1 2 3 4 5 6 7 8 9 10 |
// src/terminal/palette.ts export const palette = { primary: chalk.hex('#5B8DEF'), success: chalk.hex('#6BCB77'), warning: chalk.hex('#FFD93D'), error: chalk.hex('#FF6B6B'), muted: chalk.gray, highlight: chalk.bold.white, // ... 更多颜色定义 } as const; |
这一设计确保了 Lobster 在不同终端模拟器和配色方案下的视觉一致性,同时简化了主题定制。
Caclawphony(仓库 openclaw/caclawphony,34 stars)是构建在 Lobster 之上的 Symphony 系统。它的核心能力是将项目级任务分解为相互隔离的自主执行单元(Isolated Autonomous Execution Runs)。每个执行单元拥有独立的上下文、工具集与沙箱环境,多个单元可以并行运行。
Caclawphony 适用于大规模项目重构、批量代码迁移等需要将工作分而治之的场景。项目经理(人类或 Agent)在顶层定义任务分解策略,Caclawphony 负责将其转化为可并行执行的 Lobster 管线集合。
Caclawphony 与 OpenClaw 主仓库的 Session 工具形成互补:sessions_send 提供 Agent 间的点对点通信,而 Caclawphony 提供的是任务级的编排框架——它关心的是"哪些工作单元需要并行/串行执行",而非"Agent A 如何向 Agent B 发消息"。两者结合,构成了从单次对话到复杂项目执行的完整 Agent 协作栈。
Lobster 的名称选择(龙虾)并非随意。在 OpenClaw 的概念体系中,龙虾象征着两个工程理念:其一,龙虾的螯足(claw)代表工具——Lobster 管线中的每个步骤都是一个可独立运行的工具调用;其二,龙虾的蜕壳(molt)代表版本演进——管线可以在保持外部接口不变的情况下替换内部实现。
Lobster 管线与 Unix 管道的另一个关键区别在于错误处理语义。Unix 管道中,上游命令的非零退出码可以被下游忽略(除非设置了 set -o pipefail)。Lobster 管线的每个步骤都必须显式声明其错误处理策略:fail-fast(任何错误立即终止整条管线)、retry(按指数退避重试)、skip(记录错误但继续执行)或 fallback(切换到备选步骤)。这种显式的错误处理语义使得 Lobster 管线在可靠性上远超 Shell 脚本。
Lobster 管线可以与 OpenClaw 的 Cron 调度系统结合,实现定时自动化。Cron 负责触发时机,Lobster 负责执行逻辑。典型应用包括:每日凌晨执行代码质量扫描管线、每周生成项目状态报告管线、在特定事件触发后延迟执行清理管线等。Cron 触发器将 Lobster 管线 ID 作为执行载荷传递,Gateway 的调度器负责在指定时间实例化管线并开始执行。
OpenClaw 的 Web 管理界面——Control UI——直接由 Gateway 进程托管和分发,不需要独立的前端服务器。UI 源码位于 ui/ 目录,使用 Lit 3(Google 的 Web Components 库)构建,以 Vite 作为开发服务器和构建工具。构建命令为 pnpm ui:build,产出物嵌入到 Gateway 的静态资源路径中。
选择 Lit 而非 React/Vue/Svelte 体现了 OpenClaw 的工程偏好:Lit 基于 Web Components 标准,无需虚拟 DOM 运行时,产出的 bundle 体积极小,且与 Gateway 的原生 HTTP 服务天然兼容。Control UI 的功能覆盖会话管理、渠道状态监控、配置编辑、Skills 管理和 Agent 交互。UI 构建系统支持信号(Signals)响应式模式,通过 @lit-labs/signals@0.2.0 和 signal-utils@0.21.1 实现细粒度的 UI 更新。
UI 还有独立的测试流水线 pnpm test:ui,以及专门的 lint 规则 lint:ui:no-raw-window-open 防止在 UI 代码中使用原始的 window.open()(应使用框架提供的安全包装)。
WebChat(详见 docs.openclaw.ai/web/webchat)是 Control UI 中内嵌的对话界面,直接使用 Gateway 的 WebSocket 连接——无需独立的 WebChat 端口或额外配置。安装完 Gateway 后,用户在浏览器中访问 http://localhost:18789 即可开始与 Agent 对话。
WebChat 同时也是 macOS App 的内嵌 Web 视图,通过 macOS 的 WebKit 视图直接加载。这种架构复用确保了 Web 端和 macOS 端的对话体验一致。
OpenClaw 的浏览器控制工具(详见 docs.openclaw.ai/tools/browser)是核心工具体系中最复杂的模块之一。它使用 playwright-core@1.58.2 通过 CDP(Chrome DevTools Protocol)控制一个专属的 Chromium 实例——不是用户的日常浏览器,而是 OpenClaw 管理的独立实例,拥有独立的浏览器配置文件(Profile)。
浏览器控制的核心能力包括:
- 页面快照(Snapshots):捕获页面的 DOM 状态和视觉渲染,供 Agent 分析页面内容
- 结构化操作(Actions):点击、填写表单、滚动、导航——Agent 通过结构化指令驱动浏览器,而非注入自由 JavaScript
- 文件上传:Agent 可以指示浏览器在文件选择器中上传指定文件
- 多 Profile 隔离:不同任务可以使用不同的浏览器配置文件,保持 Cookie 和登录状态的隔离
浏览器工具的配置通过 JSON 声明:
|
1 2 3 4 5 6 |
{ "browser": { "enabled": true, "color": "#FF4500" } } |
color 参数控制浏览器窗口的标题栏颜色——这是一个细节设计,当 Agent 控制的浏览器窗口出现在屏幕上时,用户可以通过颜色快速区分它与自己的日常浏览器。
Docker 镜像构建时,可以通过 --build-arg OPENCLAW_INSTALL_BROWSER=1 预安装 Chromium 和 Xvfb(X Virtual Frame Buffer),增加约 300MB 镜像体积,但省去了每次容器启动时 60-90 秒的 Playwright 安装时间。这对 CI/CD 场景尤其重要。
OpenClaw 的一等工具(First-class Tools)是平台核心能力的直接延伸,区别于通过 Skills 或 MCP 接入的第三方工具。一等工具直接集成在 Gateway 和 Agent 运行时中,享有完整的安全策略和沙箱支持:
| 工具 | 能力 | 文档 |
| Browser | 专属 Chromium 控制、CDP 快照、结构化操作、文件上传 | docs.openclaw.ai/tools/browser |
| Canvas | A2UI 驱动的可视化工作区(push/reset/eval/snapshot) | docs.openclaw.ai/platforms/mac/canvas |
| Nodes | 设备端操作:camera snap/clip、screen record、location.get、notifications | docs.openclaw.ai/nodes |
| Cron | 定时任务调度与自动化触发 | docs.openclaw.ai/automation/cron-jobs |
| Sessions | sessions_list / sessions_history / sessions_send(Agent 间通信) | docs.openclaw.ai/concepts/session-tool |
| Webhooks | 接收外部 HTTP 回调并触发 Agent 处理 | docs.openclaw.ai/automation/webhook |
| Gmail Pub/Sub | Gmail 邮件到达事件驱动 | docs.openclaw.ai/automation/gmail-pubsub |
| Discord/Slack Actions | 平台原生交互(斜杠命令、按钮、下拉菜单) | 渠道文档内嵌 |
在沙箱模式下,工具的可用性受到严格约束。非主会话(non-main sessions)的 Docker 沙箱中,默认允许的工具包括 bash、process、read、write、edit 以及 sessions 系列;默认禁止的工具包括 browser、canvas、nodes、cron、discord、gateway。这种白名单+黑名单的双层控制确保了多租户场景下的安全隔离。
OpenClaw 的安全模型覆盖了从消息入口到执行环境的完整链路。本章从 DM(Direct Message)配对的接入控制讲起,经过沙箱隔离的执行边界,到安全基础设施与凭证管理,系统性地拆解 OpenClaw 的安全架构。
OpenClaw 的默认 DM 安全策略(dmPolicy)设置为 "pairing"。在此模式下,任何未知发送者发起的 DM 会话都会收到一个配对码(Pairing Code),用户需要在服务器端通过 CLI 确认才能建立信任关系。
三种 DM 策略模式的对比:
| 模式 | 行为 | 安全级别 |
| pairing(默认) | 未知发送者收到配对码,需管理员批准 | 高 |
| allowlist | 仅白名单中的用户可发起 DM | 高 |
| open | 接受所有 DM(需同时配置 allowFrom: "*") | 低 |
配对审批通过 CLI 命令完成:
|
1 |
openclaw pairing approve <channel> <code> |
每个渠道的允许列表通过 allowFrom 字段独立配置。例如 channels.telegram.allowFrom、channels.discord.allowFrom 分别控制 Telegram 和 Discord 渠道的准入名单。
公开 DM 访问需要双重显式授权:dmPolicy="open" 和 allowFrom 数组中包含 "*" 通配符。仅设置其中一项不会开放公开访问 — 这是一项有意为之的双重门控设计,防止配置笔误导致意外暴露。
openclaw doctor 会主动检测并告警风险或错误的 DM 策略配置,包括但不限于:open 模式下缺少 allowFrom 通配符、allowlist 模式下白名单为空等异常情况。
历史遗留的配置键名 channels.discord.dm.policy 已迁移为 channels.discord.dmPolicy。旧格式在当前版本仍可被识别,但会触发弃用警告。
OpenClaw 的沙箱策略通过 agents.defaults.sandbox.mode 配置。推荐的默认值为 "non-main",意味着非主会话(群组会话、频道会话等)自动进入沙箱隔离环境。
这一设计基于 OpenClaw 的单用户设计假设:主会话(Main Session)的操作者是服务的所有者,拥有完整的宿主机访问权限,工具在宿主机上直接执行。而非主会话来自外部用户,每个会话在独立的 Docker 沙箱容器中执行,彼此以及与宿主机之间完全隔离。
沙箱内的工具可用性由白名单和黑名单双重控制:
| 类别 | 工具列表 |
| 沙箱白名单(允许使用) | bash, process, read, write, edit, sessions_list, sessions_history, sessions_send, sessions_spawn |
| 沙箱黑名单(禁止使用) | browser, canvas, nodes, cron, discord, gateway |
黑名单中的工具若在沙箱会话中被调用,将返回明确的权限拒绝错误而非静默忽略。
OpenClaw 的安全策略文档维护在独立仓库 openclaw/trust(35 stars),对外发布于 trust.openclaw.ai。该仓库包含完整的威胁模型(Threat Model)文档。安全漏洞报告通过 security@openclaw.ai 接收。
OpenClaw Plugin SDK 导出 ssrf-runtime 模块,供插件在发起网络请求时使用。该模块会校验目标地址,阻止对内网地址(RFC 1918)、环回地址、链路本地地址以及云元数据端点的访问,从而防范 SSRF(Server-Side Request Forgery,服务端请求伪造)攻击。所有插件的网络调用都应通过此模块路由,而非直接使用 fetch 或 http 模块。
OpenClaw 将 Prompt Injection(提示注入)正式声明为范围外(Out of Scope)— 不将其视为安全漏洞。这一立场基于现实考量:当前 LLM 架构下不存在可靠的 prompt injection 防御手段,将其纳入漏洞范围只会制造虚假的安全承诺。相应地,canvas.eval 和浏览器脚本执行均被归类为 Operator 控制面,安全边界由部署方自行划定。
插件安装流程的安全管控在 v2026.3.28 至 v2026.3.31 之间经历了显著强化。
安装流程中的 before_install 钩子为安全扫描器提供了集成点。任何外部安全扫描工具都可以注册为 before_install 处理器,在插件代码落盘前进行检查。
v2026.3.31 破坏性变更:内置的危险代码检测器现在对 "critical" 级别的发现默认执行关闭失败(Fail Closed)策略。此前,critical 级别的发现仅生成警告,管理员可以选择忽略。新策略下,标记为 critical 的发现会直接阻止安装。如需强制安装已标记的插件,必须使用显式的覆盖参数:
|
1 |
openclaw plugin install <name> --dangerously-force-unsafe-install |
该参数名称的冗长是有意为之 — 让每次使用都足够刻意,避免误操作。Skills 安装和 Plugins 安装都受到相同的扫描门控约束。
v2026.3.31 对 Gateway 的认证机制进行了多项收紧:
trusted-proxy 模式拒绝混合共享令牌配置(Mixed Shared-token Configs)。如果检测到多个服务共用同一认证令牌,Gateway 将拒绝启动并报告配置冲突。
local-direct 回退模式现在要求显式配置令牌。此前,同一主机上的连接可以隐式获得认证(Implicit Same-host Auth),这在多租户部署场景下存在风险。新版本移除了这一隐式信任,所有连接都必须提供有效令牌。
节点配对审批(Node Pairing Approval)成为强制前提 — 节点命令直到配对审批完成后才暴露。节点发起的运行(Node-originated Runs)被限制在缩减的可信执行面上。
OpenClaw 的凭证统一存储于 ~/.openclaw/credentials/ 目录。Web 服务提供商的凭证刷新通过 openclaw login 命令重新执行 OAuth 流程。
Provider 插件中的密钥引用使用 SecretRef 语义 — 配置文件中仅存储密钥的引用标识符而非明文值,运行时由凭证管理器解析为实际密钥。这一设计确保配置文件可以安全地纳入版本控制。
关于内容安全的基本原则:永远不要提交真实的电话号码、视频文件或生产环境配置值到代码仓库中。
OpenClaw 的构建与测试基础设施是其工程纪律的集中体现。本章逐一拆解构建工具链的选型、198 个 npm 脚本的分类、测试基础设施的架构设计以及代码质量门控的实施细节。
OpenClaw 的构建工具选型刻意回避了主流的 webpack/rollup/esbuild 全家桶模式,转而采用一套更专注的工具组合:
| 工具 | 版本 | 职责 |
| tsdown | 0.21.7 | 打包器(bundler),通过 scripts/tsdown-build.mjs 驱动 |
| TypeScript | 6.0.2 | 类型检查 |
| @typescript/native-preview | 7.0.0-dev.20260331.1 | Go 实现的 TypeScript 编译器预览版(pnpm tsgo) |
| oxfmt | 0.43.0 | 代码格式化(取代 Prettier) |
| oxlint + oxlint-tsgolint | 1.58.0 / 0.18.1 | 代码检查(取代 ESLint) |
| Bun | - | 开发/测试阶段的 TypeScript 执行器 |
| Node 22+ | - | 生产运行时(保持 Node + Bun 双路径兼容) |
| tsx | 4.21.0 | 基于 Node 的 TypeScript 执行 |
| jiti | 2.6.1 | 运行时 ESM 解析(plugin-sdk 别名解析) |
几点选型要点值得展开:
tsdown 而非直接使用 esbuild:tsdown 在 esbuild 之上提供了更高层的打包抽象,其配置文件比直接编写 esbuild 插件更简洁。构建入口是 scripts/tsdown-build.mjs。
@typescript/native-preview:这是 TypeScript 官方的 Go 语言重写实验版本,通过 pnpm tsgo 调用。其类型检查速度比标准 TypeScript 编译器快一个数量级,OpenClaw 将其用于 CI 中的快速类型检查路径。
oxfmt / oxlint:基于 Rust 的格式化和检查工具链,替代了传统的 Prettier + ESLint 组合。格式化命令为 pnpm format(检查)和 pnpm format:fix(自动修复),检查命令为 pnpm lint。
Bun + Node 双运行时:开发和测试阶段使用 Bun 获得更快的启动速度(bun <file.ts>、bunx <tool>),生产部署使用 Node 22+ 确保兼容性。两条路径必须同时保持可用。
完整构建管线:
|
1 2 3 4 5 |
pnpm build # 展开为: # 1. pnpm canvas:a2ui:bundle → A2UI bundle 构建 # 2. scripts/tsdown-build.mjs → 主体打包 # 3. runtime-postbuild.mjs → 运行时后处理 |
三种构建变体服务于不同场景:
| 变体 | 命令 | 用途 |
| 完整构建 | pnpm build | 包含 A2UI bundle + 主体 + 后处理 |
| Docker 构建 | pnpm build:docker | 跳过 A2UI bundle(可能在 QEMU 下失败) |
| 严格冒烟测试 | pnpm build:strict-smoke | 快速验证构建产物的基本可用性 |
OpenClaw 的 package.json 包含 198 个 npm 脚本。这个数字并非膨胀 — 它反映了一个覆盖多平台、多渠道、多插件的工程体系所需的自动化指令密度。以下按职责分类:
build、build:docker、build:plugin-sdk:dts、build:strict-smoke — 核心构建管线及其变体,加上 Plugin SDK 的类型声明生成。
以 pnpm check 作为元检查入口,编排 tsgo、lint、format、format:check 及约 20 个特定规则检查脚本。详见 17.6 节的 CI 架构分析。
测试脚本是数量最多的一组:test、test:fast、test:watch、test:coverage、test:e2e、test:live、test:gateway、test:channels、test:extensions、test:contracts,以及一系列 test:docker:* 和 test:parallels:* 脚本。
release:check、release:openclaw:npm:check、release:plugins:npm:check — 发布前的版本号、changelog、npm registry 一致性校验。
android:*、ios:*、ui:* — 各平台的构建、测试、lint 快捷入口。
docs:check-links(死链检测)、docs:spellcheck(拼写检查)、docs:check-i18n-glossary(国际化术语表一致性)。
protocol:check(协议定义一致性检查)、protocol:gen(生成 TypeScript 类型)、protocol:gen:swift(生成 Swift 类型)。
OpenClaw 使用 Vitest 4.1.2 作为测试框架,搭配 @vitest/coverage-v8 进行 V8 引擎级别的代码覆盖率采集。覆盖率门槛统一设置为 70%,覆盖 lines、branches、functions、statements 四个维度。
一条关键的强制规则:Vitest 的并发模式只允许使用 forks 池。threads、vmThreads、vmForks 三种模式被显式禁用。这一限制源于 OpenClaw 测试中大量涉及进程级副作用(子进程创建、文件系统操作、网络端口占用等),线程级隔离无法提供足够的隔离保障。
并行测试编排由 test-parallel.mjs 脚本驱动,提供三种执行配置:
| 配置 | 并行度 | 用途 |
| default | CPU 核心数的 50% | 日常开发,平衡速度与系统响应性 |
| serial | 1 | 调试失败用例,排除并发干扰 |
| max | CPU 核心数的 100% | CI 环境,最大化吞吐 |
测试体系覆盖多个层级,每个层级关注不同粒度的验证需求:
单元测试与集成测试:pnpm test(全量运行)、pnpm test:fast(排除慢速用例)、pnpm test:watch(文件监听模式)、pnpm test:coverage(带覆盖率报告)。
领域测试:test:channels(渠道集成)、test:extensions(扩展接口)、test:gateway(Gateway 协议)、test:e2e(端到端流程)、test:live(真实 API 对接)。
契约测试(Contract Tests):test:contracts:channels 和 test:contracts:plugins 分别强制渠道和插件的接口契约一致性。契约测试确保 Channel 适配器和 Plugin 遵循其声明的接口协议,防止实现漂移。
Docker E2E 测试(8+ 场景):在完整的 Docker 容器化环境中执行端到端验证。覆盖场景包括:
| 场景 | 验证范围 |
| onboard | 首次启动引导流程 |
| plugins | 插件安装、加载与执行 |
| MCP channels | MCP 协议渠道连通性 |
| gateway network | Gateway 网络拓扑与路由 |
| OpenWebUI | OpenWebUI 集成 |
| doctor-switch | doctor 诊断与配置切换 |
| qr-import | QR 码配置导入 |
| live models | 真实模型端点对接 |
Parallels 冒烟测试:在 macOS、Windows、Linux 三个虚拟机客户端上执行冒烟测试,验证跨操作系统的基本功能可用性。
性能测试套件:
| 脚本 | 度量维度 |
| test:perf:budget | 性能预算检查(运行时间/内存上限) |
| test:perf:hotspots | 热点函数 profiling |
| test:perf:imports | 模块导入耗时分析 |
| test:startup:bench | 启动时间基准 |
| test:startup:memory | 启动内存占用 |
Live 测试:通过设置环境变量 OPENCLAW_LIVE_TEST=1 启用,执行 pnpm test:live。这些测试使用真实的 API 密钥调用外部服务,因此不在常规 CI 中运行,而是在专用的 live 测试环境中定期执行。
OpenClaw 对代码质量的门控措施密度极高,以下逐一展开:
文件行数限制:check:loc 脚本强制执行约 500-700 行的文件行数上限。超过上限的文件会被标记为需要拆分。这是一项软性但有强制检查的编码指南,目标是防止出现难以维护的巨型文件。
严格类型纪律:禁止使用 @ts-nocheck,避免使用 any 类型,优先使用 unknown。在对外边界(配置文件、Webhook 载荷、CLI 输出、API 响应)处优先使用 zod@4.3.6 进行运行时 schema 校验。
动态导入防护:构建系统会检测同一模块同时存在静态导入和动态导入的情况,并发出 INEFFECTIVE_DYNAMIC_IMPORT 警告。这种混用模式会导致 tree-shaking 失效 — 模块已经通过静态导入被打包,动态导入不会带来额外的按需加载收益,反而增加了代码理解的复杂度。
重复代码检测:使用 jscpd@4.0.8 扫描 src/、extensions/、test/、scripts/ 目录下的代码重复。超过阈值的重复块会触发 CI 失败。
漂移检测:一系列 check 脚本监控各类定义与实现之间的一致性:
| 检查 | 检测内容 |
| canon:check | 规范代码样式一致性 |
| plugin-sdk:api:check | Plugin SDK 公开 API 漂移检测 |
| config:docs:check | 配置 schema 与文档的一致性 |
| lint:plugins:plugin-sdk-subpaths-exported | Plugin SDK 子路径导出完整性 |
此外还有 8 个以上针对特定扩展(Extension)的边界 lint 规则,确保各扩展模块不会越界访问其他扩展的内部 API。
OpenClaw 的 CI 采用两层检查体系(Two-tier Check System),将本地开发门控与 CI 门控分离:
pnpm check 是每次提交前必须通过的本地检查。其执行顺序为:
|
1 2 3 4 5 6 |
# pnpm check 的执行序列: # 1. no-conflict-markers → 检测未解决的合并冲突标记 # 2. host-env-policy:swift → 验证 Swift 宿主环境策略 # 3. tsgo → Go 版 TypeScript 类型检查 # 4. lint → oxlint 代码检查 # 5. format → oxfmt 格式校验 |
该管线为串行执行,任何步骤失败都会终止后续步骤并报告错误位置。
check-additional 在 CI 环境中额外执行,包含架构策略和边界策略守卫。这些检查被有意排除在本地开发循环之外 — 它们通常运行较慢且依赖 CI 专有环境(如完整的 git 历史、所有分支的 diff 信息等),放入本地循环会严重拖慢开发节奏。
Pre-commit 钩子由 prek 工具管理,钩子的默认行为是执行完整的 pnpm check 管线。
对于需要快速迭代的场景,环境变量 FAST_COMMIT=1 可以跳过 format 和 check 步骤:
|
1 2 |
# 跳过格式和检查(手动保证代码质量时使用) FAST_COMMIT=1 git commit -m "wip: experimental changes" |
使用 FAST_COMMIT 意味着开发者自行承担代码质量责任 — CI 仍会执行完整检查,不符合要求的提交将在 CI 阶段被拦截。
代码合入主分支(main)的准入门槛(Landing Bar)为:
|
1 2 3 4 |
# 主分支准入三件套: pnpm check # 类型 + lint + 格式 pnpm test # 全量测试 pnpm build # 构建验证(当变更涉及构建影响面时) |
第三项 pnpm build 是条件性的:仅在变更涉及构建影响面(build-affecting surfaces)时才要求。构建影响面的定义包括但不限于:tsdown-build.mjs 配置变更、package.json 依赖变更、tsconfig.json 变更、新增或删除模块导出等。纯粹的逻辑变更(函数实现调整、bug 修复等)不触发构建要求,以此平衡 CI 速度与安全性。
OpenClaw 的部署策略覆盖了从单人开发者到企业团队的全部场景。部署方式按复杂度递增排列:npm 全局安装、Docker 容器化、Ansible 编排、Nix 声明式配置、Windows 系统托盘。每种方式对应不同的运维哲学和安全模型。
对于大多数开发者而言,npm 全局安装是进入 OpenClaw 最快的路径:
|
1 2 |
npm install -g openclaw@latest openclaw onboard --install-daemon |
第一条命令将 OpenClaw CLI 及其全部依赖安装到 Node.js 的全局 node_modules 目录。第二条命令启动交互式引导向导(Onboarding Wizard),--install-daemon 标志指示向导在流程结束后自动注册系统守护进程(Daemon)。
守护进程的注册方式因操作系统而异。在 macOS 上,OpenClaw 生成一个 launchd plist 文件并通过 launchctl load 注册为用户级别的 Launch Agent。plist 的关键配置如下:
|
1 2 3 4 5 6 7 8 9 10 11 |
<key>Label</key> <string>ai.openclaw.gateway</string> <key>ProgramArguments</key> <array> <string>/usr/local/bin/node</string> <string>/usr/local/lib/node_modules/openclaw/dist/gateway.js</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> |
在 Linux 上,OpenClaw 采用 systemd 用户服务(user service),将单元文件写入 ~/.config/systemd/user/openclaw-gateway.service,并通过 systemctl --user enable --now openclaw-gateway 启动。这一选择的关键在于"用户级别"——无需 root 权限,服务生命周期与用户会话绑定,遵循最小权限原则。配合 loginctl enable-linger 可以实现即使用户未登录也保持运行。
Docker 部署是 OpenClaw 为生产环境和隔离场景提供的首选方案。其 Dockerfile 采用多阶段构建(Multi-Stage Build)模式,共分四个阶段,每个阶段都经过精心设计以最小化最终镜像体积。
第一阶段的唯一职责是从 extensions/ 目录树中提取所有 package.json 文件,同时保留其目录结构。这是一个纯文件复制阶段,不执行任何安装操作:
|
1 2 3 4 5 |
FROM node:24-bookworm AS ext-deps WORKDIR /app COPY extensions/ extensions/ RUN find extensions -name "package.json" -exec sh -c \ 'mkdir -p /out/$(dirname {}) && cp {} /out/{}' \; |
这种分离的目的是利用 Docker 的层缓存机制——只有当扩展的 package.json 发生变化时,后续的依赖安装层才会失效。
构建阶段使用 Bun 作为 JavaScript 运行时加速依赖安装,同时以 pnpm 作为包管理器,tsdown 作为 TypeScript 编译工具:
|
1 2 3 4 5 6 7 8 |
FROM oven/bun:1 AS build WORKDIR /app COPY --from=ext-deps /out/extensions ./extensions COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ RUN pnpm install --frozen-lockfile COPY . . RUN pnpm run build RUN cd ui && pnpm run build |
构建产物包括两部分:dist/ 目录下的 TypeScript 编译输出(通过 tsdown 生成),以及 ui/dist/ 目录下的 Web Control UI 静态资源(通过 Vite 构建)。
第三阶段是整个构建流水线中最关键的体积优化环节:
|
1 2 3 4 5 |
FROM build AS runtime-assets RUN pnpm prune --prod RUN find . -name "*.d.ts" -delete \ && find . -name "*.map" -delete \ && find . -name "*.ts" ! -name "*.d.ts" -path "*/src/*" -delete |
首先通过 pnpm prune --prod 移除所有 devDependencies,然后逐一清除 TypeScript 声明文件(.d.ts)、Source Map 文件(.map)和源码文件。最终只保留 JavaScript 运行时代码和生产级依赖。
最终阶段基于精简的 Node 24 镜像,且所有基础镜像均采用固定 SHA256 摘要(Pinned SHA256 Digest)以确保构建可复现:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 默认变体 FROM node:24-bookworm@sha256:abc123... AS runtime # 精简变体 # FROM node:24-bookworm-slim@sha256:def456... AS runtime USER node WORKDIR /home/node/app COPY --from=runtime-assets --chown=node:node /app ./ HEALTHCHECK --interval=3m --timeout=10s --start-period=30s \ CMD curl -f http://localhost:18789/healthz || exit 1 EXPOSE 18789 18790 CMD ["node", "dist/gateway.js"] |
OpenClaw 提供两个镜像变体(Variant),通过构建参数 OPENCLAW_VARIANT 选择:
| 变体 | 基础镜像 | 特点 | 适用场景 |
| default | node:24-bookworm | 包含完整 Debian 工具链,支持浏览器安装 | 需要 Playwright/浏览器渠道 |
| slim | node:24-bookworm-slim | 最小化系统库,镜像体积减小约 40% | 纯 CLI/API 场景 |
其余构建参数(Build Args)包括:
| 参数名 | 默认值 | 说明 |
| OPENCLAW_EXTENSIONS | all | 控制构建哪些扩展,逗号分隔或 all |
| OPENCLAW_INSTALL_BROWSER | false | 是否在镜像中预装 Chromium(Playwright) |
| OPENCLAW_INSTALL_DOCKER_CLI | false | 是否安装 Docker CLI(用于沙箱功能) |
安全方面,最终镜像以 USER node(uid 1000)运行,杜绝 root 权限。健康检查(Health Check)配置了两个端点:/healthz 用于存活探测(Liveness Probe),/readyz 用于就绪探测(Readiness Probe),检测间隔为 3 分钟,超时 10 秒,启动宽限期 30 秒。
官方 docker-compose.yml 定义了两个服务,体现了 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 30 31 32 33 |
version: "3.9" services: openclaw-gateway: image: ghcr.io/openclaw/openclaw:latest ports: - "18789:18789" - "18790:18790" volumes: - openclaw-data:/home/node/.openclaw - /var/run/docker.sock:/var/run/docker.sock security_opt: - no-new-privileges:true cap_drop: - NET_RAW - NET_ADMIN restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:18789/healthz"] interval: 3m timeout: 10s start_period: 30s openclaw-cli: image: ghcr.io/openclaw/openclaw:latest command: ["node", "dist/cli.js"] depends_on: openclaw-gateway: condition: service_healthy environment: - OPENCLAW_GATEWAY_URL=http://openclaw-gateway:18789 volumes: openclaw-data: |
安全加固(Security Hardening)体现在三处:no-new-privileges 阻止进程通过 setuid/setgid 提权;cap_drop 丢弃 NET_RAW 和 NET_ADMIN 能力(Capability),防止原始套接字操作和网络配置篡改;Docker Socket 挂载(/var/run/docker.sock)为沙箱集成提供Docker-in-Docker(DinD)能力,允许 Agent 在隔离容器中执行命令。
端口映射方面,18789 是 Gateway 的 HTTP 主端口,承载 REST API、WebSocket 连接和 Web Control UI;18790 是 Bridge 端口,供外部渠道插件通过 gRPC 或 WebSocket 桥接到 Gateway。
openclaw/openclaw-ansible(545 stars)提供了一套完整的 Ansible Playbook,将 OpenClaw 的 Docker 部署包装为可重复执行的基础设施代码(Infrastructure as Code)。其核心特性包括:
Tailscale VPN 集成:Playbook 默认集成 Tailscale,Gateway 绑定到 Tailscale 虚拟网络接口而非公网接口。这意味着 OpenClaw 实例只在 Tailnet 内可达,无需暴露任何公网端口,从根本上消除了未授权访问的风险。
UFW 防火墙配置:自动配置 UFW(Uncomplicated Firewall)规则,仅放行 SSH(22)和 Tailscale 所需端口(41641/UDP),其余入站流量全部丢弃。
Docker 隔离:OpenClaw 运行在独立 Docker 网络中,数据卷映射到宿主机的指定路径,支持通过 Ansible 变量自定义挂载点、环境变量和资源限制。
openclaw/nix-openclaw(611 stars)提供 Nix Flake 形式的声明式配置。对于 NixOS 用户或使用 home-manager 的开发者,这是最符合其工作流的部署方式:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ inputs.openclaw.url = "github:openclaw/nix-openclaw"; outputs = { self, nixpkgs, openclaw }: { nixosConfigurations.myhost = nixpkgs.lib.nixosSystem { modules = [ openclaw.nixosModules.default { services.openclaw = { enable = true; gateway.port = 18789; extensions = [ "discord" "telegram" "whatsapp" ]; }; } ]; }; }; } |
Nix 部署的优势在于完全的可复现性(Reproducibility)——相同的 Flake 输入必然产生相同的系统配置,消除了"在我机器上能跑"的环境差异问题。
openclaw/openclaw-windows-node(405 stars)为 Windows 提供了原生集成体验。其核心组件包括:
系统托盘伴侣(System Tray Companion):一个轻量级的 .NET 应用,驻留在 Windows 系统托盘。它管理 OpenClaw Gateway 进程的生命周期(启动/停止/重启),显示实时状态,并提供快捷菜单访问 Web Control UI 和日志。
PowerToys 命令面板扩展(Command Palette Extension):集成 Microsoft PowerToys 的命令面板(Run 插件),用户可以通过 Alt+Space 快捷键直接向 OpenClaw Agent 发送指令,无需切换到浏览器或终端窗口。
在远程 Linux 服务器上部署 Gateway 时,安全暴露服务是核心问题。OpenClaw 提供三种模式:
Tailscale Serve(Tailnet 内部访问):通过 tailscale serve 将 Gateway 端口映射到 Tailscale 的 HTTPS 代理,仅 Tailnet 内的设备可访问。配合 Gateway 的 --tailscale serve 模式,自动完成证书配置和端口映射。
Tailscale Funnel(公网 HTTPS 暴露):tailscale funnel 模式将服务通过 Tailscale 的全球边缘网络暴露到公网,自动获取 HTTPS 证书。适用于需要外部 Webhook 回调(如 Telegram Bot)的场景。
SSH 隧道:最传统但最灵活的方式,通过 SSH 端口转发将远程 Gateway 映射到本地:
|
1 |
ssh -L 18789:localhost:18789 -L 18790:localhost:18790 user@remote-host |
Gateway 的绑定模式(Bind Mode)通过 --bind 参数控制:loopback(默认)仅监听 127.0.0.1,lan 监听 0.0.0.0 以接受局域网连接。Tailscale 模式通过 --tailscale 参数设置:off(默认)、serve、funnel。
openclaw onboard 是 OpenClaw 的交互式初始化命令,引导用户完成从零到可用的全部配置。流程按步骤执行:
步骤一:Gateway 配置——选择绑定模式(loopback/lan)、端口、Tailscale 模式。若检测到已有 Gateway 实例运行,则询问是否复用。
步骤二:工作区配置——创建默认工作区目录(~/.openclaw/workspace),配置 LLM 提供商密钥(OpenAI API Key、Anthropic API Key 等),设置默认模型。
步骤三:渠道配置——根据用户选择启用渠道(Discord Bot Token、Telegram Bot Token、WhatsApp 手机号等),验证凭据有效性。
步骤四:Skills 配置——推荐安装热门 Skills,提示用户浏览 ClawHub 发现更多。
当附带 --install-daemon 标志时,向导结束后自动注册并启动系统守护进程。若出现问题,openclaw doctor 命令执行全面的健康检查:验证 Node.js 版本、检查端口占用、测试 LLM 连接、校验配置文件语法,并输出诊断报告及修复建议。
ClawHub(openclaw/clawhub,7,214 stars)是 OpenClaw 的官方 Skill 注册中心与分发平台。它的定位类似于 npm 之于 Node.js,或 crates.io 之于 Rust——一个集中式的包注册表,但分发的是 AI Agent 能力模块。
安装 Skill 只需一条命令:
|
1 2 |
clawhub install weather-forecast clawhub install code-review --version 2.1.0 |
ClawHub 的 Agent 集成能力是其核心差异化特性:当 Agent 在对话中遇到需要但当前未安装的能力时,可以自动搜索 ClawHub 并在用户确认后拉取安装。这一流程的实现路径是 Agent 调用内置的 clawhub_search 工具函数,该函数向 api.clawhub.com/v1/search 发送请求,返回匹配的 Skill 列表及其安全评级。
Web 端的 clawhub.com 提供可视化的市场(Marketplace)界面,支持按类别浏览、按关键词搜索、查看安装统计和社区评分。每个 Skill 页面展示其 SKILL.md 的渲染内容、依赖关系图和版本历史。
openclaw/skills(3,622 stars)是所有 Skill 的版本存档仓库,保存了每个 Skill 每个版本的完整快照。这一设计确保即使 Skill 作者删除了某个版本,已部署的实例仍可从存档拉取。
VoltAgent/awesome-openclaw-skills(43,292 stars)是社区维护的精选 Skill 列表,收录超过 5,400 个经过社区验证的 Skill。其 Star 数反映了 OpenClaw Skill 生态的活跃程度——一个"awesome 列表"的 Star 数通常是其生态规模的风向标。
OpenClaw 的 Skills 按分发方式分为三个层级:
| 层级 | 存储位置 | 安装方式 | 更新策略 |
| 内置 Skills(Bundled) | skills/ 目录,随 npm 包分发 | 自动包含 | 随 OpenClaw 版本更新 |
| 托管 Skills(Managed) | ~/.openclaw/managed/skills/ | clawhub install | clawhub update |
| 工作区 Skills(Workspace) | ~/.openclaw/workspace/skills/<name>/ | 手动创建 | 用户自行管理 |
加载优先级从上到下递增——工作区 Skills 可以覆盖同名的托管或内置 Skill,提供最大的定制灵活性。
每个 Skill 由一个 SKILL.md 文件定义,这是 AgentSkills 规范的核心载体。SKILL.md 采用带有特殊 YAML Front Matter 的 Markdown 格式:
|
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 |
--- name: code-review version: 2.1.0 description: Automated code review with multi-language support triggers: - pattern: "review {file_path}" - pattern: "check code quality" permissions: - filesystem:read - git:read before_install: scripts/check-deps.sh --- # Code Review Skill ## Instructions You are a senior code reviewer. When triggered, analyze the provided file for bugs, style issues, and potential improvements. ## Tools ### review_file Analyze a single file and return findings. - `file_path` (string, required): Path to the file to review - `severity` (string, optional): Minimum severity to report (info|warn|error) |
其中 before_install 字段指定一个安全钩子(Security Hook)脚本,在安装阶段执行。该脚本用于验证系统依赖(如检查 Python 版本、确认特定二进制文件存在),并以非零退出码阻止安装。这一机制的安全意义在于:它为 Skill 作者提供了一个声明式的前置检查点,防止不兼容的 Skill 被安装到不具备运行条件的环境中。
OpenClaw 组织下维护着一系列功能各异的子仓库:
| 仓库 | Stars | 定位 |
| openclaw/acpx | 1,834 | 无头 ACP CLI(Agent Control Protocol 命令行客户端) |
| openclaw/lobster | 992 | 工作流 Shell(Workflow Shell),交互式任务编排 |
| openclaw/nix-openclaw | 611 | Nix Flake 声明式部署 |
| openclaw/openclaw-ansible | 545 | Ansible Playbook 自动化部署 |
| openclaw/openclaw-windows-node | 405 | Windows 系统托盘 + PowerToys 集成 |
| openclaw/openclaw.ai | 250 | 官方网站源码 |
| openclaw/community | 92 | 社区治理文档与 Discord 管理策略 |
| openclaw/trust | 35 | 安全策略、漏洞披露流程、审计报告 |
| openclaw/caclawphony | 34 | Symphony 自主运行框架,长时间无人值守 Agent 任务 |
OpenClaw 并非孤立存在。以下项目在不同维度上与其构成竞争或互补关系:
HKUDS/nanobot(37,216 stars)定位为"超轻量 OpenClaw 替代品",去除了多渠道和插件系统的复杂性,聚焦于单一 CLI 场景下的极速响应。其核心卖点是亚秒级冷启动和极低内存占用,适合资源受限的边缘设备。
chatgpt-on-wechat/CowAgent(42,673 stars)以微信生态为核心战场,提供企业微信、公众号、小程序等深度集成。在中国市场,微信的渗透率使其成为 AI Agent 的天然入口,CowAgent 在这一垂直领域的覆盖深度超过 OpenClaw。
AstrBot(28,373 stars)是一个 IM 聊天机器人框架,支持 QQ、飞书、钉钉等国内主流即时通讯平台。与 OpenClaw 的平台无关性不同,AstrBot 选择深耕国内生态,提供更贴合国内开发者习惯的 API 设计。
OpenClaw 的文档基于 Mintlify 构建,部署在 docs.openclaw.ai。中文本地化版本位于 docs.openclaw.ai/zh-CN。
国际化(i18n)流水线的技术实现值得关注:翻译工作由 scripts/docs-i18n 脚本驱动,该脚本读取 glossary.zh-CN.json 作为术语表(Glossary),确保专有名词翻译一致(例如 "Gateway" 始终翻译为"网关","Skill" 保留英文)。翻译记忆(Translation Memory)存储在 zh-CN.tm.jsonl 文件中,采用 JSON Lines 格式,每行一对源文本与译文。该文件的作用类似于传统本地化工具中的 TMX 文件——当源文本发生变化时,i18n 脚本先在翻译记忆中查找完全匹配或模糊匹配,避免重复翻译已有内容。
社区交流的主阵地是 Discord(discord.gg/clawd),这也是获取实时开发进度和与维护者直接交流的主要渠道。
以下表格从多个维度对比 OpenClaw 与当前主流 AI Agent 框架:
| 维度 | OpenClaw | Manus | AutoGen | LangChain | OpenHands |
| 协议 | MIT | 闭源 SaaS | MIT (CC-BY-4.0 docs) | MIT | MIT |
| 部署方式 | 本地优先 + Docker + Ansible | 纯云端 | 本地 / 云端 | 本地 / 云端 | Docker 容器 |
| 主语言 | TypeScript | 未公开 | Python | Python | Python |
| 多渠道 | Discord/Telegram/WhatsApp/Slack/Web/SMS 等 15+ | Web 唯一入口 | 无原生渠道 | 无原生渠道 | Web UI |
| 语音支持 | 原生 Realtime API | 有 | 无 | 社区扩展 | 无 |
| 插件系统 | Skills + 插件 SDK + ClawHub | 内置工具 | 工具注册 | 工具/链/代理 | 沙箱工具 |
| 记忆系统 | SQLite + 向量 + 知识图谱 | 云端对话历史 | 内存状态 | 多种 Memory 类型 | 对话历史 |
| 安全模型 | 三层沙箱 + 权限 DSL + 审计日志 | 平台托管 | 无内置沙箱 | 无内置沙箱 | Docker 沙箱 |
| 社区规模 | 342K stars, 20K+ commits | N/A(闭源) | 42K stars | 105K stars | 55K stars |
从对比中可以提炼出 OpenClaw 的三个核心差异化支柱:
本地优先(Local-First):所有数据默认存储在用户设备上。Gateway 进程运行在本地或用户控制的服务器上,LLM API 调用从用户设备直接发出,不经过任何第三方中转服务器。这一设计对于受数据合规要求约束的企业用户尤为关键——GDPR、HIPAA 等法规对数据离境有严格限制,本地优先架构天然满足这些要求。
多渠道原生支持(Multi-Channel Native):不是通过适配器(Adapter)将单一接口包装成多个渠道,而是在架构层面将渠道(Channel)作为一等公民(First-Class Citizen)。每个渠道有独立的消息格式化器(Formatter)、权限模型和用户身份映射。
MIT 全开放:不设 Enterprise 版本,不保留核心功能的闭源组件。所有功能对所有用户完全免费。这种策略在商业模式上高度依赖赞助商和社区贡献,但在信任建立上极为有效。
OpenAI、NVIDIA 和 Vercel 为何赞助一个本地优先的"竞争者"?这一看似矛盾的赞助关系背后是清晰的战略逻辑:
OpenAI:OpenClaw 的每一次 Agent 调用都消耗 OpenAI 的 API Token。本地优先≠不用云模型,恰恰相反——OpenClaw 是 OpenAI API 的超级分发渠道。每个 OpenClaw 用户都是潜在的 API 付费用户,且使用频率远高于普通 ChatGPT 用户。赞助 OpenClaw 是一种生态锁定(Ecosystem Lock-in)策略:当开发者习惯了 OpenClaw + GPT-4 的工作流,切换到其他模型的成本就会显著上升。
NVIDIA:本地推理(Local Inference)是 OpenClaw 的长期演进方向之一。当用户开始在本地运行开源 LLM 时,对 GPU 算力的需求直接转化为 NVIDIA 的硬件销售。赞助 OpenClaw 是在培育本地推理(Local Inference)的市场需求。
Vercel:OpenClaw 的 Web Control UI、文档站点、ClawHub 市场均可部署在 Vercel 平台上。赞助开源项目是 Vercel 拓展开发者工具生态的标准动作,与其赞助 Next.js、Turborepo 的逻辑一致。
客观评估,OpenClaw 面临以下结构性挑战:
16,843 个待处理 Issue:截至 2026 年 4 月,仓库有超过 16,000 个开放 Issue。这一数字反映了极高的用户参与度,但同时也意味着维护团队面临巨大的分诊压力(Triage Pressure)。大量 Issue 长期无响应,社区信任可能随时间侵蚀。
Node.js 环境门槛:对于非 JavaScript 开发者,安装和维护 Node.js 环境本身就是一个障碍。Python 生态的 AutoGen 和 LangChain 在这一点上有天然优势——Python 的安装和环境管理对数据科学家和研究人员更为友好。
单一维护者风险(Bus Factor):steipete 贡献了 14,756 个提交,占总提交数(20,000+)的约 73%。第二贡献者(vincentkoc,1,690 个提交)的差距巨大。这意味着项目高度依赖单一个人,其 巴士因子(Bus Factor) 接近 1——如果核心维护者因任何原因无法继续,项目存续性将受到严重威胁。
激进的重构节奏:几乎每个版本都包含破坏性变更(Breaking Changes)。插件 API 的频繁变动导致社区 Skills 的维护成本很高——一个 Skill 可能在几周内因上游 API 变化而失效。这种"快速迭代"与"稳定平台"之间的张力是 OpenClaw 当前最大的架构风险。
TypeScript 原生编译器:OpenClaw 正在跟踪 @typescript/native-preview 7.0.0-dev(基于 Go 语言实现的 TypeScript 原生编译器)。该编译器承诺 10 倍以上的编译速度提升,这对 OpenClaw 的开发体验和 CI/CD 流水线效率将产生显著影响。仓库中已有实验性分支开始适配新编译器的特性。
插件 SDK 稳定化:当前插件系统存在多个历史遗留路径(Legacy Paths),包括已废弃但尚未删除的旧版导入方式。SDK 稳定化的核心目标是确定一个长期不变的 API 面(API Surface),将所有旧路径标记为 deprecated 并在后续版本中移除。
微信官方集成:与腾讯的合作将带来微信渠道的官方支持,而非目前依赖第三方库的间接集成。这对中国市场的渗透率至关重要——微信的月活跃用户数超过 13 亿,官方渠道意味着更稳定的 API 和更低的封号风险。
企业级采用路径:Ansible Playbook + Docker 容器 + 沙箱隔离的组合已为企业部署铺平道路。下一步是完善 RBAC(基于角色的访问控制)、审计日志导出(Audit Log Export)到 SIEM 系统、以及 SSO(单点登录)集成。
OpenClaw 代表的是一种明确的技术哲学:AI Agent 应该运行在用户控制的基础设施上,数据不应离开用户的信任边界。这一立场在当前"一切皆云"的行业趋势中显得逆流而行,但正是这种逆流赋予了它独特的价值。
从技术实现角度看,OpenClaw 在 TypeScript 单体仓库中实现了渠道抽象、插件隔离、三层沙箱、向量记忆和跨平台原生应用等复杂功能,代码质量和架构设计的成熟度远超其仅四个月的年龄。但其单一维护者集中度、激进重构节奏和日益庞大的 Issue 积压也构成了实质性风险。
对于开发者而言,OpenClaw 是目前最完整的开源本地优先 AI Agent 平台,没有之一。对于企业而言,其 Docker + Ansible + 沙箱的组合提供了可审计、可隔离、可复现的部署路径。对于 AI 行业而言,它证明了"本地优先"不是一个妥协方案,而是一个可以在功能完备性上与云端 SaaS 竞品正面对抗的架构范式。
| 资源 | 链接 |
| GitHub 主仓库 | github.com/openclaw/openclaw |
| 官方网站 | openclaw.ai |
| 英文文档 | docs.openclaw.ai |
| 中文文档 | docs.openclaw.ai/zh-CN |
| Discord 社区 | discord.gg/clawd |
| ClawHub 市场 | clawhub.com |
| ClawHub 源码 | github.com/openclaw/clawhub |
| Star 增长曲线 | star-history.com/#openclaw/openclaw |
| DeepWiki 分析 | deepwiki.com/openclaw/openclaw |
| 安全信任中心 | trust.openclaw.ai |
| 安全联络邮箱 | security@openclaw.ai |
| 仓库 | Stars | 说明 |
| openclaw/openclaw | 343,696 | 主仓库:CLI、Gateway、Agent 运行时、Plugin SDK |
| openclaw/clawhub | 7,214 | 官方 Skill 目录平台 |
| openclaw/skills | 3,622 | ClawHub 所有 Skill 版本归档 |
| openclaw/acpx | 1,834 | 无头 ACP CLI:有状态 Agent Client Protocol 会话 |
| openclaw/lobster | 992 | Lobster 工作流 Shell:类型化 JSON 管线 + 审批门 |
| openclaw/nix-openclaw | 611 | Nix 声明式打包支持 |
| openclaw/openclaw-ansible | 545 | Ansible 自动化部署(Tailscale + UFW + Docker) |
| openclaw/openclaw-windows-node | 405 | Windows 系统托盘 + PowerToys 命令面板扩展 |
| openclaw/openclaw.ai | 250 | 官方网站源码 |
| openclaw/trust | 35 | 安全信任策略与威胁模型 |
| openclaw/caclawphony | 34 | Symphony:项目任务 → 隔离自主执行 |
| 命令 | 用途 |
| openclaw onboard | 交互式引导安装(Gateway + 渠道 + Skills) |
| openclaw gateway run | 启动 Gateway 控制平面 |
| openclaw agent --message "..." | 向 Agent 发送消息 |
| openclaw channels status --probe | 检查所有渠道连接状态 |
| openclaw channels login | 渠道登录(如 WhatsApp QR 扫码) |
| openclaw pairing approve <channel> <code> | 审批 DM 配对请求 |
| openclaw doctor | 诊断配置问题与安全风险 |
| openclaw config set <key> <value> | 修改配置项 |
| openclaw update --channel <ch> | 切换发布频道并更新 |
| openclaw message send --to <target> | 向指定目标发送消息 |
| openclaw gateway status | 查看 Gateway 运行状态 |
| openclaw nodes list | 列出已连接的设备节点 |
| clawhub install <skill> | 从 ClawHub 安装 Skill |
以下命令可在 WhatsApp、Telegram、Slack、Discord、Teams、WebChat 等渠道的对话中直接发送:
| 命令 | 功能 |
| /status | 查看当前会话状态(模型 + token 用量 + 费用) |
| /new 或 /reset | 重置会话 |
| /compact | 压缩会话上下文(生成摘要) |
| /think <level> | 设置思考等级:off|minimal|low|medium|high|xhigh |
| /verbose on|off | 控制详细输出 |
| /usage off|tokens|full | 每条回复后显示用量统计 |
| /restart | 重启 Gateway(群组中仅 owner 可用) |
| /activation mention|always | 群组激活模式切换 |
| /elevated on|off | 切换提升权限的 bash 访问 |
| /approve | 审批挂起的工具执行或插件操作 |
| /acp spawn codex --bind here | 在当前对话中创建 ACP 工作区 |
本文所有技术细节均来源于以下一手数据,不依赖任何二手社区资料:
- GitHub API(api.github.com/repos/openclaw/openclaw):仓库元数据、Stars/Forks/Issues 统计、贡献者排名、Release 说明
- AGENTS.md(仓库根目录,35,263 字节):架构规范、模块边界、构建指南、测试策略、发布守则
- package.json(仓库根目录):233 个 exports 条目(含 230 个 plugin-sdk 子路径)、47 个运行时依赖、22 个开发依赖、198 个 npm scripts
- Dockerfile 与 docker-compose.yml:完整的容器化构建与部署配置
- README.md(GitHub API base64 解码):官方功能列表、渠道支持、安装指南、安全模型
- GitHub Releases API(v2026.3.31、v2026.3.28 Release Notes):破坏性变更与新功能详情
完成 openclaw onboard 后,系统会生成一个最小配置文件 ~/.openclaw/openclaw.json。手动配置时,最小可用的 JSON 如下:
|
1 2 3 4 5 |
{ "agent": { "model": "anthropic/claude-sonnet-4-6" } } |
仅需指定一个模型即可启动 Gateway。Agent 会使用该模型进行所有推理任务。更复杂的配置可以声明多模型故障转移、渠道接入、安全策略、沙箱模式和 Skills:
|
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 |
{ "agent": { "model": "openai/gpt-5.2", "fallbackModels": ["anthropic/claude-sonnet-4-6", "google/gemini-2.5-flash"], "thinkingLevel": "medium" }, "agents": { "defaults": { "workspace": "~/.openclaw/workspace", "sandbox": { "mode": "non-main" } } }, "channels": { "telegram": { "botToken": "123456:ABCDEF", "dmPolicy": "pairing", "allowFrom": [] }, "discord": { "token": "your-discord-bot-token", "dmPolicy": "pairing" }, "whatsapp": { "allowFrom": ["+1234567890"] } }, "browser": { "enabled": true }, "gateway": { "mode": "local", "auth": { "mode": "token" } } } |
完整配置参考详见 docs.openclaw.ai/gateway/configuration。配置文件支持 JSON5 格式(允许注释和尾逗号),这是一个面向人类可读性的设计选择。
对于中国用户群体,微信接入是一个高优先级需求。OpenClaw 的微信支持通过腾讯官方发布的 npm 包 @tencent-weixin/openclaw-weixin 实现,基于 iLink Bot API。这是一个具有里程碑意义的集成——标志着腾讯以官方身份参与开源 AI Agent 生态。
安装与激活流程:
|
1 2 3 4 5 |
# 安装微信插件 openclaw plugins install "@tencent-weixin/openclaw-weixin" # 扫码登录 openclaw channels login --channel openclaw-weixin |
微信集成当前仅支持私聊(Private Chat),不支持群聊。v2.x 版本要求 OpenClaw >=2026.3.22。用户需要在微信客户端(我 → 设置 → 插件)中启用"微信 ClawBot 插件"——该功能由腾讯逐步灰度发布。
这种通过官方 npm 包而非逆向工程实现的微信接入路径,避免了 chatgpt-on-wechat 等项目面临的账号封禁风险,具有更高的稳定性和合规性。但目前的功能受限(仅私聊)也反映了腾讯在开放微信生态时的审慎态度。
Leave a Reply