这是 OpenClaw 源码解析系列的开篇。在深入具体模块之前,我们先从宏观视角俯瞰整个项目的架构——五层结构、数据流、关键设计决策,帮你建立起一张清晰的全局地图。

项目规模一览

模块 文件数 代码行数 定位
extensions/ 5,006 820K 插件生态(模型/渠道/工具)
src/agents 1,395 327K Agent 执行引擎
src/gateway 570 161K 网关服务器
src/auto-reply 475 111K 自动回复调度
src/plugins 424 103K 插件 SDK + 运行时
src/config 311 101K 配置系统
ui/ 285 82K WebUI 前端
src/cli 374 68K 命令行界面
src/channels 280 35K 渠道抽象层
src/cron 157 30K 定时任务
src/process 33 5K 进程管理 + CommandQueue

总计约 180 万行 TypeScript——OpenClaw 的体量相当庞大。


宏观架构:五层结构

OpenClaw 采用经典的分层架构,从入口启动到插件生态共五层:

┌─────────────────────────────────────────────────────────────────────────┐
│ 第 1 层:入口与启动 │
│ │
│ openclaw.mjs → src/entry.ts → src/cli/run-main.ts │
│ ↓ 解析命令行参数,路由到子命令 │
│ ↓ OpenClaw (无参数) 或 OpenClaw gateway → 启动 Gateway │
│ ↓ OpenClaw chat → 启动 CLI 聊天 │
│ ↓ OpenClaw onboard → 启动安装向导 │
└────────────────────────────────┬────────────────────────────────────────┘

┌────────────────────────────────▼────────────────────────────────────────┐
│ 第 2 层:Gateway 服务层(单进程,单线程) │
│ │
│ src/gateway/server.impl.ts — 主服务器 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ HTTP Server WebSocket Server │ │
│ │ ├── /control-ui (WebUI) ├── 客户端连接认证 │ │
│ │ ├── /v1/chat/completions ├── 事件广播 (broadcast) │ │
│ │ ├── /v1/embeddings ├── 方法调用 (RPC) │ │
│ │ ├── /v1/models └── Presence + Health │ │
│ │ ├── /hooks (webhook 入口) │ │
│ │ └── /health │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 辅助设施: │
│ • server-maintenance.ts — 定时清理与 GC │
│ • server-broadcast.ts — WebSocket 事件广播 │
│ • server-lanes.ts — CommandQueue 并发配置 │
│ • server-channels.ts — Channel 插件管理 │
│ • server-cron.ts — Cron 服务绑定 │
│ • server-plugins.ts — 插件 HTTP 路由注册 │
└────────────────────────────────┬────────────────────────────────────────┘

┌────────────────────────────────▼────────────────────────────────────────┐
│ 第 3 层:调度与编排 │
│ │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ CommandQueue │ │ Auto-Reply │ │ Cron Service │ │
│ │ (src/process) │ │ (src/auto-reply)│ │ (src/cron) │ │
│ │ │ │ │ │ │ │
│ │ Lane: main(4) │ │ 消息路由 │ │ 定时触发 │ │
│ │ Lane: cron(1) │ │ 渠道 → Agent │ │ cron 表达式 │ │
│ │ Lane: subagent(8)│ │ 重试/去重 │ │ 隔离执行 │ │
│ │ Lane: session:X │ │ 队列清理 │ │ │ │
│ └──────────────────┘ └──────────────────┘ └──────────────────┘ │
│ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Hooks │ │ Routing │ │
│ │ (src/hooks) │ │ (src/routing) │ │
│ │ │ │ │ │
│ │ Webhook 接入 │ │ 消息→会话映射 │ │
│ │ 生命周期钩子 │ │ 账户查找 │ │
│ └──────────────────┘ └──────────────────┘ │
└────────────────────────────────┬────────────────────────────────────────┘

┌────────────────────────────────▼────────────────────────────────────────┐
│ 第 4 层:Agent 执行引擎(327K 行,最复杂的模块) │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ pi-embedded-runner/ — 核心 Agent 执行器 │ │
│ │ run.ts → Agent 会话执行入口 │ │
│ │ lanes.ts → session/global lane 解析 │ │
│ │ compact.ts → 会话上下文压缩 │ │
│ │ stream-resolution.ts → 流式响应处理 │ │
│ │ system-prompt.ts → 系统提示词构建 │ │
│ │ │ │
│ │ tools/ → 工具执行框架 │ │
│ │ harness/ → Agent 执行约束与沙箱 │ │
│ │ sandbox/ → 代码执行沙箱 │ │
│ │ skills/ → 技能加载与调度 │ │
│ │ schema/ → Agent 配置结构 │ │
│ │ command/ → Agent 命令处理 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ src/context-engine/ — 上下文管理(token 预算、截断) │
│ src/memory/ + extensions/memory-* — 长期记忆 │
│ src/trajectory/ — 执行轨迹记录 │
└────────────────────────────────┬────────────────────────────────────────┘

