[TOC]
项目地址: OpenClaw
项目概述
OpenClaw 是一个个人 AI 助手平台,用户可以在自己的设备上运行,支持多种通讯渠道的统一接入。该项目采用 TypeScript 开发,具有高度的模块化和可扩展性。
核心特性
- 多渠道支持: WhatsApp、Telegram、Slack、Discord、Google Chat、Signal、iMessage、Microsoft Teams、LINE、Matrix 等
- AI 集成: 支持 OpenAI、Anthropic、Google、MiniMax、Moonshot 等多个 AI 提供商
- 跨平台: 提供 iOS、Android、macOS 原生应用
- 插件化: 通过扩展系统支持自定义渠道和功能
- 本地优先: 数据存储在用户设备,保护隐私
整体目录结构
openclaw/
├── src/ # 核心源代码
│ ├── cli/ # CLI 命令行界面
│ ├── channels/ # 通用渠道功能
│ ├── gateway/ # 网关和 API 服务器
│ ├── commands/ # 命令实现
│ ├── config/ # 配置管理
│ ├── infra/ # 基础设施
│ ├── media/ # 媒体处理
│ ├── plugin-sdk/ # 插件开发 SDK
│ ├── routing/ # 消息路由
│ ├── auto-reply/ # 自动回复
│ └── [channel-id]/ # 各渠道具体实现
│ ├── telegram/
│ ├── discord/
│ ├── slack/
│ ├── signal/
│ ├── imessage/
│ ├── whatsapp/
│ ├── line/
│ └── web/
├── extensions/ # 扩展插件
│ ├── matrix/
│ ├── msteams/
│ ├── zalo/
│ ├── bluebubbles/
│ └── voice-call/
├── apps/ # 移动和桌面应用
│ ├── ios/
│ ├── android/
│ ├── macos/
│ └── shared/
├── skills/ # 技能模块
├── docs/ # 文档
├── scripts/ # 构建脚本
├── test/ # 测试文件
├── ui/ # UI 组件
└── packages/ # 工作空间包
核心架构设计
分层架构
┌─────────────────────────────────────────────────────────────┐
│ 客户端层 (Client Layer) │
│ iOS / Android / macOS / Web UI / CLI │
└─────────────────────────────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ 网关层 (Gateway Layer) │
│ WebSocket Server / HTTP API / 认证 / 会话管理 │
└─────────────────────────────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ 路由层 (Routing Layer) │
│ 消息路由 / 代理解析 / 会话绑定 │
└─────────────────────────────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ 渠道层 (Channel Layer) │
│ Telegram / WhatsApp / Discord / Slack / Signal / ... │
└─────────────────────────────────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ 提供商层 (Provider Layer) │
│ OpenAI / Anthropic / Google / 本地模型 │
└─────────────────────────────────────────────────────────────┘
核心模块职责
CLI 模块 (src/cli/)
- 职责: 命令行界面入口和命令分发
- 核心文件:
program/build-program.ts: CLI 程序构建command-registry.ts: 命令注册中心deps.ts: 依赖注入工厂
网关模块 (src/gateway/)
- 职责: 核心 API 服务器和消息中枢
- 核心功能:
server-browser.ts: WebSocket 服务器server-http.ts: HTTP API 服务器auth.ts: 认证授权server-chat.ts: 聊天状态管理
路由模块 (src/routing/)
- 职责: 消息路由和代理选择
- 核心文件:
resolve-route.ts: 路由解析引擎session-key.ts: 会话密钥生成
配置模块 (src/config/)
- 职责: 配置文件加载和管理
- 特性:
- 支持 JSON5 格式
- 环境变量替换
- 配置文件包含 (
$include) - 原子写入和备份
消息流与路由机制
消息流程图
┌──────────┐ 消息接收 ┌──────────┐ 路由解析 ┌──────────┐
│ 渠道监听器 │ ────────▶ │ 路由器 │ ────────▶ │ 代理解析 │
│ (Channel) │ │ (Router) │ │ (Resolver)│
└──────────┘ └──────────┘ └──────────┘
▼
┌──────────┐ 回复发送 ┌──────────┐ AI 处理 ┌──────────┐
│ 渠道发送器 │ ◀─────── │ 会话管理 │ ◀─────── │ AI Provider│
│ (Sender) │ │ (Session) │ │ (Provider)│
└──────────┘ └──────────┘ └──────────┘
路由解析优先级
路由解析器按照以下优先级匹配代理绑定:
binding.peer- 特定用户/群组绑定binding.peer.parent- 父级群组继承(用于线程)binding.guild- Discord 服务器绑定binding.team- 团队绑定binding.account- 账户绑定binding.channel- 渠道绑定default- 默认代理
会话密钥结构
sessionKey = buildAgentSessionKey({
agentId, // 代理 ID
channel, // 渠道 ID
accountId, // 账户 ID
peerKind, // 对等方类型 (user/group)
peerId, // 对等方 ID
dmScope, // DM 范围 (main/per-peer/per-channel)
identityLinks, // 身份链接
})
插件系统架构
插件类型
OpenClaw 支持两种插件类型:
- 渠道插件: 扩展新的通讯渠道
- 技能插件: 扩展 AI 助手能力
插件结构
extensions/<plugin-name>/
├── package.json # NPM 包配置
├── openclaw.plugin.json # OpenClaw 插件元数据
├── index.ts # 插件入口
├── src/ # 源代码
│ ├── channel.ts # 渠道适配器
│ ├── auth.ts # 认证实现
│ └── config.ts # 配置 schema
└── README.md # 文档
插件加载流程
- 发现: 扫描
extensions/目录 - 验证: 检查
openclaw.plugin.json - 加载: 动态导入插件模块
- 初始化: 调用插件初始化函数
- 注册: 注册到渠道注册表
核心技术栈
运行时环境
| 组件 | 版本要求 | 说明 |
|---|---|---|
| Node.js | ≥22 | 主要运行时 |
| Bun | 最新 | 可选的 TypeScript 执行 |
| TypeScript | 5.x | 开发语言 |
核心依赖
渠道集成
@whiskeysockets/baileys- WhatsApp Webgrammy- Telegram Bot API@slack/bolt- Slackdiscord.js- Discord@signalapp/libsignal- Signal
Web 框架
hono- HTTP 服务器@hono/node-server- Node.js 适配器
AI/ML
@anthropic-ai/sdk- Anthropic APIopenai- OpenAI API@google-cloud/vertexai- Google Vertex AI
工具库
zod- 数据验证jiti- 动态 TypeScript 执行json5- JSON 配置解析
开发工具
- 构建:
tsdown(TypeScript 编译器) - 检查:
oxlint(快速 linter) - 格式:
oxfmt(代码格式化) - 测试:
vitest(测试框架) - 包管理:
pnpm(包管理器)
设计模式应用
依赖注入模式
目的: 解耦组件依赖,提高可测试性
// 依赖工厂 (src/cli/deps.ts)
export function createDefaultDeps(): CliDeps {
return {
sendMessageWhatsApp,
sendMessageTelegram,
sendMessageDiscord,
// ...
};
}
// 使用注入的依赖
export async function handleMessage(
message: Message,
deps: CliDeps = createDefaultDeps()
) {
await deps.sendMessageTelegram(message);
}
策略模式
目的: 统一接口,多种实现
渠道发送策略:
// 每个渠道独立实现
interface MessageSender {
send(message: Message, options: SendOptions): Promise<void>;
}
class TelegramSender implements MessageSender { /* ... */ }
class WhatsAppSender implements MessageSender { /* ... */ }
Provider 策略:
interface Provider {
baseUrl: string;
api: "openai-completions" | "anthropic-messages";
models: ModelDefinition[];
}
class OpenAIProvider implements Provider { /* ... */ }
class AnthropicProvider implements Provider { /* ... */ }
工厂模式
目的: 封装对象创建逻辑
// Provider 工厂
export function buildMinimaxProvider(): ProviderConfig {
return {
baseUrl: MINIMAX_API_BASE_URL,
api: "openai-completions",
models: [/* 模型列表 */],
};
}
// 会话工厂
export function createChatRunState(): ChatRunState {
return {
registry: createChatRunRegistry(),
buffers: new Map(),
deltaSentAt: new Map(),
abortedRuns: new Map(),
};
}
观察者模式
目的: 事件驱动,松耦合通信
// 事件系统 (src/infra/agent-events.ts)
type AgentListener = (event: AgentEventPayload) => void;
const listeners: AgentListener[] = [];
export function onAgentEvent(listener: AgentListener) {
listeners.push(listener);
}
export function emitAgentEvent(event: AgentEventPayload) {
for (const listener of listeners) {
listener(event);
}
}
适配器模式
目的: 统一不同渠道的接口
// 渠道适配器
export type ChannelMessagingAdapter = {
sendText: (params: SendTextParams) => Promise<void>;
sendMedia: (params: SendMediaParams) => Promise<void>;
editMessage: (params: EditParams) => Promise<void>;
deleteMessage: (params: DeleteParams) => Promise<void>;
};
// 每个渠道实现适配器
const telegramAdapter: ChannelMessagingAdapter = {
sendText: async (params) => { /* Telegram 实现 */ },
sendMedia: async (params) => { /* Telegram 实现 */ },
// ...
};
错误处理与容错
错误分类
// 错误代码提取
export function extractErrorCode(err: unknown): string | undefined {
if (!err || typeof err !== "object") return undefined;
const code = (err as { code?: unknown }).code;
if (typeof code === "string") return code;
if (typeof code === "number") return String(code);
return undefined;
}
重试机制
指数退避重试:
export type RetryConfig = {
attempts?: number; // 默认 3 次
minDelayMs?: number; // 最小延迟 300ms
maxDelayMs?: number; // 最大延迟 30s
jitter?: number; // 随机抖动 0-1
shouldRetry?: (err: unknown) => boolean;
};
// 延迟计算: delay = minDelayMs * 2 ** (attempt - 1) + jitter
渠道特定错误处理
| 渠道 | 错误处理策略 |
|---|---|
| Discord | 权限错误自动降级,静默失败 |
| Signal | 网络错误自动重连 |
| 连接断开自动重连 | |
| iMessage | 设备未激活状态检测 |
并发与异步处理
消息去重
// src/infra/dedupe.ts
const messageDedupe = new Map<string, MessageEntry>();
export function shouldProcessMessage(
messageId: string,
accountId: string
): boolean {
const key = `${messageId}:${accountId}`;
if (messageDedupe.has(key)) return false;
messageDedupe.set(key, { timestamp: Date.now() });
return true;
}
节流机制
// src/auto-reply/inbound-debounce.ts
export function createInboundDebouncer(
channel: ChannelId,
accountId: string
) {
return new Debouncer({
delayMs: resolveInboundDebounceMs(channel),
maxPending: 10,
});
}
活动跟踪
// src/infra/channel-activity.ts
const activity = new Map<string, ActivityEntry>();
export function recordChannelActivity(params: {
channel: ChannelId;
accountId?: string;
direction: "inbound" | "outbound";
at?: number;
}) {
const entry = ensureEntry(params.channel, params.accountId);
entry[`${params.direction}At`] = params.at || Date.now();
}
构建与部署
构建流程
# 安装依赖
pnpm install
# 类型检查
pnpm tsgo
# 代码检查
pnpm check
# 构建
pnpm build
# 测试
pnpm test
macOS 应用打包
# 打包 macOS 应用
scripts/package-mac-app.sh
# 签名和公证
codesign --sign ... OpenClaw.app
xcrun notarytool submit OpenClaw.app.dmg ...
架构优势总结
技术优势
| 特性 | 说明 |
|---|---|
| 高度模块化 | 清晰的模块边界,易于维护和扩展 |
| 插件化设计 | 支持动态扩展渠道和功能 |
| 类型安全 | 全面的 TypeScript 类型定义 |
| 事件驱动 | 松耦合的组件通信 |
| 配置驱动 | 通过配置文件控制行为,无需修改代码 |
运维优势
| 特性 | 说明 |
|---|---|
| 本地优先 | 数据存储在用户设备,保护隐私 |
| 跨平台支持 | iOS、Android、macOS 原生应用 |
| 完整测试 | 单元、集成、E2E 测试全覆盖 |
| 生产就绪 | 包含错误处理、重试、降级机制 |
开发体验
| 特性 | 说明 |
|---|---|
| 快速开发 | Bun 支持,毫秒级启动 |
| 代码质量 | Oxlint + Oxfmt 自动检查和格式化 |
| 清晰文档 | 详细的代码注释和文档 |
| 开发工具 | 完善的 CLI 工具链 |
相关链接
- OpenClaw GitHub: https://github.com/openclaw/openclaw
- 项目文档: https://openclaw.dev