Alan Hou的个人博客

如何实现ChatGPT的打字机效果

体验过 OpenAI的ChatGPT的朋友们应该都会发现交谈的内容都是一个字一个字蹦出来的,熟悉其背后原理的朋友都知道除了一些预先调校的回复实际上AI的回复都是实时生成的,或者更专业的说法应该是实时预测出来的。所以这种显示效果也是一种无奈之举,但小伙伴有没有发现其实它还蛮酷的,至少不太容易让人产生反感。

既然内容是实时生成的,那自然是后端接口实时喂数据给前端。我们一般的接口都是一次性返回所有数据,如何才能实时不断地给客户端返回数据呢?我们先来看 OpenAI官方是如何实现的?

打开控制台,可以看到核心就是下图红框中所标识的。

text/event-stream是何方神圣呢?它称为Server Sent Events (SSE),也就是服务端实时向客户端推送数据。下面我们通过 Golang 来实现服务端,首先构造一段 ChatGPT tell me a story中预先编辑的一段数据,文字比较多,方便演示:

下面使用net/http来创建接口:

客户端使用 Python 来做网络请求:

效果如下:

注:这里使用iter_lines来进行处理,因此换行存在一些问题,可通过指定delimiter参数使用其它特殊字母来处理数据的刷新。

与之对应的还有一种application/x-ndjson,ndjson是 Newline Delimited JSON的简写,顾名思义是通过换行来不断以JSON格式返回新的数据。比如我们构建一个简单的结构体和测试数据:

接下来配置路由:

同样使用Python 客户端来完成请求:

或者前端同学也可通axios来完成请求:

后端Java可通过响应式的Webflux实现:

对于流式响应我们使用 Websocket 长连接进行处理,只不过 Websocket 可同时用于双向数据传输,较多用于聊天应用,这里不再赘述。

对 ChatGPT训练感兴趣的朋友,下面附上OpenAI 联合创始人 Andrej Karpathy近期演讲State of GPT中的截图:

退出移动版