┌────────────────────────────────▼────────────────────────────────────────┐
│ 第 5 层:插件与集成生态 (extensions/ — 820K 行) │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 模型提供商 (LLM Providers) │ │
│ │ openai / anthropic / google / deepseek / ollama / groq / │ │
│ │ mistral / xai / fireworks / qwen / litellm / vllm ... │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 消息渠道 (Channels) │ │
│ │ telegram / whatsapp / discord / slack / signal / matrix / │ │
│ │ irc / msteams / feishu / line / qqbot / imessage ... │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 媒体生成 (Media) │ │
│ │ elevenlabs(TTS) / deepgram(STT) / fal(图像) / comfy / │ │
│ │ runway(视频) / minimax ... │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 搜索 / 工具 │ │
│ │ brave / exa / tavily / browser / codex / github-copilot ... │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 记忆系统 (Memory) │ │
│ │ memory-core / memory-lancedb / memory-wiki / active-memory │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘

数据流:一条消息的完整旅程

以用户在 Telegram 发送一条消息为例,追踪一次完整的请求生命周期:

用户在 Telegram 发消息 "帮我总结这篇文章"


┌─ extensions/telegram/ ─────────────────────────────────┐
│ Telegram Bot API 收到 update │
│ → 解析消息,调用 Gateway 的 channel delivery 接口 │
└────────────────────────────────────┬───────────────────┘


┌─ src/channels/ ──────────────────────────────────────────┐
│ transport 层标准化消息格式 │
│ → routing: 根据 account-id 定位对应 session │
└────────────────────────────────────┬─────────────────────┘


┌─ src/auto-reply/ ────────────────────────────────────────┐
│ 判断是否需要 AI 回复,准备 Agent 执行参数 │
│ → enqueueCommandInLane("session:xxx", agentTask) │
└────────────────────────────────────┬─────────────────────┘


┌─ src/process/command-queue.ts ───────────────────────────┐
│ 检查 lane 空位 (session max=1, global max=4) │
│ → 有空位直接 pump(),满了排队等待 │
└────────────────────────────────────┬─────────────────────┘


┌─ src/agents/pi-embedded-runner/run.ts ───────────────────┐
│ 构建系统提示词 → 加载技能/工具/会话历史/记忆 │
│ → 调用 LLM API(流式接收响应) │
│ → LLM 要求调用工具时:执行工具 → 结果回传 → 继续推理 │
│ → 最终回复写入 session transcript 文件 │
└────────────────────────────────────┬─────────────────────┘


┌─ 回复路由 ──────────────────────────────────────────────┐
│ auto-reply 将回复文本送回 channel │
│ → 广播 "chat.done" 事件通知 WebUI │
└──────────────────────────────────────────────────────────┘

关键设计决策

了解 OpenClaw 为什么长成现在这样,比知道它长什么样更有价值:

决策 选择 原因 代价
进程模型 单进程 简单、状态共享便利 存在阻塞风险
插件策略 全在 extensions/ 核心精简、按需加载 820K 行仍挂同一进程
会话存储 JSONL 文件 零数据库依赖、可 cat 查看 大文件 readFileSync 阻塞
任务调度 CommandQueue lane 同会话串行、跨会话并行 非真并行,仅调度排序
实时通信 WebSocket 广播 推送 agent streaming stringify 成本随连接线性增长
配置管理 YAML + 热重载 改配置不需重启 增加 generation tracking 复杂度

各模块一句话定位

模块 定位
src/gateway HTTP+WS 服务器,所有外部请求的入口
src/agents AI Agent 执行引擎,LLM 调用与工具编排
src/auto-reply 消息到 Agent 的调度器
src/channels 渠道抽象层,统一多平台消息格式
src/config YAML 配置 + 热重载 + sessions 管理
src/plugins 插件 SDK 与运行时
src/process CommandQueue,唯一任务调度队列
src/cron 类 crontab 的周期性 Agent 触发
src/hooks Webhook 钩子与生命周期管理
src/mcp MCP 协议支持
src/memory 长期记忆入口
src/tts 语音合成
src/canvas-host Canvas 实时可视化(A2UI)
src/cli 命令行界面
src/routing account-id → session 映射
extensions/ 所有插件实现
ui/ Vite + React WebUI
apps/ iOS/Android/macOS 原生客户端
packages/ 独立 npm 包(plugin-sdk 等)

下一步

五层架构为你提供了一张全局地图。但地图只是起点——接下来我们将逐层深入:

  • 第二集:Agent 执行引擎 — 327K 行的核心,LLM 怎么调、工具怎么执行、上下文怎么压
  • 第三集:消息调度 — 从飞书/Telegram 消息到 Agent 回复的完整链路
  • 第四集:插件系统 — 插件 SDK 设计、加载机制、扩展点

本系列将持续更新,欢迎关注。