1.我们来聊聊这个聊天助手。它最吸引人的特点之一就是像真人聊天一样,答案一个字一个字地蹦出来。这种‘流式响应’或‘打字机效果’,在技术上是如何实现的?
我先从整体的流程说起:当前端用户开始一次对话时,浏览器会通过 WebSocket 与后端建立一个长连接。这是一种双向的、长时间保持的连接,非常适合实时交互的场景,比如流式响应、打字机效果。
一旦用户在前端发出提问,这个消息就会通过 WebSocket 通道发送到后端。后端接收到消息后会去调用知识库去做一次混合检索,找出相关的文本内容后,再拼接上用户的历史上下文,构建一个完整的 Prompt。
接着去调用 DeepSeek,我们调用的是流式响应的 API。这一步是实现打字机效果的关键:我们用 Spring WebFlux 的 WebClient 作为 HTTP 客户端,在请求 LLM 的时候也以流式的方式订阅返回的数据流。也就是说,LLM 一边生成内容,一边把内容分成一小段一小段地推给我们,我们这边就一边接收一边处理。
每接收一段内容,就通过 WebSocket 立刻推送给前端。前端收到一小段字符后,就直接追加到聊天窗口中,给用户的感觉就是“打字机一点一点显示”的效果。
2.既然用到了WebSocket,那它和我们更常用的HTTP请求相比,有什么本质区别?为什么在这个场景下,必须用WebSocket?
WebSocket 能够支持服务端主动、实时地向客户端推送数据,而 HTTP 不具备这个能力。
具体来说,HTTP 是一种无状态、单向的请求-响应协议,它的工作机制决定了只能由客户端发起请求,服务端只是被动响应。哪怕我们用长轮询等手段模拟实时性,本质上还是客户端不断地问“有没有新的消息”,服务器无法主动发“有了”。
WebSocket 是一种有状态、全双工的协议,一旦连接建立,前后端就可以随时互相发送消息。在派聪明中,前端发起 WebSocket 请求建立连接后,后端就会一直监听前端的请求并保持连接。用户一旦发送请求,派聪明就会实时将 DeepSeek 返回的是流式数据通过 WebSocket 传回给前端。
总的来说,WebSocket 是我们实现流式响应和打字机效果的最佳选择,它解决了 HTTP 无法实时双向通信的问题,真正做到了后端一边接收大模型响应、一边实时推送给前端的效果。
3.WebSocket连接是长连接,它比HTTP要脆弱。如果用户的网络抖动一下,连接断了,会发生什么?你们有什么异常处理和重连机制吗?
考虑到用户可能在使用过程中遇到网络波动或者临时断网的情况...
回复