为什么 OpenClaw 在实时推送场景下选择拥抱 WebSocket?

精炼回答

因为 Agent 的工作方式是流式的、双向的、多客户端的------而这三点,HTTP 轮询从设计上就满足不了。

OpenClaw 的 Gateway 运行在 ws://127.0.0.1:18789,CLI、WebChat UI、macOS App、iOS/Android Node 全都通过 WebSocket 连到这个控制平面。这不是随手选的技术,而是 Agent 运行模型倒逼出来的结论。

当你发一条消息给 OpenClaw,Brain 进入 ReAct 推理循环:Thought → Action → Observation → Thought......这个过程可能持续几秒到几十秒,中间会不断产生中间状态。如果用 HTTP 请求-响应,你只能等整个循环跑完拿到最终结果;用 WebSocket,Gateway 可以把每一步的状态实时流向所有连接中的客户端------这就是你在 Telegram 看到"正在思考......"然后逐步更新的效果背后的机制。

HTTP 本质是"一问一答",问完连接就关了,服务端没有办法主动联系客户端。轮询是对这个限制的绕行方案:客户端每隔几秒问一次"有消息吗"。这个方案能用,但 99% 的请求换来的是空响应,每次都要重新走 TCP 握手和 HTTP 头解析的完整流程。对于 Agent 这种执行过程本身就是连续事件流的系统,这个代价完全不值得付。


扩展分析

OpenClaw 面对的是什么样的通信模型

要理解为什么选 WebSocket,先得看清楚 OpenClaw 的消息流长什么样。

注意图里有个细节:Telegram 和 WhatsApp 走的是 HTTP,CLI/WebChat/App 走的是 WebSocket。这不是矛盾,而是各归其位------外部平台的协议由平台决定,OpenClaw 自己控制的通道全部选择了 WebSocket。

Gateway 在这里不是消息转发器,而是整个系统的神经中枢:它接收来自各个渠道的输入,驱动 Brain 推理,再把推理过程中产生的每一个中间状态实时广播出去。这个"实时广播"的需求,是选型的核心出发点。


为什么轮询在这个场景下撑不住

把三种常见方案放在一起比较,差距会非常直观:

短轮询在 Agent 场景下问题很明显:推理过程可能持续 30 秒,轮询间隔设 1 秒就有 30 次空请求,设 5 秒消息延迟又高得难以接受。而且每次请求都要重新建 TCP 连接,在本地环回地址还好,一旦上云或走移动网络,开销就完全不可接受。

长轮询是 OpenClaw 在 Telegram 通道上的选择------但这是一个刻意的权衡,不是通用最优解。Telegram Bot 的长轮询模式(由 grammY runner 实现)之所以适合,是因为本地部署场景下无需公网 IP、无需 HTTPS 证书,零配置开箱即用。但长轮询本质上仍然是"等服务端回应后立刻发下一个请求",本地维持一条连接的逻辑比较绕,高并发下服务端也需要维持大量挂起的连接。

WebSocket 一次握手,连接永久保持。对 OpenClaw 来说,这意味着三件事同时成立:推理中间状态可以实时 stream 出来、用户确认可以随时插入流程、多个客户端能同步看到同一个 Agent 的状态变化。


三个具体场景,三个"HTTP 做不到"的理由

场景一:流式推理输出

Brain 执行一次任务的过程不是"输入 → 等 → 输出",而是连续的状态机:

vbnet 复制代码
Thought: 用户想看 PR 列表,需要调用 github skill
Action: exec("gh pr list --state open --json number,title,author")
Observation: [{"number":42,"title":"Fix login bug"...}]
Thought: 拿到数据了,整理成自然语言回复
Final Answer: "当前有 3 个 open PR..."

每一步都是一个事件。WebSocket 让这些事件实时流向客户端,用户能看到 Agent"正在干什么",而不是盯着转圈等结果。HTTP 做不到这个------你必须等整条链路跑完,才能发出那个唯一的响应。

场景二:双向确认交互

