
1. 从一条消息的旅程看 OpenClaw 的 Gateway 设计如果你第一次接触 OpenClaw最直观的困惑往往是一条从 Telegram 发来的消息到底是怎么被路由到某个 Agent、又怎么触发插件能力的这个问题的答案几乎全部藏在 Gateway 里。OpenClaw 是一个面向个人 AI 助手的开源框架它能做什么简单说它把消息平台、AI 模型、系统能力摄像头、浏览器、命令执行统一到一个进程里适合想自己搭一套可控 AI 助手的开发者。而它最核心的设计取舍就是「以 Gateway 为中心的可插件化单体系统」。我先把结论摆出来OpenClaw 没有走微服务路线也没有做完全去中心化的 P2P 架构而是把 Gateway 做成整个系统的神经中枢——协议统一、能力协调、消息路由、安全控制四件事全在这里完成。插件则通过能力声明capabilities挂载到 Gateway 上核心代码不需要为每个渠道写 if-else。这个设计哲学听起来抽象但落到配置文件和请求日志上其实非常具体。这篇文章不会停留在概念层面。我会带你拆解 Gateway 的路由优先级、插件注册机制给出可以直接复制的 JSON 配置片段然后演示新增一个插件后如何通过请求分发日志和插件加载状态验证它是否真的生效。如果你正在评估 OpenClaw 是否适合自己的项目或者想理解「可插件化单体」到底怎么落地这篇拆解应该能帮你省下不少翻源码的时间。在开始之前先明确一个前提OpenClaw 的所有客户端——CLI、Web UI、macOS App、移动节点——都通过统一的 WebSocket 协议与 Gateway 通信。这意味着无论前端怎么变后端接口保持稳定。这是理解后续所有路由和插件逻辑的基础。2. Gateway 路由与插件注册的前置准备在动手配置之前你需要先让 Gateway 跑起来并且理解它的配置文件结构。OpenClaw 的配置采用声明式 JSON核心文件通常位于~/.openclaw/config.json也可以通过环境变量覆盖。这里我不重复注册流程直接假设你已经有一个可运行的 Gateway 实例接下来聚焦路由和插件这两块。先说 Gateway 的四大职责这决定了你配置时该关注哪些字段。第一是协议统一所有连接走 WebSocket消息类型只有 Request、Response、Event 三种事件里带seq和stateVersion用于状态同步。第二是能力协调每个 Node 连接时声明自己的caps和commandsGateway 维护命令白名单。第三是消息路由这是本篇的重点OpenClaw 采用分层优先级绑定从高到低是 Group/Topic 级别、DM 级别、Channel 级别、全局默认 Agent。第四是安全控制三层认证Gateway Token、Device Identity、Pairing Approval本地 loopback 或 tailnet 地址会自动批准。插件注册则围绕「能力声明驱动」展开。一个 Channel Plugin 只需要声明自己支持哪些 capabilities比如是否支持群聊、是否支持媒体、是否支持流式输出Gateway 的核心消息处理逻辑就会根据这些声明动态调整行为。举个例子如果插件声明streaming: trueAgent 的回复就能实时推送如果声明media.images: trueGateway 会自动下载入站图片并调用视觉理解模型。核心代码里没有一行是针对某个具体渠道写的。这里有个容易踩的坑很多人以为插件是「运行时动态发现」的实际上 OpenClaw 在 Gateway 启动时会扫描~/.openclaw/plugins/和node_modules中符合命名规范的包然后按依赖关系拓扑排序加载。也就是说插件的加载顺序是有保证的依赖的插件一定先于依赖它的插件加载。如果你新增的插件没有被加载第一件事就是检查它是否在扫描路径内、包名是否符合规范。另外配置系统支持多级合并默认配置、全局配置、项目配置、环境变量优先级从低到高。这意味着你可以在项目目录放一个局部配置覆盖全局设置调试时非常方便。配置验证用的是 Zod Schema写错字段会直接报错不会静默失败——这一点对排查问题很友好。理解了这些你就可以开始写路由和插件配置了。下一节给出可直接复制的片段。3. 可复制的 Gateway 路由与插件配置片段这一节是实操核心。我会给出三段配置Gateway 全局路由、渠道插件注册、Agent 级别绑定。你可以直接复制到自己的config.json里按需改字段。先看 Gateway 全局路由与安全策略。这段配置决定了哪些命令允许、哪些拒绝以及默认 Agent 是谁{ gateway: { nodes: { allowCommands: [camera.snap, canvas.navigate, browser.open], denyCommands: [system.run, fs.delete] }, routing: { defaultAgentId: main, priority: [group, dm, channel, global] } } }这里的priority数组就是分层优先级的显式声明。当一条消息进来Gateway 会从group开始逐级向下匹配命中即停。allowCommands和denyCommands是命令白名单机制Node 声明的命令必须同时满足「在 allow 里」且「不在 deny 里」才会被放行。接下来是渠道插件注册。以 Telegram 和飞书为例注意capabilities字段——这是插件能力声明的关键{ channels: { telegram: { enabled: true, botToken: ${TELEGRAM_BOT_TOKEN}, capabilities: { chatTypes: [direct, group], media: { images: true, audio: true }, streaming: true, reactions: false }, groups: { -1001234567890: { topics: { 1: { agentId: main }, 3: { agentId: work } } } } }, feishu: { enabled: true, appId: ${FEISHU_APP_ID}, appSecret: ${FEISHU_APP_SECRET}, capabilities: { chatTypes: [direct, group], media: { images: true }, streaming: false } } } }注意 Telegram 的groups里用了 topic 级别绑定这就是最高优先级的 Group/Topic 路由。topic 1 的消息走mainAgenttopic 3 走workAgent。飞书没有配 topic所以它会落到 Channel 级别或全局默认。最后是 Agent 级别的工具过滤这是安全控制的第二层{ agents: { list: [ { id: main, tools: { allow: [browser, camera], deny: [exec] } }, { id: work, tools: { allow: [browser], deny: [exec, camera] } } ] } }这三段配置合在一起就构成了一个完整的「路由 插件 安全」闭环。你可以把它们合并到一个config.json里注意 JSON 顶层不能有重复键。改完后 Gateway 支持热重载不需要重启进程。如果你在配置里用到了${VAR}形式的环境变量记得在启动 Gateway 前 export 好否则 Zod 验证会报缺失字段。这是新手最常见的第一个报错来源。4. 验证请求分发与插件加载是否生效配置写完不代表生效。这一节教你用三种方式验证看启动日志、发测试请求、查插件加载状态。第一步重启或热重载 Gateway 后观察启动日志。正常情况下你会看到类似这样的输出[gateway] scanning plugins in ~/.openclaw/plugins/ [gateway] loaded plugin: channel-telegram (capabilities: chatTypes, media, streaming) [gateway] loaded plugin: channel-feishu (capabilities: chatTypes, media) [gateway] routing priority: group dm channel global [gateway] default agent: main如果某个插件没出现在loaded plugin列表里说明它没被扫描到或者包名不符合规范。检查~/.openclaw/plugins/目录下是否有对应的包以及package.json里的 name 字段是否符合openclaw/channel-*或openclaw-channel-*的命名约定。第二步发一条测试请求观察路由结果。你可以用 CLI 直接向 Gateway 发一个 Requestopenclaw request --method message.send \ --params {channel:telegram,chatId:-1001234567890,topicId:3,text:ping} \ --idempotency-key test-001注意idempotencyKey是必须的因为message.send有副作用Gateway 会用它做短期去重。发送后Gateway 的日志会打印路由决策[router] incoming message channeltelegram chatId-1001234567890 topicId3 [router] matched group/topic binding - agentIdwork [router] dispatching to agent work如果日志显示matched global default - agentIdmain说明你的 topic 绑定没生效检查groups里的 chatId 和 topicId 是否和实际消息一致。Telegram 的 chatId 是负数topicId 是字符串这两个类型错了都会导致匹配失败。第三步查插件加载状态。OpenClaw 提供了一个诊断接口openclaw request --method plugin.list --params {}返回结果会列出所有已加载插件及其 capabilities。你可以对照配置文件确认每个插件的streaming、media等字段是否和预期一致。如果某个插件显示capabilities: {}说明它的能力声明没被正确解析通常是插件代码里capabilities字段拼写错误或类型不对。实测下来最常见的验证失败是「插件加载了但能力没生效」。原因往往是插件声明了streaming: true但 Gateway 的核心逻辑没有对应的处理分支——这通常意味着插件版本和 Gateway 版本不匹配。检查两者的版本兼容性或者看插件文档里有没有要求最低 Gateway 版本。5. 本篇常见报错排查配置和验证过程中有几类报错几乎每个人都会遇到。我把它们整理成对照表方便你快速定位。第一类401 认证失败。报错信息通常是401 Unauthorized: invalid gateway token。这有两种可能一是你的 Gateway Token 没配对检查环境变量OPENCLAW_GATEWAY_TOKEN是否和 Gateway 启动时用的一致二是设备身份验证没过新设备需要走 Pairing Approval 流程。如果你在本地 loopback 地址上遇到 401检查 Gateway 是否把该地址识别为本地连接——有时候容器网络会让 loopback 判断失效。第二类local proxy failed。这个报错一般出现在 Node 连接 Gateway 时说明 Node 声明的命令和 Gateway 的白名单不匹配。检查gateway.nodes.allowCommands里是否包含该 Node 需要的命令。注意命令是精确匹配camera.snap和camera.snapshot是两个不同的命令。第三类reading choices相关错误。这通常发生在 Agent 调用模型接口时返回结构里没有choices字段。如果你是通过兼容接口接入模型检查 Base URL、Key、Model ID 三件套是否完整。以 TaoToken 为例Base URL 填https://taotoken.net/apiKey 在控制台生成Model ID 按文档填。三者缺一不可少一个就会返回非预期结构导致reading choices报错。第四类OAuth 相关报错。如果你用的是需要 OAuth 的渠道插件报错可能是OAuth token expired或invalid redirect uri。这类问题多半是回调地址没在平台侧配置或者 token 刷新逻辑没走通。检查插件文档里的 OAuth 配置章节确认 redirect URI 和平台后台填的一致。第五类插件加载顺序问题。报错可能是plugin X depends on Y which is not loaded。这说明拓扑排序时依赖缺失。检查你的插件package.json里有没有声明peerDependencies或openclaw.dependencies确保依赖的插件也在扫描路径内。这里要特别提醒如果你在配置里同时用了 CC Switch、Cline MCP 或 Codex 的auth.json务必确认 Base URL、Key、Model ID 三件套写全。我见过太多人只填了 Key 和 Model ID忘了 Base URL结果请求发到了默认地址报了一堆看不懂的错。三件套缺一不可这是硬性要求。排查时的一个通用技巧把 Gateway 日志级别调到 debug能看到完整的路由决策链和插件调用栈。大部分问题在 debug 日志里一目了然。6. 把 Gateway 用起来接入与后续走到这里你应该已经理解了 OpenClaw 以 Gateway 为中心的可插件化单体设计并且能自己配置路由、注册插件、验证分发。接下来最实际的一步是把它接到你日常用的模型服务上让 Agent 真正跑起来。接入的核心就是三件套Base URL、API Key、Model ID。以 TaoToken 为例你可以在控制台生成 Key然后按文档把 Base URL 填成https://taotoken.net/apiModel ID 按你选的模型填。配置写进config.json的模型段后热重载即可生效。如果你想先验证模型通不通可以直接用模型对话页面发一条测试消息确认返回正常再写进配置。对于长期跑编码任务或 Agent 工作流的场景Coding Plan 会更合适它针对持续调用做了优化。而如果你只是想快速试一下接入效果API Keys 页面加上接入文档就够用了。文档里有完整的配置示例照着改字段就行。回到架构本身OpenClaw 这套设计最值得借鉴的地方是它没有盲目追微服务而是根据个人 AI 助手的实际需求——状态密集、实时交互、能力多样、安全敏感——选择了单体加插件化的路线。Gateway 作为唯一的安全控制点和路由中枢让所有能力都经过统一入口这既简化了部署也让审计和排障变得可控。插件的能力声明驱动机制则让核心代码保持稳定扩展通过声明完成而不是改核心逻辑。如果你正在设计类似的系统不妨问自己一个问题我的场景真的需要分布式吗还是说一个边界清晰的单体加插件机制反而能更快落地、更好维护OpenClaw 给出的答案至少在个人助手这个定位上是站得住脚的。