实时性是智能客服体验的生命线。客户发消息后 30 秒没收到回复,就开始怀疑对面没人;1 分钟没回复,就去找别家了。但很多人对"实时"有个误解:以为只要机器人回复快就够了。真实的实时客服系统是 端到端 的实时——从客户发消息那一刻,到你后端 AI 处理完、消息推到客服工作台、客服接管操作,每一环都要快。这篇把基于 Eyun 企业微信 API 搭建实时智能客服机器人涉及的两条实时通道讲清楚,重点聊聊 WebSocket 在其中的角色。

一、实时的两个层次

很多团队只盯着一个方向做实时:客户到机器人那一段。但完整的实时链路是两段:

客户 ←→ 平台 ←→ 你的后端服务 ←→ 客服工作台(前端)
         [回调通道]              [推送通道]

回调通道(平台到你的后端):Eyun 通过 Webhook 把客户消息推给你,亚秒级。这一段是平台侧的实时性,不用你操心,做好接收就行。

推送通道(你的后端到客服工作台):消息进了你的后端之后,要实时推到客服正在用的 Web 工作台,让客服立刻看到、能接管。这一段就要你自己搭,大多数人栽的就是这里。

传统做法是前端轮询——每 2 秒问一次"有新消息吗?"。看起来挺快,实际坑一堆:没消息时也在刷接口、有消息要等下一次轮询才能拿到、多人同时轮询数据库扛不住。WebSocket 才是这一段的正确解法。

二、为什么 WebSocket 比轮询强

不是 WebSocket 多炫,是轮询的代价随规模指数级恶化:

维度

轮询(2秒一次)

WebSocket

100 个客服同时在线

50 QPS 持续打数据库

100 个长连接,无业务请求

消息延迟

平均 1 秒,最差 2 秒

毫秒级推送

服务器资源

每个请求都要建连、解析、查库

一条长连接复用

空闲时开销

持续轮询消耗

几乎为零

突发消息处理

串行处理积压

一条消息一次推送

100 个客服在线时差距已经很明显,到 500 个客服时轮询基本不可用。WebSocket 把"主动询问"变成"被动接收",从根本上消除无效请求。

三、WebSocket 通道要传什么

新手最容易的错把 WebSocket 当成"消息推送专用通道",只推消息正文。实际上工作台需要实时同步的信息种类很多:

消息类型

触发时机

内容

新客户消息

回调收到客户消息

完整消息对象

客户输入中

客户正在打字

客户ID + 状态

已读回执

客户看了你的消息

会话ID + 时间

会话状态变更

转人工、超时、改派

会话ID + 新状态

客户上下线

客户上线/离线

客户ID + 状态

群成员变更

拉人、踢人、退群

群ID + 变更详情

系统通知

任务、审批、告警

通知内容

AI 处理进度

AI 正在分析、已生成回复

会话ID + 进度

这些信息按"会话维度"和"客服维度"分通道推送:

  • 会话维度的事件推给"当前正在处理这个会话的客服"。

  • 客服维度的事件(比如分配给你的新工单、你的客户超时了)推给该客服个人。

推送时要带 traceId,把 WebSocket 推送和后端处理链路串起来,方便排查"客户发消息后客服为什么 5 秒才看到"这种延迟问题。

四、WebSocket 服务端的工程设计

WebSocket 看起来就是"建个长连接推消息",工程上要稳定运行有不少细节:

连接管理:每个客服一个长连接,连接上时要登记"这个连接属于哪个客服"。后端事件来了,按客服 ID 找到对应连接推送。客服切换账号、关闭浏览器、网络抖动都要处理——断线要自动重连、重连后状态要恢复。

连接路由:多机部署时,客服 A 的连接在服务器 1 上,事件产生在服务器 2 上怎么办?需要一个 发布订阅通道(Redis Pub/Sub 或消息队列)做跨机路由:服务器 2 把事件发到频道,所有 WebSocket 服务器订阅该频道,谁持有对应连接谁推送。

心跳保活:长连接长时间没数据时会被中间网络设备断开。客户端每 30 秒发一个 ping,服务端回 pong,确认连接还活着。心跳也是检测"客服关了浏览器但没正常断连"的手段——多次 ping 无响应就主动关闭连接释放资源。

