openclaw.md 10.1 KB

OpenClaw 源码技术方案解读

面向源码阅读者的技术剖析:从 CLI 入口、Gateway 控制面、渠道插件、路由与会话、Agent 执行到媒体与安全。

1. 总体架构(控制面 + 执行面)

OpenClaw 把系统拆成两层:

  • Gateway 控制面:统一承载 WebSocket/HTTP、方法分发、客户端连接、鉴权、配置热重载、渠道生命周期。
  • Agent/Channel 执行面:负责模型调用、会话持久化、消息路由、跨渠道发送、媒体处理、插件扩展。

这种设计把“系统连接与治理”与“具体业务执行”分离,便于在不改动主干的前提下持续增加新渠道和新能力。

2. CLI 启动链:轻入口 + 按需加载命令

src/index.ts 作为统一入口,先做运行时守护(环境变量归一化、运行时版本检查、全局异常处理),再交给 Commander 程序对象解析命令。核心思路是:先把运行环境稳定,再执行命令逻辑

CLI 命令注册使用“延迟加载”策略:registerCoreCliCommands 会先挂占位命令,在真正执行时动态 import 对应模块并二次解析参数。这显著降低了冷启动成本,也能避免一次性加载全部命令依赖。

3. Gateway 服务器:集中式编排器

startGatewayServer 是系统级编排入口,启动前会串行处理:

  1. 读取并迁移历史配置;
  2. 校验配置合法性并补齐启动鉴权;
  3. 自动启用满足条件的插件;
  4. 组装基础能力 + 渠道插件能力形成完整方法集;
  5. 构建运行时状态(鉴权、限流、心跳、节点、插件、通道、发现服务等);
  6. 挂载 WS 处理器并对外广播统一事件。

这让 Gateway 成为“单一控制平面”:无论来自 CLI、WebChat、桌面端还是移动端,最终都走同一套 RPC/Event 协议。

4. 方法协议:基础方法 + 插件方法拼接

server-methods-list.ts 维护内置方法集合(如 agentsendchannels.statusnode.invokechat.send),再合并渠道插件额外暴露的方法,形成完整 capability 列表。

这相当于“内核 API + 扩展 API”模型:内核保持稳定,插件在边界内扩展。

5. 渠道插件体系:注册表驱动

渠道并不是硬编码在主流程中,而是通过插件注册表统一管理。listChannelPlugins 从活动插件注册表读取渠道定义并排序输出;Gateway 在启动时基于这些定义动态创建日志上下文、运行时环境与方法集合。

这意味着新增渠道的关键不是修改核心 switch-case,而是实现符合接口的插件并注册,整体可维护性更好。

6. 渠道生命周期管理:可观测 + 自恢复

createChannelManager 负责渠道账户的启动/停止/状态维护,具备:

  • 多账户粒度运行时快照;
  • 启动前配置完整性检查;
  • 崩溃后指数退避重启;
  • 手动停用后禁止自动拉起;
  • 统一暴露运行状态给上层 health/status。

这套机制让各渠道实现从“业务代码”中抽离,收敛到统一的运维语义。

7. 路由与会话键:多维绑定解析

resolve-route.ts 把输入上下文(channel/account/peer/guild/team/roles)映射到目标 agent 与 sessionKey。其本质是一套优先级匹配规则:

  • peer 精确匹配;
  • parent peer 继承;
  • guild + roles;
  • guild/team/account/channel;
  • 默认 agent 回退。

并且它带有按 channel+account 的评估缓存,避免在高频消息场景重复解析绑定规则。

8. Agent 执行:Gateway 方法到模型调用

Gateway 侧 agent 方法会完成请求校验、幂等处理、附件规范化、会话键解析与重置语义,然后调用 agentCommand 执行一次 Agent turn。

agentCommand 再根据模型/Provider/思考等级/会话状态选择执行路径:

  • CLI Provider 走 runCliAgent
  • 内嵌执行走 runEmbeddedPiAgent
  • 并支持模型回退、会话更新、事件发射、结果投递。

因此 OpenClaw 的 Agent 调用并不是“直接请求模型”,而是带有会话与路由语义的受控执行流水线。

9. Outbound 抽象:优先插件动作,回退核心发送

outbound-send-service.ts 体现了一个关键策略:

  1. 先尝试调用渠道插件动作(send/poll);
  2. 插件未处理时回退到核心 sendMessage/sendPoll
  3. 在发送链路中支持中断信号、镜像写回会话、网关上下文。

这保证了不同渠道可做差异化实现,同时保留统一兜底路径。

10. 媒体管线:安全优先

media/store.ts 中可见明显的“安全默认”策略:

  • 限制协议仅 HTTP/HTTPS;
  • 使用 SSRF 防护与主机名解析钉扎;
  • 限制文件大小(默认 5MB);
  • 临时目录权限收紧(700/600);
  • 文件名净化与过期清理;
  • 安全读取本地文件并映射错误类型。

这使媒体能力在可用性与安全性间取得平衡。

11. 配置系统:JSON5 + 兼容迁移 + 环境变量注入