Heartbeat 触发了一个定时任务,任务执行到一半发现需要合并一个 PR,OpenClaw 需要向用户确认:"要不要 merge #42?"用户回复"可以",任务继续执行,最终结果回推。

这整个过程里,服务端和客户端都需要随时主动发消息。HTTP 的单向性(服务端不能主动发)在这里根本撑不住------你必须用轮询来"模拟"服务端的主动推,而 WebSocket 原生就支持。

场景三:多客户端状态同步

你同时在手机 Telegram 发了一条消息,在电脑上的 WebChat 看进度。Gateway 通过 WebSocket 把同一个 Agent 的执行状态广播给所有已连接的客户端------Telegram 那边显示"正在执行",WebChat 这边同步更新,两边看到的是同一个任务的同一个进度。轮询方案里,每个客户端只能各自问、各自拿,状态同步需要额外的协调层。


不可忽视的代价:断线重连

WebSocket 不是没有成本。选择持久连接,就必须认真处理"连接断了怎么办"。

移动网络切换、服务端重启、网络抖动都会导致 WebSocket 断开。一个生产可用的客户端必须实现指数退避重连,并在重连后重新同步状态:

kotlin 复制代码
class ReconnectingWebSocket {
  constructor(url) {
    this.url = url;
    this.retryDelay = 1000;   // 初始等 1s
    this.maxDelay = 30000;    // 最长等 30s
    this.connect();
  }

  connect() {
    this.ws = new WebSocket(this.url);

    this.ws.onopen = () => {
      this.retryDelay = 1000; // 连上了,重置退避计时
    };

    this.ws.onclose = () => {
      setTimeout(() => {
        this.retryDelay = Math.min(this.retryDelay * 2, this.maxDelay);
        this.connect();
      }, this.retryDelay);
    };

    this.ws.onmessage = ({ data }) => {
      this.handleMessage(JSON.parse(data));
    };
  }
}

OpenClaw 本地运行的场景下,这个问题相对简单------主要是 Gateway 重启。但如果通过 Tailscale Funnel 把 Gateway 暴露到公网,移动客户端就必须把断线重连做扎实。


小结:不是"WebSocket 更好",而是"Agent 模型需要它"

短轮询 长轮询 WebSocket
服务端主动推 ✗ △ 模拟 ✓ 原生
流式中间状态 ✗ ✗ ✓
双向通信 ✗ ✗ ✓
多客户端广播 需要额外层 需要额外层 原生支持
连接开销 高(每次重建) 中 低(一次握手)
OpenClaw 用在哪 不用 Telegram 通道 CLI / WebChat / App

OpenClaw 的选择不是"WebSocket 在所有场景都比轮询好"------Telegram 通道至今用的还是 long polling,因为那个场景下零配置比低延迟更重要。技术选型从来不是找最优解,而是找最匹配约束的解。Agent 的流式推理、双向交互、多客户端同步这三个约束加在一起,WebSocket 是唯一能同时满足的方案。

相关推荐
怕浪猫4 小时前
外包和大厂的前端代码,差在凌晨三点
前端·面试·github
十年Java程序媛11 小时前
Java this 与 super 详解|继承高频踩坑 + 面试题整理
java·spring boot·面试
萧瑟余晖11 小时前
Spring Cloud配置中心与动态刷新详解
spring cloud·面试
白露与泡影12 小时前
一线 Java 后端面试八股(2026 更新版,含完整答案)
java·开发语言·面试
学到老活到老17 小时前
集合换成线程安全的,就不用加锁了吗?
java·面试
萧瑟余晖18 小时前
Spring Cloud Alibaba生态整合详解
spring·spring cloud·面试
Sailing20 小时前
【封闭结束2】Agent 意图识别:从语义理解到稳定路由
人工智能·面试·agent
Sailing20 小时前
【封闭结束1】端到端交付:Agent 一次请求如何走完全链路
人工智能·面试·agent
怕浪猫1 天前
红利窗口开着,程序员别在场边囤课
面试·github·ai编程
lll23526917791 天前
HR如何快速整理面试沟通内容?
面试·职场和发展