AI 回复如何使用慢慢打印实现更好的用户体验
最近 AI 产品蓬勃发展,人工智能正在被广泛应用,在使用这些工具的过程中,我发现了一个有意思的细节:AI 回复页面上会采用慢慢打印的方式,一个字一个字地出现在屏幕上,这样就可以获得更好的用户体验。因此,本文将介绍 AI 回复如何采用慢慢打印的方式实现更好的用户体验。
服务端实现
使用 SseEmitter
来发送 SSE 响应。在该例中,通过创建一个新的线程来异步发送事件数据给客户端。在循环中,每隔 200ms 发送一个包含当前时间的事件数据。emitter.send(SseEmitter.event().data(event))
用于发送事件数据。最后,通过调用 emitter.complete()
来标记事件发送的完成:
@Slf4j
@RequestMapping("/biz/chat")
@RestController
public class ChatController {
@Data
static class ChatBo {
private String prompt;
}
@PostMapping(value = "/completions", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter completions(@RequestBody ChatBo bo) {
log.info("message: {}", bo);
SseEmitter emitter = new SseEmitter();
// 异步方式发送事件数据
new Thread(() -> {
try {
for (int i = 0; i < 50; i++) {
String event = "Event data: " + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
emitter.send(SseEmitter.event().data(event));
Thread.sleep(200);
}
emitter.complete(); // 完成事件发送
} catch (Exception e) {
emitter.completeWithError(e); // 发送错误信息
}
}).start();
return emitter;
}
}
客户端实现
通过 fetch
发起 text/event-stream
请求,并使用 response.body.getReader()
获取响应流的阅读器,然后使用 TextDecoder
对响应流进行解码:
fetch('/api/biz/chat/completions', {
method: 'POST',
headers: {
Accept: 'text/event-stream',
'Content-Type': 'application/json',
Authorization: `Bearer ${getToken()}`,
},
body: JSON.stringify({
prompt: '你好',
}),
}).then((response) => {
const reader = response.body.getReader();
const decoder = new TextDecoder('UTF-8');
const processStream = (result) => {
if (result.done) {
return;
}
const chunk = decoder.decode(result.value, { stream: true });
console.log(chunk);
reader.read().then(processStream);
};
reader.read().then(processStream);
}).catch((error) => {
console.error('Request error:', error);
});
通过使用服务端慢慢打印的方式发送事件数据,并使用客户端解码消息,就可以实现 AI 回复的慢慢打印,从而获得更好的用户体验。