消息有序性:同一会话的多条消息要按顺序到达。WebSocket 单连接上消息本身有序,但跨多机、多事件源时要小心——后端要把同一会话的事件串行推送到同一连接,不能并行(避免"客户已读"比"客户消息"先到,逻辑就乱了)。

断线补偿:客服网络断了 30 秒重连,这期间的消息不能丢。后端要保存"未确认推送"队列,重连后把积压消息按顺序补发。或者更简单——重连后客户端主动调一次"拉取最近消息"接口补齐。

五、把 WebSocket 和回调链路串起来

完整的实时链路是这样跑的:

1. 客户发消息(企微客户端)
2. Eyun 平台推送回调到你后端的 Webhook 端点
3. Webhook 端点快速验签、幂等检查、写入消息队列、返回 2xx
4. 消息处理 worker 消费队列:解析消息、识别意图、调 AI 生成回复
5. 处理结果通过 WebSocket 推送给客服工作台
6. 客服在工作台看到消息和 AI 建议的回复
7. 客服确认发送 → 后端调 Eyun 的 sendText 接口
8. 发送结果通过 WebSocket 回推给客服工作台(消息已发出)

每一步都要监控延迟。常见瓶颈是第 4 步——AI 处理慢。这时 WebSocket 反而有用:先给客服推一条"AI 正在处理",让客服知道消息到了、AI 在动,比干等 3 秒什么都看不到的体验好得多。实时性不只是"快",还包括"让用户知道系统在动"。

六、AI 实时回复的特殊处理

机器人自动回复的实时链路有几个特殊设计:

流式输出:LLM 生成回复时支持流式输出,每个 token 生成完就通过 WebSocket 推给工作台显示,客户那边等发送时机成熟再统一发出去。客服看到机器人"打字"过程,能在生成到一半就发现方向不对,及时打断。

多候选并行:高价值场景让 AI 并行生成 2-3 个候选回复,全部实时推给客服,客服选一个发。比单候选慢一点但质量更高。

接管信号:客服看 AI 生成的回复不满意,随时可以打断、改写、自己重写。这个"打断"信号要通过 WebSocket 反向发给后端,后端立即停止 AI 后续生成。

回复预览:AI 生成的内容先以"草稿"形式显示给客服,客服确认后才真正调发送接口。这一步把"AI 生成"和"消息发出"解耦,避免 AI 失误直接发给客户。

七、性能与稳定性

WebSocket 服务比 HTTP 服务脆弱:一条连接出问题影响一个客服,不像 HTTP 请求独立。稳定性要做几件事:

连接数监控:实时连接数、每客服平均推送量、断线重连率。断线率高说明网络或客户端有问题。

推送延迟监控:从后端事件产生到 WebSocket 推送完成的时间,P95 应在 100ms 内。延迟突然变高通常是订阅通道拥堵或服务器 GC 抖动。

慢消费者保护:客户端处理慢(比如客服浏览器卡了)会导致推送积压。服务端要设上限,积压超阈值直接断开连接让客户端重连,避免一条慢连接拖垮服务器。

优雅停机:服务发版时不能粗暴断开所有连接。要先停止接收新连接、给现有连接发"服务即将重启"通知、等连接逐步迁移到新版本、最后才真正关闭。这一步不做,每次发版客服都要被踢一次。

八、安全:长连接不是法外之地

WebSocket 长连接同样要防:

  • 鉴权:连接建立时带 token 验证身份,不验证的连接直接拒绝。

  • 来源校验:只接受自家工作台域名的连接,防止 CSRF 式的跨站连接。

  • 消息签名:高敏感操作(改派会话、外发消息)的推送带签名,防止客户端被劫持后伪造指令。

  • wss 加密:必须用 wss 而非 ws,长连接传输的所有数据都要加密。

写在最后

Eyun 企业微信 API 平台 把平台到后端的实时性做好了,但后端到客服工作台这一段的实时性要自己搭。用 WebSocket 替代轮询是这一段的标准解法,难点不在协议本身,在连接管理、跨机路由、心跳保活、断线补偿、慢消费者保护、AI 流式推送这些工程细节。把这套做扎实,客服的实时体验才能真正立起来——客户发消息的瞬间,对面就能动起来,这才是"实时智能客服"四个字该有的样子。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