一、问题背景导购助手项目中AI 智能体的接口响应时间约 120 秒远超微信小程序的 60 秒最大超时限制wx.request 超时上限为 60s。用户在等待 AI 回复时小程序端会直接断开连接体验中断。二、方案对比方案一主方案同接口轮询单接口 randomId在原有接口基础上改造不新增独立接口。通过 randomId 参数区分首次调用和轮询调用。调用流程第一次调用不传 randomId客户端发起请求调用原有接口不携带 randomId服务端创建 AI 任务生成随机数 randomId 并存入 Redis立即返回{ randomId, status: wait, callCount: 0 }后续轮询调用携带 randomId callCount客户端携带 randomId 再次调用同一接口服务端通过 randomId 到 Redis 查询任务状态数据就绪 → 返回 { randomId, status: success, data }任务失败 → 返回 { randomId, status: faild }未就绪 → 线程 sleep(10s)再次查询- 有数据 → success仍无数据 → status: wait, callCount1callCount 超过上限如 12 次→ 直接返回 faild返回参数randomId随机数 ID标识任务status响应状态success / faild / waitcallCount当前调用次数超过上限自动中断data成功时携带的 AI 回复数据优点代码改动最小只需在原有接口新增参数判断逻辑不引入新协议纯 HTTP小程序原生支持超时可控callCount 上限直接对应最大等待时间缺点用户需等待完整结果无法流式体验服务端 sleep 占用线程资源方案二备选双接口分离init responseTrue将启动任务和查询状态拆分为两个接口职责更清晰。调用流程第一步调用 init 接口1. 客户端调用 init 接口如 /api/guide/init传入用户消息2. 服务端创建 AI 任务启动异步处理3. 返回任务标识如 taskId不等待 AI 完成第二步轮询responseTrue 接口1. 客户端反复调用 responseTrue 接口如 /api/guide/responseTrue2. 接口只返回三种状态之一true数据已就绪可以去拉取了false任务失败wait还在处理中继续轮询第三步获取数据1. 当 responseTrue 返回 true 后客户端再次调用 init 接口获取实际响应数据2. 注这里 init 接口的职责包含了「启动任务」和「获取已就绪的数据」两个功能返回参数responseTrue 接口仅返回 true / false / wait简洁明了可通过 HTTP 状态码或 JSON 体返回优点职责分离启动与状态查询解耦接口更清晰状态接口轻量只返回布尔/枚举值响应极快调用模式直观前端逻辑容易理解缺点两个接口增加维护成本仍然需要轮询体验与方案一类似方案三高级WebSocket 长连接实现最复杂但用户友好度最高。AI 边生成边推送到客户端实现打字机效果。调用流程用户进入对话页面后建立 WebSocket 连接用户发送消息服务端接手并转发给 AI 智能体流式调用AI 每生成一段内容通过 WebSocket 实时推送到小程序端小程序端逐步展示回复呈现打字机效果AI 回复结束后发送完成信号关闭或保持连接等待下一轮优点用户体验最佳实时流式输出无等待感无超时问题连接保持后不受 60s 限制可扩展支持主动推送促销、推荐商品等功能缺点实现最复杂需维护连接状态、心跳、重连逻辑小程序切后台后 WebSocket 可能断开需处理重连开发周期比前两种长适用场景当轮询方案的等待体验不满足业务需求时升级为此方案需要实时交互、流式输出的场景三、补充说明SSEServer-Sent EventsSSE 是 WebSocket 的轻量替代方案但需要注意平台兼容性。平台兼容微信小程序❌ 不适用- 小程序原生不支持 EventSource API- 小程序目前仅支持 WebSocket 进行流式数据传输Web 应用H5/PC✅ 适用- 浏览器原生支持 EventSource实现简单- 仅需 HTTP 协议无需额外依赖SSE 特点单向推送服务端 → 客户端适合 AI 对话输出场景实现比 WebSocket 简单仅 HTTP 协议浏览器自动重连不适合需要客户端→服务端实时通信的场景结论如果只接小程序优先考虑方案一/二/三WebSocket。SSE 仅作为 Web 端备选。