让一个 Agent 同时吃 Telegram、飞书、钉钉,关键不是给每个平台写适配,而是先抽一层统一的消息接口,把“协议差异”挡在核心之外。OpenClaw 用 ChannelPlugin 这个排他式抽象接口做这件事:核心只认统一消息事件,每个 IM 平台实现一个插件做入站归一和出站翻译,新平台按接口规范写个插件就能接入,核心零改动。下文给出这层的设计要点、接口字段和落地步骤。
一、抽象层要解决的三个问题
多渠道接入的难点不在收发消息本身,而在三个统一。
| 问题 | 不抽象的后果 | 抽象后的目标 |
|---|---|---|
| 消息格式不一 | 飞书富文本卡片、Telegram Command、企微 XML 各写各的 | 统一成标准消息事件 |
| 身份不互通 | 用户从 WhatsApp 切 Telegram 上下文断 | 按 sessionKey 统一标识 |
| 能力差异大 | 有的支持富媒体有的不支持,硬调会崩 | 能力声明,核心按能力降级 |
OpenClaw 截至 2026 年 4 月内置 8 个核心通道,社区贡献 50+ 扩展通道,覆盖主流即时通讯工具。
二、ChannelPlugin 接口的字段设计
2.1 必选与可选字段
接口分必选和可选两档。必选四个缺一不可,可选按通道能力实现,没实现即视为该通道不支持。
| 字段 | 必选 | 职责 |
|---|---|---|
| id | 是 | 通道唯一标识,如 telegram、feishu |
| meta | 是 | 通道元信息,名称图标描述 |
| capabilities | 是 | 能力声明,是否支持富媒体文件 |
| config | 是 | 配置管理,读 API Key、Webhook |
| outbound | 否 | 发送适配器,不实现不能主动发 |
| pairing | 否 | 配对逻辑,不实现不支持扫码绑定 |
| heartbeat | 否 | 心跳检测,不实现无心跳 |
| messaging | 否 | 核心消息接收与解析适配器 |
export type ChannelPlugin = {
// 必选,缺一不可
id: ChannelId;
meta: ChannelMeta;
capabilities: ChannelCapabilities;
config: ChannelConfigAdapter;
// 可选,按通道需求实现
outbound?: ChannelOutboundAdapter;
pairing?: ChannelPairingAdapter;
heartbeat?: ChannelHeartbeatAdapter;
messaging?: ChannelMessagingAdapter;
};
这种“面向接口编程而非面向实现”是生态能转起来的根基:核心模块不关心底层是哪个 IM,只跟抽象接口打交道。
2.2 标准消息事件与无状态适配
无论外面怎么变,进了 OpenClaw 的大门,所有消息都被强制整形成统一格式。
{
"event_id": "evt_123456789",
"channel_id": "feishu",
"sender_id": "ou_xxyyzz123",
"timestamp": 1710259200,
"payload": {
"type": "text",
"content": "帮我把桌面的 log 压缩发给张三",
"attachments": []
}
}
Channels 层完全无状态,像纯函数 f(x) = y,不含业务逻辑只做协议转换。社区因此能轻松贡献 Discord-Adapter、Slack-Adapter 等插件。
2.3 sessionKey 统一身份
OpenClaw 用标准化 sessionKey 统一标识跨渠道会话,格式按平台前缀区分。
| 渠道 | sessionKey 格式 |
|---|---|
| wa:+1234567890 | |
| Telegram | tg:123456789 |
| 飞书 | feishu:ou_xxxxx |
| 钉钉 | ding:user_xxxxx |
| Web | web:abc123 |
所有会话状态、记忆、任务都按 sessionKey 存储,用户从 WhatsApp 切到 Telegram,只要绑定同一身份,对话上下文无缝衔接。
三、自己接一个新渠道的步骤
以接入一个虚构的“春哥通”为例,核心层不用改任何代码。
- 在 package.json 写
openclaw.channel元数据声明 id、label、blurb、capabilities,触发渠道发现; - 用
createChatChannelPlugin入口构建插件,实现 id、meta、capabilities、config 四个必选字段; - 实现 messaging 适配器,把平台原始 Webhook 或事件回调归一成标准消息事件;
- 实现 outbound 适配器,把内部回复翻译成平台格式并发送;
- 在配置里填好 API 凭证,用
openclaw doctor验证通道加载,完成。
{
"openclaw": {
"channel": {
"id": "acme-chat",
"label": "Acme Chat",
"blurb": "Connect to Acme Chat messaging platform",
"markdownCapable": true,
"exposure": { "configured": true, "setup": true, "docs": true }
}
}
}
渠道与 AI 核心之间通过 ACP(Agent Communication Protocol)消息总线通信,消息格式统一为 JSON Schema,含 source、message_id、content、attachments、timestamp 等标准字段,插件不直接与核心交互。exposure 字段控制渠道在设定列表、交互式选择器和文档页面的可见性。
常见问题(FAQ)
Q1:通道插件必须实现所有字段吗?
四个必选字段缺一不可,可选字段不实现即视为不支持。
Q2:新平台接入要改核心代码吗?
不用,按接口规范写个插件即可,核心零改动。
Q3:用户跨平台切换会丢上下文吗?
不会,按 sessionKey 统一标识,绑定身份即无缝衔接。