config/io.ts 不是简单读写配置文件,而是完整的配置编排层:

  • 支持 JSON5;
  • include/merge patch/env 引用替换;
  • 默认值补全、路径归一化、版本迁移;
  • 写入审计与备份轮转;
  • 与插件 schema 联合校验。

这套机制让 OpenClaw 能在长期迭代中保持配置向后兼容。

12. 具体案例:从用户一句话到系统动作链

下面用两个典型请求,说明 OpenClaw 在真实场景里会触发什么动作。

案例 A:"帮我在 GitHub 搜索 xx 相关项目,筛选能迁移到 xx 的方案,仔细阅读并讲技术方案和关键代码"

这个需求不是一次普通问答,而是一条“检索 -> 过滤 -> 深读 -> 结构化输出”的多阶段流水线。典型动作链如下:

  1. 消息入站 用户消息通过 Telegram/Discord/WebChat 等渠道进入 Gateway;渠道插件先归一化消息、账户信息、线程信息,再转为统一 agent 请求。
  2. 会话与目标 agent 解析 路由层用 channel/account/peer/thread 上下文解析 agentId + sessionKey,把任务绑定到既有会话(避免每轮丢上下文)。
  3. 请求校验与幂等 Gateway agent handler 校验参数、附件、渠道合法性和幂等键,然后把任务交给 agentCommand
  4. 任务规划(Agent 内部) Agent 将原句拆成可执行子任务,例如:
    • 关键词扩展(xx 的同义词、上下游术语);
    • 候选项目召回(stars/更新时间/语言/许可证);
    • 迁移可行性筛选维度(架构耦合度、依赖复杂度、部署形态、数据模型兼容性);
    • 深读清单(README、docs、核心目录、关键 entrypoint)。
  5. 候选项目检索 Agent 通过浏览器或 HTTP 工具抓取 GitHub 搜索页/项目页,得到候选仓库列表与基础元信息。
  6. 第一轮筛选(可迁移性粗筛) 基于显性信号先过滤:
    • 是否活跃维护;
    • 是否与目标技术栈接近;
    • 是否有可运行示例与清晰模块边界;
    • 许可证是否满足使用场景。
  7. 第二轮深读(代码级) 对入围项目进行“关键代码阅读”:
    • 定位入口文件与启动链;
    • 识别核心模块边界与数据流;
    • 抽取关键实现片段(例如路由层、调度层、插件层、存储抽象层);
    • 记录迁移风险(强绑定云服务、隐式全局状态、非标准构建流程)。
  8. 输出构建 Agent 生成结构化结论:
    • 项目对比表(适配度/迁移成本/风险);
    • 每个项目的技术方案摘要;
    • 关键代码位置与原因说明(为什么这段代码关键);
    • 推荐优先级与迁移路径建议(PoC -> 灰度 -> 全量)。
  9. 结果发送与会话沉淀 结果经 outbound 发送到原渠道(插件优先、核心兜底),并写入会话 transcript。后续用户说“把第 2 个项目展开到模块级改造方案”时,可直接沿用当前上下文继续执行。

这个案例在系统内触发的关键机制

  • Gateway 控制面:统一承接请求、鉴权、方法分发。
  • 路由层:保证请求进入正确 agent/session。
  • Agent 执行层:负责任务分解与工具编排。
  • Outbound 层:统一回传,不同渠道差异由插件吸收。
  • 会话存储层:沉淀中间结论与最终报告,支撑多轮深挖。

案例 B:"在 Twitter 上搜集 xx 相关信息,写一篇调查报告"

一个典型执行链如下:

  1. 请求入站与鉴权 用户请求到达 Gateway 后,先经过鉴权与方法白名单控制。
  2. 任务分解 Agent 将任务拆成“检索关键词集合、时间窗口、可信账号优先级、去重规则、证据归档格式”。
  3. 数据采集 通过浏览器/HTTP 等工具抓取公开推文、线程、外链文章与引用关系,必要时抓页面快照做证据留存。
  4. 清洗与聚类 依据主题、立场、时间线、传播强度进行聚类,过滤明显噪声与重复转发。
  5. 报告生成 输出“事实层(发生了什么)+ 观点层(各方怎么说)+ 风险层(哪些结论证据不足)+ 建议层(下一步怎么验证)”。
  6. 多渠道投递 按当前会话策略发送到用户指定渠道;如果是群聊线程,还会带上 thread 信息以保持上下文连续。

两个案例背后的共性机制

  • 同一控制面:不管是 GitHub 调研还是 Twitter 调研,都是同一条 Gateway RPC/Event 主干。
  • 同一路由语义:都通过 sessionKey/agentId 保证上下文连续,而不是每次“无状态回答”。
  • 同一执行模式:都属于“规划 -> 工具调用 -> 归纳输出”的 agentic 工作流。
  • 同一发送抽象:都走 outbound 统一接口,渠道差异由插件吸收。
  • 同一安全基线:媒体下载、外链抓取、文件读写都受限于安全策略(协议、大小、路径、SSRF)。

13. 一句话总结

OpenClaw 的核心技术方案可以概括为:

“以 Gateway 为统一控制面,以插件与路由为扩展骨架,以 Agent 会话语义为执行核心,并在媒体/配置层默认内建安全与可运维能力。”