不管是飞书、QQ 还是微信,最常见的交互都是文字;而在语音场景里,“说话”才是更自然的沟通方式。
直到我看到这篇关于“小智语音对话机器人”和 OpenClaw 打通的文章。

核心思路:让小智通过 MCP 指挥 OpenClaw,从而把能力边界从已接入的 MCP 工具,扩展到 OpenClaw 背后的海量 Skills。
实现思路:
- 平台侧:建立与 OpenClaw 的稳定通信
- 用户侧:接入自己的 OpenClaw,并通过设备端 MCP 调用


一、平台侧:打通与 OpenClaw 的通信
1.1 通信协议
与 OpenClaw 的传输层基于 WebSocket。
面对飞书、微信等不同终端、不同会话,使用以下标识即可区分:
client.id:标识终端session_key:标识会话

因此,多个客户端可以共享同一个 session 的记忆与历史。

你也可以在 OpenClaw 控制台查看指定 session 的对话。

1.2 核心接口
基于 OpenClaw 的通信协议,以下几个关键请求方法

并通过 self.request 统一封装(底层采用 WebSocket 传输):
async def chat_send(self, message: str) -> Any:
"""发送聊天消息到指定session"""
return await self.request('chat.send', {
'sessionKey': self.session_key,
'message': message,
'idempotencyKey': f'{int(time.time() * 1000)}-{hash(message)}',
})
async def get_history(self, limit: int = 50) -> Any:
"""获取聊天历史"""
return await self.request('chat.history', {
'sessionKey': self.session_key,
'limit': limit
})
async def list_sessions(self) -> Any:
"""列出所有session"""
return await self.request('sessions.list')
async def list_agents(self) -> Any:
"""列出agents"""
return await self.request('agents.list')
async def get_config(self) -> Any:
"""获取配置"""
return await self.request('config.get')
1.3 响应解析
在响应事件中,重点关注 agent 与 chat 两类事件。
以下为日志中的关键数据结构节点:
2026-02-15 17:38:44 - openclaw - INFO - 尝试连接: ws://14.xx.xx.82:18789
2026-02-15 17:38:44 - openclaw - INFO - WS已连接,等待 challenge...
2026-02-15 17:38:44 - openclaw - INFO - 收到 challenge: {'type': 'event', 'event': 'connect.challenge', 'payload': {'nonce': 'ae76555e-1d6e-4dc1-acea-294e67e0dcce', 'ts': 1771148324902}}
2026-02-15 17:38:44 - openclaw - INFO - ✅ 连接成功!
2026-02-15 17:38:44 - openclaw - INFO - 🚀 消息已发送,runId: 1771148324960--1126353816726381137,等待 AI 回复...
2026-02-15 17:38:45 - openclaw - INFO - 🤖 Agent事件: runId=1771148324960--1126353816726381137, stream=lifecycle, data={'phase': 'start', 'startedAt': 1771148325217}
2026-02-15 17:38:50 - openclaw - INFO - 🤖 Agent事件: runId=1771148324960--1126353816726381137, stream=assistant, data={'text': '收到', 'delta': '收到'}
2026-02-15 17:38:50 - openclaw - INFO - 💬 Chat事件: runId=1771148324960--1126353816726381137, state=delta, message={'role': 'assistant', 'content': [{'type': 'text', 'text': '收到'}], 'timestamp': 1771148330101}
2026-02-15 17:38:50 - openclaw - INFO - 🤖 Agent事件: runId=1771148324960--1126353816726381137, stream=assistant, data={'text': '收到,我去', 'delta': ',我去'}
2026-02-15 17:38:50 - openclaw - INFO - 💬 Chat事件: runId=1771148324960--1126353816726381137, state=delta, message={'role': 'assistant', 'content': [{'type': 'text', 'text': '收到,我去检查下人设文件'}], 'timestamp': 1771148330294}
2026-02-15 17:38:50 - openclaw - INFO - 🤖 Agent事件: runId=1771148324960--1126353816726381137, stream=assistant, data={'text': '收到,我去检查下人设文件。', 'delta': '。'}
2026-02-15 17:39:11 - openclaw - INFO - 🤖 Agent事件: runId=1771148324960--1126353816726381137, stream=lifecycle, data={'phase': 'end', 'endedAt': 1771148351507}
2026-02-15 17:39:11 - openclaw - INFO - 💬 Chat事件: runId=1771148324960--1126353816726381137, state=final, message={'role': 'assistant', 'content': [{'type': 'text', 'text': '你说得对,我漏了。SOUL.md 里写得清清楚楚:\n\n> 收到任何消息或者任务,先立即回复我\'收到\',然后再去具体执行\n\n以后我会先回"收到",再干活。记住了。'}], 'timestamp': 1771148351507}
1.4 架构设计
基于上述事件流,小智Pro 采用双 WebSocket 桥接方案:
- 后端服务作为 Proxy,中间桥接
- 一端连接前端客户端 / ESP32 设备端
- 另一端连接用户的 OpenClaw Gateway

前端连通后,即可向 OpenClaw 发送一条测试消息,验证链路。

二、设备端:MCP 调用
平台侧已贯通与 OpenClaw 的通信,那么设备端如何调度?
本质仍是通过 MCP。

对应到本文开头的流程图,在设备端新增一个 Tool:
self.openclaw.send
考虑到语音识别命中率,给 OpenClaw 起个中文外号更稳:“欧克劳”。

实测,发送成功,并收到了 OpenClaw 的回应。

三、用户接入 OpenClaw
3.1 调整人设设定
OpenClaw 接入的是推理模型,其 thinking 阶段耗时较长。
为缩短等待,需要适当修改其人设配置,减少无谓延迟。

3.2 前端建立连接
在 OpenClaw 控制台获取公网可访问的 Gateway URL 与鉴权 Token;

前往小智Pro 控制台,填入对应字段;

session_key 命名规范:agent::
如果不需要区分会话,可直接使用 OpenClaw 控制台的 Default Session Key。连接成功后,你可以在小智Pro 控制台直接对话,并查看历史记录。

人设优化到位后,前端延迟测试显示:简单指令基本秒回。


随后让小智给 OpenClaw 下发一条任务


回到 OpenClaw 控制台验收,任务执行通过。

写在最后
本文完整拆解了“小智Pro 让小智控制 OpenClaw”的实现路径:协议、事件流、桥接架构到设备端调用与用户接入,逐步打通。
若对你有帮助,欢迎点赞收藏备用。
更多能力体验请戳:https://mkwyqeoebedx.sealosbja.site
注:接管 OpenClaw 能力需设备端固件 v2.2.2.2 支持。

目前已适配小智官方仓库收录的开发板型号,