我构建了一个流式 AI 聊天客户端,且没有让自己抓狂
我想构建一个 AI 能够实时响应的聊天界面。我想要那种平滑的打字机效果。
这比我想象中要难。问题不在于 AI,而在于 API 与浏览器之间的传输链路。
我尝试了三种不同的方法来解决这个问题。
等待法 我调用 API 并等待完整响应返回后再进行显示。这虽然可行,但 UI 会冻结几秒钟。用户会以为应用坏了,然后反复点击“发送”。这是一种很糟糕的用户体验。
轮询法 我曾考虑让服务器发送一个任务 ID,然后客户端每秒请求一次更新。这需要繁重的服务器管理。更新会以随机的分块形式出现,不够平滑。
WebSocket 法 我尝试了 Socket.IO。这增加了巨大的复杂性。我必须处理重连、心跳检测和状态同步。对于一个简单的聊天应用来说,WebSocket 显得大材小用了。
解决方案其实更简单:Server-Sent Events (SSE)。
大多数 AI API 已经通过 HTTP 使用 SSE 发送响应。我不再寻找复杂的工具,而是使用了原生的 fetch API。
通过使用 response.body.getReader(),我直接读取字节流。我自己解析了 SSE 协议。这种方法既能保持 UI 的响应性,又使用了标准的 HTTP。
为什么这种方法有效:
- 不需要 WebSocket 服务器。
- 不需要复杂的重连逻辑。
- 适用于任何支持 SSE 的 API。
- 可以使用
AbortController轻松停止流。
也有权衡之处。
- 如果没有请求,你就无法向客户端推送更新。
- 如果连接中断,你会丢失部分响应。
如果你要构建聊天应用,除非需要双向通信,否则请避开 WebSockets。坚持使用 HTTP 流式传输。它更简单,也更可靠。
你的流式传输策略是什么?你使用的是 WebSockets 还是 SSE?在评论区告诉我吧。
来源:https://dev.to/__c1b9e06dc90a7e0a676b/i-built-a-streaming-ai-chat-client-without-losing-my-mind-3gi0