结构决定功能,历史揭示设计。本文从用户视角出发,向底层追问"它是怎么做到的"。
OpenClaw 是什么?
你在任何聊天窗口给它发一条消息,它就能帮你操作电脑——执行命令、读写文件、浏览网页、操控桌面应用、管理定时任务,甚至语音对话。
和常见的 AI 聊天机器人不同,OpenClaw 运行在你自己的电脑上,不依赖云端服务器。它支持 WhatsApp、Telegram、Discord、Slack、Signal、iMessage 等海外主流平台,也通过插件支持飞书、企业微信、qq等国内渠道。除了消息平台,还有 macOS / iOS / Android 原生应用,以及终端命令行和 Web 控制台。
简单说:20+ 种入口,一个本地 AI 大脑,一套工具集。
#mermaid-svg-vCQh3TXO56gZXrDp{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-vCQh3TXO56gZXrDp .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-vCQh3TXO56gZXrDp .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-vCQh3TXO56gZXrDp .error-icon{fill:#552222;}#mermaid-svg-vCQh3TXO56gZXrDp .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vCQh3TXO56gZXrDp .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-vCQh3TXO56gZXrDp .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vCQh3TXO56gZXrDp .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vCQh3TXO56gZXrDp .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-vCQh3TXO56gZXrDp .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vCQh3TXO56gZXrDp .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vCQh3TXO56gZXrDp .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vCQh3TXO56gZXrDp .marker.cross{stroke:#333333;}#mermaid-svg-vCQh3TXO56gZXrDp svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vCQh3TXO56gZXrDp p{margin:0;}#mermaid-svg-vCQh3TXO56gZXrDp .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-vCQh3TXO56gZXrDp .cluster-label text{fill:#333;}#mermaid-svg-vCQh3TXO56gZXrDp .cluster-label span{color:#333;}#mermaid-svg-vCQh3TXO56gZXrDp .cluster-label span p{background-color:transparent;}#mermaid-svg-vCQh3TXO56gZXrDp .label text,#mermaid-svg-vCQh3TXO56gZXrDp span{fill:#333;color:#333;}#mermaid-svg-vCQh3TXO56gZXrDp .node rect,#mermaid-svg-vCQh3TXO56gZXrDp .node circle,#mermaid-svg-vCQh3TXO56gZXrDp .node ellipse,#mermaid-svg-vCQh3TXO56gZXrDp .node polygon,#mermaid-svg-vCQh3TXO56gZXrDp .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-vCQh3TXO56gZXrDp .rough-node .label text,#mermaid-svg-vCQh3TXO56gZXrDp .node .label text,#mermaid-svg-vCQh3TXO56gZXrDp .image-shape .label,#mermaid-svg-vCQh3TXO56gZXrDp .icon-shape .label{text-anchor:middle;}#mermaid-svg-vCQh3TXO56gZXrDp .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-vCQh3TXO56gZXrDp .rough-node .label,#mermaid-svg-vCQh3TXO56gZXrDp .node .label,#mermaid-svg-vCQh3TXO56gZXrDp .image-shape .label,#mermaid-svg-vCQh3TXO56gZXrDp .icon-shape .label{text-align:center;}#mermaid-svg-vCQh3TXO56gZXrDp .node.clickable{cursor:pointer;}#mermaid-svg-vCQh3TXO56gZXrDp .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-vCQh3TXO56gZXrDp .arrowheadPath{fill:#333333;}#mermaid-svg-vCQh3TXO56gZXrDp .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-vCQh3TXO56gZXrDp .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-vCQh3TXO56gZXrDp .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vCQh3TXO56gZXrDp .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-vCQh3TXO56gZXrDp .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vCQh3TXO56gZXrDp .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-vCQh3TXO56gZXrDp .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-vCQh3TXO56gZXrDp .cluster text{fill:#333;}#mermaid-svg-vCQh3TXO56gZXrDp .cluster span{color:#333;}#mermaid-svg-vCQh3TXO56gZXrDp div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-vCQh3TXO56gZXrDp .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-vCQh3TXO56gZXrDp rect.text{fill:none;stroke-width:0;}#mermaid-svg-vCQh3TXO56gZXrDp .icon-shape,#mermaid-svg-vCQh3TXO56gZXrDp .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vCQh3TXO56gZXrDp .icon-shape p,#mermaid-svg-vCQh3TXO56gZXrDp .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-vCQh3TXO56gZXrDp .icon-shape rect,#mermaid-svg-vCQh3TXO56gZXrDp .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vCQh3TXO56gZXrDp .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-vCQh3TXO56gZXrDp .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-vCQh3TXO56gZXrDp :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
工具集
用户入口
Agent 运行时
Pi SDK agent loop
Provider 路由
Model Failover
Context Engine
Gateway 网关
消息路由
消息队列
会话管理
Cron 调度
Hook 系统
Plugin 注册
消息渠道WhatsApp · Telegram · DiscordSlack · Signal · iMessage飞书 · LINE · Matrix …
原生应用macOS · iOS · Android
终端与 WebTUI 命令行 · Control UI
系统操作exec · read · write · cron
网络与感知browser · web_search · memory
多媒体与 GUIpeekaboo · canvas · tts
演化史
OpenClaw 历经 Warelay → Clawdis → Clawdbot → OpenClaw 四次更名,我们看看每次更名时的架构变化。
Warelay:“一条管道”
项目名 warelay = WA Relay(WhatsApp 中继)。用户通过 WhatsApp 或短信给 AI 发消息,收到文字回复。没有 Gateway、没有 Agent、没有会话管理——就是一个 webhook 脚本。
#mermaid-svg-fFWSCuDSVoy1iYfl{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-fFWSCuDSVoy1iYfl .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-fFWSCuDSVoy1iYfl .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-fFWSCuDSVoy1iYfl .error-icon{fill:#552222;}#mermaid-svg-fFWSCuDSVoy1iYfl .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fFWSCuDSVoy1iYfl .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-fFWSCuDSVoy1iYfl .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fFWSCuDSVoy1iYfl .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fFWSCuDSVoy1iYfl .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-fFWSCuDSVoy1iYfl .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fFWSCuDSVoy1iYfl .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fFWSCuDSVoy1iYfl .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fFWSCuDSVoy1iYfl .marker.cross{stroke:#333333;}#mermaid-svg-fFWSCuDSVoy1iYfl svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fFWSCuDSVoy1iYfl p{margin:0;}#mermaid-svg-fFWSCuDSVoy1iYfl .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-fFWSCuDSVoy1iYfl .cluster-label text{fill:#333;}#mermaid-svg-fFWSCuDSVoy1iYfl .cluster-label span{color:#333;}#mermaid-svg-fFWSCuDSVoy1iYfl .cluster-label span p{background-color:transparent;}#mermaid-svg-fFWSCuDSVoy1iYfl .label text,#mermaid-svg-fFWSCuDSVoy1iYfl span{fill:#333;color:#333;}#mermaid-svg-fFWSCuDSVoy1iYfl .node rect,#mermaid-svg-fFWSCuDSVoy1iYfl .node circle,#mermaid-svg-fFWSCuDSVoy1iYfl .node ellipse,#mermaid-svg-fFWSCuDSVoy1iYfl .node polygon,#mermaid-svg-fFWSCuDSVoy1iYfl .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-fFWSCuDSVoy1iYfl .rough-node .label text,#mermaid-svg-fFWSCuDSVoy1iYfl .node .label text,#mermaid-svg-fFWSCuDSVoy1iYfl .image-shape .label,#mermaid-svg-fFWSCuDSVoy1iYfl .icon-shape .label{text-anchor:middle;}#mermaid-svg-fFWSCuDSVoy1iYfl .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-fFWSCuDSVoy1iYfl .rough-node .label,#mermaid-svg-fFWSCuDSVoy1iYfl .node .label,#mermaid-svg-fFWSCuDSVoy1iYfl .image-shape .label,#mermaid-svg-fFWSCuDSVoy1iYfl .icon-shape .label{text-align:center;}#mermaid-svg-fFWSCuDSVoy1iYfl .node.clickable{cursor:pointer;}#mermaid-svg-fFWSCuDSVoy1iYfl .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-fFWSCuDSVoy1iYfl .arrowheadPath{fill:#333333;}#mermaid-svg-fFWSCuDSVoy1iYfl .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-fFWSCuDSVoy1iYfl .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-fFWSCuDSVoy1iYfl .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fFWSCuDSVoy1iYfl .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-fFWSCuDSVoy1iYfl .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fFWSCuDSVoy1iYfl .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-fFWSCuDSVoy1iYfl .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-fFWSCuDSVoy1iYfl .cluster text{fill:#333;}#mermaid-svg-fFWSCuDSVoy1iYfl .cluster span{color:#333;}#mermaid-svg-fFWSCuDSVoy1iYfl div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-fFWSCuDSVoy1iYfl .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-fFWSCuDSVoy1iYfl rect.text{fill:none;stroke-width:0;}#mermaid-svg-fFWSCuDSVoy1iYfl .icon-shape,#mermaid-svg-fFWSCuDSVoy1iYfl .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fFWSCuDSVoy1iYfl .icon-shape p,#mermaid-svg-fFWSCuDSVoy1iYfl .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-fFWSCuDSVoy1iYfl .icon-shape rect,#mermaid-svg-fFWSCuDSVoy1iYfl .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fFWSCuDSVoy1iYfl .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-fFWSCuDSVoy1iYfl .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-fFWSCuDSVoy1iYfl :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
Twilio / Baileys接收消息
Express 路由
AI API生成回复
原路返回
关键选择:用 Baileys(开源 WhatsApp 协议库)而非商业 API 收发 WhatsApp。好处是免费且不依赖第三方服务,代价是 Baileys 要求每台机器只能维持一个 WhatsApp 会话。
Clawdis:最关键的跃迁
这是变化最剧烈的阶段——三件大事同时发生:
引入 Pi SDK:Pi 是一个外部 agent 框架,提供了"消息 → prompt → 调大模型 → 解析工具调用 → 执行 → 循环"的核心 agent 循环(架构详见后文 Pi Agent Runtime 一节)。OpenClaw 从此不再是"收到消息调一次 API",而是一个真正的 AI agent。
2 周内接入 5 个渠道:Telegram、Discord、Signal、iMessage、WhatsApp——每个平台的消息格式、API 风格、群组概念都不同。多渠道的差异催生了 Adapter 模式和 Channel Dock(统一注册中心),每个渠道只实现它需要的接口子集(详见后文通道适配器一节)。
Gateway 诞生:从一个 CLI 命令行工具变为常驻后台服务,所有客户端通过 WebSocket 统一接入,内含消息路由、队列、会话管理、Cron 调度、Hook 系统和 Plugin 注册。
Clawdbot → OpenClaw:生产化与平台化
核心思路是让新功能通过插件生长,核心代码库不再膨胀。为此落地了三层扩展机制:
插件系统:Plugin SDK + jiti
社区开发插件时,导出一个 register(api) 函数即可声明能力——可注册的类型包括:
- 渠道(registerChannel)—— 接入新的消息平台
- 工具(registerTool)—— 给 AI 新的操作能力
- 钩子(registerHook)—— 在消息流水线的特定节点插入逻辑
- HTTP 路由 / CLI 子命令 / 后台服务 —— 扩展 Gateway 和命令行
Node.js 生态的模块格式分裂(ESM vs CJS)是插件加载的主要障碍。OpenClaw 用 jiti(运行时 TypeScript 编译加载器)统一处理:插件不需要预编译,写完直接安装即可运行。目前 40+ 个扩展(飞书、LINE、Matrix、Twitch、语音通话……)都以插件形式存在。
本地记忆:sqlite-vec
让 AI 拥有跨会话的长期记忆。文本切片后转为向量,存入本地 SQLite,用 sqlite-vec 扩展做余弦相似度检索。搜索采用混合策略——向量语义匹配 + BM25 关键词匹配——兼顾"意思相近"和"关键词命中"。所有数据留在本地磁盘,也可通过 MCP 桥接对接外部知识库。
技能市场:ClawHub
插件解决了渠道和工具的扩展,但 AI 的行为模式怎么共享?ClawHub(clawhub.ai)是公开的技能注册中心。技能本质是注入 system prompt 的声明文件,描述 AI 在特定场景下该怎么做(比如"操控 macOS 桌面"、“生成代码后自动运行测试”)。
- 安装:clawhub install <slug>
- 加载优先级:workspace > 本地 > 内置
- 社区治理:点赞、评论、举报,有独立审核机制
项目的 VISION.md 明确要求:新技能应先发布到 ClawHub,不要默认加入核心仓库。
核心子系统拆解
Pi Agent Runtime:OpenClaw 的大脑
OpenClaw 的 agent 能力不是从零自研——它站在 Pi SDK 的肩膀上。Pi 是一个 7 包 monorepo,从底向上分三层:
#mermaid-svg-K7qt43pR7fPLY9Xa{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-K7qt43pR7fPLY9Xa .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-K7qt43pR7fPLY9Xa .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-K7qt43pR7fPLY9Xa .error-icon{fill:#552222;}#mermaid-svg-K7qt43pR7fPLY9Xa .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-K7qt43pR7fPLY9Xa .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-K7qt43pR7fPLY9Xa .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-K7qt43pR7fPLY9Xa .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-K7qt43pR7fPLY9Xa .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-K7qt43pR7fPLY9Xa .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-K7qt43pR7fPLY9Xa .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-K7qt43pR7fPLY9Xa .marker{fill:#333333;stroke:#333333;}#mermaid-svg-K7qt43pR7fPLY9Xa .marker.cross{stroke:#333333;}#mermaid-svg-K7qt43pR7fPLY9Xa svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-K7qt43pR7fPLY9Xa p{margin:0;}#mermaid-svg-K7qt43pR7fPLY9Xa .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-K7qt43pR7fPLY9Xa .cluster-label text{fill:#333;}#mermaid-svg-K7qt43pR7fPLY9Xa .cluster-label span{color:#333;}#mermaid-svg-K7qt43pR7fPLY9Xa .cluster-label span p{background-color:transparent;}#mermaid-svg-K7qt43pR7fPLY9Xa .label text,#mermaid-svg-K7qt43pR7fPLY9Xa span{fill:#333;color:#333;}#mermaid-svg-K7qt43pR7fPLY9Xa .node rect,#mermaid-svg-K7qt43pR7fPLY9Xa .node circle,#mermaid-svg-K7qt43pR7fPLY9Xa .node ellipse,#mermaid-svg-K7qt43pR7fPLY9Xa .node polygon,#mermaid-svg-K7qt43pR7fPLY9Xa .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-K7qt43pR7fPLY9Xa .rough-node .label text,#mermaid-svg-K7qt43pR7fPLY9Xa .node .label text,#mermaid-svg-K7qt43pR7fPLY9Xa .image-shape .label,#mermaid-svg-K7qt43pR7fPLY9Xa .icon-shape .label{text-anchor:middle;}#mermaid-svg-K7qt43pR7fPLY9Xa .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-K7qt43pR7fPLY9Xa .rough-node .label,#mermaid-svg-K7qt43pR7fPLY9Xa .node .label,#mermaid-svg-K7qt43pR7fPLY9Xa .image-shape .label,#mermaid-svg-K7qt43pR7fPLY9Xa .icon-shape .label{text-align:center;}#mermaid-svg-K7qt43pR7fPLY9Xa .node.clickable{cursor:pointer;}#mermaid-svg-K7qt43pR7fPLY9Xa .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-K7qt43pR7fPLY9Xa .arrowheadPath{fill:#333333;}#mermaid-svg-K7qt43pR7fPLY9Xa .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-K7qt43pR7fPLY9Xa .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-K7qt43pR7fPLY9Xa .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-K7qt43pR7fPLY9Xa .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-K7qt43pR7fPLY9Xa .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-K7qt43pR7fPLY9Xa .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-K7qt43pR7fPLY9Xa .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-K7qt43pR7fPLY9Xa .cluster text{fill:#333;}#mermaid-svg-K7qt43pR7fPLY9Xa .cluster span{color:#333;}#mermaid-svg-K7qt43pR7fPLY9Xa div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-K7qt43pR7fPLY9Xa .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-K7qt43pR7fPLY9Xa rect.text{fill:none;stroke-width:0;}#mermaid-svg-K7qt43pR7fPLY9Xa .icon-shape,#mermaid-svg-K7qt43pR7fPLY9Xa .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-K7qt43pR7fPLY9Xa .icon-shape p,#mermaid-svg-K7qt43pR7fPLY9Xa .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-K7qt43pR7fPLY9Xa .icon-shape rect,#mermaid-svg-K7qt43pR7fPLY9Xa .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-K7qt43pR7fPLY9Xa .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-K7qt43pR7fPLY9Xa .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-K7qt43pR7fPLY9Xa :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
pi-coding-agent · SDK 层
createAgentSession()工具 · 钩子 · 会话一站式初始化
SessionManagerJSONL 树形持久化分支 · 恢复 · 压缩
Context 管线transformContext 裁剪注入convertToLlm 格式转换
pi-agent-core · Agent 运行时
Agent Loopprompt → stream → parse→ execute → loop
Tool 系统TypeBox schema 校验流式进度回调
事件总线turn_start · message_updatetool_execution_end …
Steering + FollowUp运行中插入新指令排队后续任务
pi-ai · LLM 抽象层
Provider 注册Anthropic · OpenAI · GoogleMistral · Bedrock 等 16+
Model 注册表340KB 自动生成成本 · 窗口 · 能力
EventStream统一流式协议text / thinking / toolcall
pi-ai(LLM 抽象层) 把 16+ 家模型供应商统一成一个 stream(model, context) 调用。每个供应商实现一个 StreamFunction,把各家私有的流式响应转成标准事件序列(text_delta、thinking_delta、toolcall_start/end)。模型注册表是自动生成的,包含每个模型的成本、上下文窗口、支持的输入类型(文本/图片)和推理能力。
pi-agent-core(Agent 运行时) 提供核心循环:用户消息进入 → 流式调用 LLM → 解析工具调用 → 按序执行工具 → 结果返回 LLM → 继续循环直到 end_turn。工具用 TypeBox 定义参数 schema,运行时自动校验。。
pi-coding-agent(SDK 层) 提供 createAgentSession() 工厂方法,一次性组装工具集、上下文钩子和会话存储。SessionManager 用 JSONL 文件存储对话树(每条消息有 id + parentId),支持分支、恢复和压缩。上下文管线分两步:transformContext() 在 AgentMessage 层面裁剪/注入(比如删掉过旧的消息),convertToLlm() 再把自定义消息类型转成 LLM 能理解的标准格式。
OpenClaw 在 Pi 之上包了六部分,让它从一个通用 agent 框架变成多渠道 AI 助手:
#mermaid-svg-CZNgaCE8ethwJVKC{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-CZNgaCE8ethwJVKC .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-CZNgaCE8ethwJVKC .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-CZNgaCE8ethwJVKC .error-icon{fill:#552222;}#mermaid-svg-CZNgaCE8ethwJVKC .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-CZNgaCE8ethwJVKC .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-CZNgaCE8ethwJVKC .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-CZNgaCE8ethwJVKC .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-CZNgaCE8ethwJVKC .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-CZNgaCE8ethwJVKC .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-CZNgaCE8ethwJVKC .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-CZNgaCE8ethwJVKC .marker{fill:#333333;stroke:#333333;}#mermaid-svg-CZNgaCE8ethwJVKC .marker.cross{stroke:#333333;}#mermaid-svg-CZNgaCE8ethwJVKC svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-CZNgaCE8ethwJVKC p{margin:0;}#mermaid-svg-CZNgaCE8ethwJVKC .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-CZNgaCE8ethwJVKC .cluster-label text{fill:#333;}#mermaid-svg-CZNgaCE8ethwJVKC .cluster-label span{color:#333;}#mermaid-svg-CZNgaCE8ethwJVKC .cluster-label span p{background-color:transparent;}#mermaid-svg-CZNgaCE8ethwJVKC .label text,#mermaid-svg-CZNgaCE8ethwJVKC span{fill:#333;color:#333;}#mermaid-svg-CZNgaCE8ethwJVKC .node rect,#mermaid-svg-CZNgaCE8ethwJVKC .node circle,#mermaid-svg-CZNgaCE8ethwJVKC .node ellipse,#mermaid-svg-CZNgaCE8ethwJVKC .node polygon,#mermaid-svg-CZNgaCE8ethwJVKC .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-CZNgaCE8ethwJVKC .rough-node .label text,#mermaid-svg-CZNgaCE8ethwJVKC .node .label text,#mermaid-svg-CZNgaCE8ethwJVKC .image-shape .label,#mermaid-svg-CZNgaCE8ethwJVKC .icon-shape .label{text-anchor:middle;}#mermaid-svg-CZNgaCE8ethwJVKC .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-CZNgaCE8ethwJVKC .rough-node .label,#mermaid-svg-CZNgaCE8ethwJVKC .node .label,#mermaid-svg-CZNgaCE8ethwJVKC .image-shape .label,#mermaid-svg-CZNgaCE8ethwJVKC .icon-shape .label{text-align:center;}#mermaid-svg-CZNgaCE8ethwJVKC .node.clickable{cursor:pointer;}#mermaid-svg-CZNgaCE8ethwJVKC .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-CZNgaCE8ethwJVKC .arrowheadPath{fill:#333333;}#mermaid-svg-CZNgaCE8ethwJVKC .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-CZNgaCE8ethwJVKC .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-CZNgaCE8ethwJVKC .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CZNgaCE8ethwJVKC .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-CZNgaCE8ethwJVKC .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CZNgaCE8ethwJVKC .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-CZNgaCE8ethwJVKC .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-CZNgaCE8ethwJVKC .cluster text{fill:#333;}#mermaid-svg-CZNgaCE8ethwJVKC .cluster span{color:#333;}#mermaid-svg-CZNgaCE8ethwJVKC div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-CZNgaCE8ethwJVKC .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-CZNgaCE8ethwJVKC rect.text{fill:none;stroke-width:0;}#mermaid-svg-CZNgaCE8ethwJVKC .icon-shape,#mermaid-svg-CZNgaCE8ethwJVKC .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CZNgaCE8ethwJVKC .icon-shape p,#mermaid-svg-CZNgaCE8ethwJVKC .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-CZNgaCE8ethwJVKC .icon-shape rect,#mermaid-svg-CZNgaCE8ethwJVKC .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CZNgaCE8ethwJVKC .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-CZNgaCE8ethwJVKC .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-CZNgaCE8ethwJVKC :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
OpenClaw 包装 — 接入层
OpenClaw 包装 — 调度层
Pi SDK
agent 循环引擎
LLM 流式推理
SessionManager会话持久化
Provider 路由适配不同 LLM 供应商
工具注册exec / browser / memory …
Model Failover主模型挂了自动切备用
Context Engine长对话不丢上下文
Prompt 构建系统指令 + Skills
会话订阅流式回调给渠道
消息全链路:从收到到回复
一条消息从进入系统到收到回复,经过这样的流水线:
#mermaid-svg-QfLnSz0Afs0Luo32{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-QfLnSz0Afs0Luo32 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QfLnSz0Afs0Luo32 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QfLnSz0Afs0Luo32 .error-icon{fill:#552222;}#mermaid-svg-QfLnSz0Afs0Luo32 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QfLnSz0Afs0Luo32 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QfLnSz0Afs0Luo32 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QfLnSz0Afs0Luo32 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QfLnSz0Afs0Luo32 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QfLnSz0Afs0Luo32 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QfLnSz0Afs0Luo32 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QfLnSz0Afs0Luo32 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QfLnSz0Afs0Luo32 .marker.cross{stroke:#333333;}#mermaid-svg-QfLnSz0Afs0Luo32 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QfLnSz0Afs0Luo32 p{margin:0;}#mermaid-svg-QfLnSz0Afs0Luo32 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-QfLnSz0Afs0Luo32 .cluster-label text{fill:#333;}#mermaid-svg-QfLnSz0Afs0Luo32 .cluster-label span{color:#333;}#mermaid-svg-QfLnSz0Afs0Luo32 .cluster-label span p{background-color:transparent;}#mermaid-svg-QfLnSz0Afs0Luo32 .label text,#mermaid-svg-QfLnSz0Afs0Luo32 span{fill:#333;color:#333;}#mermaid-svg-QfLnSz0Afs0Luo32 .node rect,#mermaid-svg-QfLnSz0Afs0Luo32 .node circle,#mermaid-svg-QfLnSz0Afs0Luo32 .node ellipse,#mermaid-svg-QfLnSz0Afs0Luo32 .node polygon,#mermaid-svg-QfLnSz0Afs0Luo32 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QfLnSz0Afs0Luo32 .rough-node .label text,#mermaid-svg-QfLnSz0Afs0Luo32 .node .label text,#mermaid-svg-QfLnSz0Afs0Luo32 .image-shape .label,#mermaid-svg-QfLnSz0Afs0Luo32 .icon-shape .label{text-anchor:middle;}#mermaid-svg-QfLnSz0Afs0Luo32 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-QfLnSz0Afs0Luo32 .rough-node .label,#mermaid-svg-QfLnSz0Afs0Luo32 .node .label,#mermaid-svg-QfLnSz0Afs0Luo32 .image-shape .label,#mermaid-svg-QfLnSz0Afs0Luo32 .icon-shape .label{text-align:center;}#mermaid-svg-QfLnSz0Afs0Luo32 .node.clickable{cursor:pointer;}#mermaid-svg-QfLnSz0Afs0Luo32 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-QfLnSz0Afs0Luo32 .arrowheadPath{fill:#333333;}#mermaid-svg-QfLnSz0Afs0Luo32 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QfLnSz0Afs0Luo32 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QfLnSz0Afs0Luo32 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QfLnSz0Afs0Luo32 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-QfLnSz0Afs0Luo32 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QfLnSz0Afs0Luo32 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-QfLnSz0Afs0Luo32 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QfLnSz0Afs0Luo32 .cluster text{fill:#333;}#mermaid-svg-QfLnSz0Afs0Luo32 .cluster span{color:#333;}#mermaid-svg-QfLnSz0Afs0Luo32 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-QfLnSz0Afs0Luo32 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-QfLnSz0Afs0Luo32 rect.text{fill:none;stroke-width:0;}#mermaid-svg-QfLnSz0Afs0Luo32 .icon-shape,#mermaid-svg-QfLnSz0Afs0Luo32 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QfLnSz0Afs0Luo32 .icon-shape p,#mermaid-svg-QfLnSz0Afs0Luo32 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-QfLnSz0Afs0Luo32 .icon-shape rect,#mermaid-svg-QfLnSz0Afs0Luo32 .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QfLnSz0Afs0Luo32 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-QfLnSz0Afs0Luo32 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-QfLnSz0Afs0Luo32 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
8 回复调度
保证顺序
仿人打字间隔
7 Agent 执行
Pi SDK 循环
Steering 转向
6 入队策略
eager立即处理
batch短时间多条合并处理
debounce等用户停止输入再处理
5 媒体理解
语音转文字
图片生成描述
4 Hook + 路由
触发插件钩子如自动翻译、日志
路由解析确定交给哪个 Agent
1 收到原始消息
2 归一化不同渠道的消息统一成相同格式
3 去重
9 投递到渠道
两个值得注意的设计:
-
Steering(转向):agent 正在生成回复时,你又发了一条消息。普通系统会让你等上一条处理完。OpenClaw 通过 session.steer() 把新消息实时注入当前 agent 运行,AI 会立刻调整回复方向——就像你跟人说话时补了一句"等等,我改主意了"。
-
仿人延迟:回复不是一次性弹出,而是分块发送,块间插入随机间隔,模拟真人打字节奏。在微信、Telegram 这类即时通讯里,这让对话体验更自然。
通道适配器:如何统一 20+ 种渠道
WhatsApp 有"已读回执",Telegram 有"群组管理 API",Discord 有"权限体系",Signal 几乎什么管理接口都没有——每个平台的能力完全不同。
OpenClaw 的做法不是设计一个大而全的接口让每个通道都实现,而是拆成 10 种细粒度 Adapter,每个通道只实现它需要的子集:
#mermaid-svg-0K6p8WvYMrrUZuSy{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0K6p8WvYMrrUZuSy .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0K6p8WvYMrrUZuSy .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0K6p8WvYMrrUZuSy .error-icon{fill:#552222;}#mermaid-svg-0K6p8WvYMrrUZuSy .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0K6p8WvYMrrUZuSy .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0K6p8WvYMrrUZuSy .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0K6p8WvYMrrUZuSy .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0K6p8WvYMrrUZuSy .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0K6p8WvYMrrUZuSy .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0K6p8WvYMrrUZuSy .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0K6p8WvYMrrUZuSy .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0K6p8WvYMrrUZuSy .marker.cross{stroke:#333333;}#mermaid-svg-0K6p8WvYMrrUZuSy svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0K6p8WvYMrrUZuSy p{margin:0;}#mermaid-svg-0K6p8WvYMrrUZuSy .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-0K6p8WvYMrrUZuSy .cluster-label text{fill:#333;}#mermaid-svg-0K6p8WvYMrrUZuSy .cluster-label span{color:#333;}#mermaid-svg-0K6p8WvYMrrUZuSy .cluster-label span p{background-color:transparent;}#mermaid-svg-0K6p8WvYMrrUZuSy .label text,#mermaid-svg-0K6p8WvYMrrUZuSy span{fill:#333;color:#333;}#mermaid-svg-0K6p8WvYMrrUZuSy .node rect,#mermaid-svg-0K6p8WvYMrrUZuSy .node circle,#mermaid-svg-0K6p8WvYMrrUZuSy .node ellipse,#mermaid-svg-0K6p8WvYMrrUZuSy .node polygon,#mermaid-svg-0K6p8WvYMrrUZuSy .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0K6p8WvYMrrUZuSy .rough-node .label text,#mermaid-svg-0K6p8WvYMrrUZuSy .node .label text,#mermaid-svg-0K6p8WvYMrrUZuSy .image-shape .label,#mermaid-svg-0K6p8WvYMrrUZuSy .icon-shape .label{text-anchor:middle;}#mermaid-svg-0K6p8WvYMrrUZuSy .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0K6p8WvYMrrUZuSy .rough-node .label,#mermaid-svg-0K6p8WvYMrrUZuSy .node .label,#mermaid-svg-0K6p8WvYMrrUZuSy .image-shape .label,#mermaid-svg-0K6p8WvYMrrUZuSy .icon-shape .label{text-align:center;}#mermaid-svg-0K6p8WvYMrrUZuSy .node.clickable{cursor:pointer;}#mermaid-svg-0K6p8WvYMrrUZuSy .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0K6p8WvYMrrUZuSy .arrowheadPath{fill:#333333;}#mermaid-svg-0K6p8WvYMrrUZuSy .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0K6p8WvYMrrUZuSy .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0K6p8WvYMrrUZuSy .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0K6p8WvYMrrUZuSy .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0K6p8WvYMrrUZuSy .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0K6p8WvYMrrUZuSy .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0K6p8WvYMrrUZuSy .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0K6p8WvYMrrUZuSy .cluster text{fill:#333;}#mermaid-svg-0K6p8WvYMrrUZuSy .cluster span{color:#333;}#mermaid-svg-0K6p8WvYMrrUZuSy div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0K6p8WvYMrrUZuSy .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0K6p8WvYMrrUZuSy rect.text{fill:none;stroke-width:0;}#mermaid-svg-0K6p8WvYMrrUZuSy .icon-shape,#mermaid-svg-0K6p8WvYMrrUZuSy .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0K6p8WvYMrrUZuSy .icon-shape p,#mermaid-svg-0K6p8WvYMrrUZuSy .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0K6p8WvYMrrUZuSy .icon-shape rect,#mermaid-svg-0K6p8WvYMrrUZuSy .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0K6p8WvYMrrUZuSy .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0K6p8WvYMrrUZuSy .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0K6p8WvYMrrUZuSy :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
Adapter 接口(按需实现)
权限与管理
Security
Auth
Group
消息收发
Messaging
Outbound
Media
生命周期
Setup
Config
Status
Heartbeat
Channel Dock 注册中心渠道发现 · 生命周期管理
Telegram
Discord
…
- WhatsApp 实现了 HeartbeatAdapter(Baileys 连接不稳定,需要心跳保活)
- Discord 实现了 SecurityAdapter(有复杂的权限体系)
- Signal 不需要 GroupAdapter(没有群管理 API)
社区开发新渠道插件(比如飞书、LINE)时,用 Plugin SDK 实现同样的接口即可接入,不需要改动 OpenClaw 核心代码。
Peekaboo Bridge:让 AI 看见并操控 macOS 桌面
你在 WhatsApp 里说"帮我看看屏幕上是什么",AI 就能截屏、理解画面内容、告诉你答案。你说"点击登录按钮",它就能找到按钮并点击。你说"打开 Safari 访问某个网址",它能启动应用、导航页面、在输入框里打字。
这背后是 Peekaboo——一个 macOS 桌面自动化工具,让 AI 拥有"眼睛"和"手":
- 看:截屏、录屏、标注 UI 元素(给每个按钮/输入框分配 ID),配合 AI 视觉分析理解画面
- 操作:点击、打字、按键组合、滚动、拖拽,支持定位到具体 UI 元素
- 管理:启动/切换/关闭应用,管理窗口大小和位置,切换 macOS 空间,读写剪贴板
典型工作流是:截屏标注 → AI 识别元素 ID → 点击/输入 → 再截屏确认结果,全程在聊天窗口完成。
Peekaboo 内部分为五层:
#mermaid-svg-Q1yhvO1sXw8EEi66{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Q1yhvO1sXw8EEi66 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Q1yhvO1sXw8EEi66 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Q1yhvO1sXw8EEi66 .error-icon{fill:#552222;}#mermaid-svg-Q1yhvO1sXw8EEi66 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Q1yhvO1sXw8EEi66 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Q1yhvO1sXw8EEi66 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Q1yhvO1sXw8EEi66 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Q1yhvO1sXw8EEi66 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Q1yhvO1sXw8EEi66 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Q1yhvO1sXw8EEi66 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Q1yhvO1sXw8EEi66 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Q1yhvO1sXw8EEi66 .marker.cross{stroke:#333333;}#mermaid-svg-Q1yhvO1sXw8EEi66 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Q1yhvO1sXw8EEi66 p{margin:0;}#mermaid-svg-Q1yhvO1sXw8EEi66 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-Q1yhvO1sXw8EEi66 .cluster-label text{fill:#333;}#mermaid-svg-Q1yhvO1sXw8EEi66 .cluster-label span{color:#333;}#mermaid-svg-Q1yhvO1sXw8EEi66 .cluster-label span p{background-color:transparent;}#mermaid-svg-Q1yhvO1sXw8EEi66 .label text,#mermaid-svg-Q1yhvO1sXw8EEi66 span{fill:#333;color:#333;}#mermaid-svg-Q1yhvO1sXw8EEi66 .node rect,#mermaid-svg-Q1yhvO1sXw8EEi66 .node circle,#mermaid-svg-Q1yhvO1sXw8EEi66 .node ellipse,#mermaid-svg-Q1yhvO1sXw8EEi66 .node polygon,#mermaid-svg-Q1yhvO1sXw8EEi66 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Q1yhvO1sXw8EEi66 .rough-node .label text,#mermaid-svg-Q1yhvO1sXw8EEi66 .node .label text,#mermaid-svg-Q1yhvO1sXw8EEi66 .image-shape .label,#mermaid-svg-Q1yhvO1sXw8EEi66 .icon-shape .label{text-anchor:middle;}#mermaid-svg-Q1yhvO1sXw8EEi66 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Q1yhvO1sXw8EEi66 .rough-node .label,#mermaid-svg-Q1yhvO1sXw8EEi66 .node .label,#mermaid-svg-Q1yhvO1sXw8EEi66 .image-shape .label,#mermaid-svg-Q1yhvO1sXw8EEi66 .icon-shape .label{text-align:center;}#mermaid-svg-Q1yhvO1sXw8EEi66 .node.clickable{cursor:pointer;}#mermaid-svg-Q1yhvO1sXw8EEi66 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Q1yhvO1sXw8EEi66 .arrowheadPath{fill:#333333;}#mermaid-svg-Q1yhvO1sXw8EEi66 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Q1yhvO1sXw8EEi66 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Q1yhvO1sXw8EEi66 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Q1yhvO1sXw8EEi66 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Q1yhvO1sXw8EEi66 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Q1yhvO1sXw8EEi66 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Q1yhvO1sXw8EEi66 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Q1yhvO1sXw8EEi66 .cluster text{fill:#333;}#mermaid-svg-Q1yhvO1sXw8EEi66 .cluster span{color:#333;}#mermaid-svg-Q1yhvO1sXw8EEi66 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Q1yhvO1sXw8EEi66 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Q1yhvO1sXw8EEi66 rect.text{fill:none;stroke-width:0;}#mermaid-svg-Q1yhvO1sXw8EEi66 .icon-shape,#mermaid-svg-Q1yhvO1sXw8EEi66 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Q1yhvO1sXw8EEi66 .icon-shape p,#mermaid-svg-Q1yhvO1sXw8EEi66 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Q1yhvO1sXw8EEi66 .icon-shape rect,#mermaid-svg-Q1yhvO1sXw8EEi66 .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Q1yhvO1sXw8EEi66 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Q1yhvO1sXw8EEi66 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Q1yhvO1sXw8EEi66 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
消费层
服务编排层
UIAutomationService统一调度入口
SnapshotManager元素状态缓存
Visualizer点击动画 · 高亮反馈
Bridge IPC 层
BridgeClient连接 UNIX Socket
BridgeHost监听 Socket
代码签名验证Team ID 白名单
peekaboo CLICommander 框架
macOS AppSwiftUI
MCP Server供外部 AI 调用
内置 AgentTachikoma 驱动
ElementDetectionAX 树遍历 · 元素分类B1/T1 编号
ScreenCapture
Click · TypeScroll · Hotkey
App · WindowSpace · Menu
AccessibilityAXorcist 封装
ScreenCaptureKit
CGEvent鼠标 · 键盘
AppleScript应用管理
几个关键设计:
Bridge 权限代理:macOS 的屏幕录制和辅助功能权限是按应用授予的,但 AI agent 调用的是命令行工具 peekaboo。解决方案是 Bridge 架构——CLI 通过 UNIX Socket 连接到 OpenClaw.app 内的 BridgeHost 进程,BridgeHost 先验证调用方的代码签名和 Team ID,通过后才借出 app 已获得的权限执行操作。用户只需在系统设置里授权一次 OpenClaw.app。
元素检测与编号:see 命令截屏时同步遍历 Accessibility 树(通过 AXorcist 封装),把每个可交互元素按类型编号——按钮 B1、B2,输入框 T1、T2。遍历有严格限制(深度 8 层、子节点 200 个、150ms 超时),检测结果缓存 1.5 秒避免重复遍历。后续 click B1 就能直接定位到目标元素。
内置 Agent 模式:Peekaboo 自带基于 Tachikoma 的 agent 循环(支持 OpenAI / Anthropic / Ollama 等模型),可以独立执行多步桌面任务——不经过 OpenClaw,直接 peekaboo agent "打开备忘录写一条待办" 就能截屏→分析→点击→输入→确认,循环直到完成。
Skill 注入:Peekaboo 在 OpenClaw 中不是代码依赖,而是一个 Skill——通过声明文件标注"仅限 macOS、需要 peekaboo 命令",运行时按需注入到 AI 的 system prompt 中。非 macOS 用户完全不会感知到它的存在。
Cron 调度器:不只是定时器
OpenClaw 的定时任务不是简单的 setInterval,而是一个生产级调度系统:
- SHA256 Stagger:如果设了 100 个"每天早上 9 点"的定时任务,不会同时触发——用每个任务 ID 的 SHA256 哈希做确定性偏移(默认在 5 分钟窗口内分散),避免所有任务同一秒涌入,导致 CPU 和 API 调用瞬间过载
- 两种执行模式:systemEvent(把消息注入主会话,像用户发了一条消息)和 agentTurn(启动独立的 agent 运行,互不干扰)
- 容错:失败后指数退避重试(30 秒 → 1 分钟 → 5 分钟 → 15 分钟 → 1 小时),连续失败触发告警,临时 session 自动回收
Context Engine:长对话不丢记忆
大模型有上下文窗口限制(比如 200K token),聊久了上下文就超出。Pi SDK 提供了底层的两步上下文管线(transformContext 裁剪 + convertToLlm 格式转换),OpenClaw 在此基础上实现了自己的 Context Engine,定义了 5 个生命周期钩子:
bootstrap(初始化)→ ingest(新消息进入)→ assemble(组装发给模型的上下文)→ compact(上下文太长时压缩)→ afterTurn(一轮对话结束后清理)
默认实现用 token 计数 + LLM 摘要来压缩历史对话。但整个 Context Engine 是可插拔的——社区可以写一个完全不同的实现(比如基于向量检索的长期记忆),替换进去不需要改一行核心代码。
结语
阿瑟·克拉克在《2001:太空漫游》里写过一个场景:猿人月亮观察者捡起一块石头,第一次意识到自己的手可以延伸。从那一刻起,工具就不再是身体之外的东西——它是意志的投射。
我们今天拆解的这些——Gateway、Adapter、Bridge、Agent Loop——本质上都是同一件事的不同切面:让意图穿透介质。用户在 WhatsApp 里打一行字,意图穿过消息协议、穿过归一化流水线、穿过 LLM 的概率空间、穿过工具调用,最终变成屏幕上的一次点击、磁盘上的一个文件、终端里的一行输出。中间的每一层抽象,都是为了让这条路径上的摩擦再少一点。
这让人想起维纳在《控制论》里的判断:智能的本质不是计算,而是与环境之间有效的信息交换。OpenClaw 做的事情,与其说是"让 AI 用工具",不如说是在缩短人的意图与世界的状态之间的距离。


