在看chatgpt的演示时留意到ai会逐字回复,当时就好奇是什么做到的?只是前端效果吗?
后来打算接下openai的api,自己也做个chat,看到文档里有个参数可以启用服务端推流(Server Sent Event)才明白过来。
但前端怎么处理SSE呢?
查了一下有JS有 EventSource,但只支持GET请求,不行。
用fetch试了下,会返回一个ReadableStream。查了下资料,ReadableStream貌似可以实时转换接收到的数据,整理如下:
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization':''
},
body: JSON.stringify({
model: 'gpt-3.5-turbo',
messages: [],
stream: true
})
})
const reader = response.body.getReader()
const decoder = new TextDecoder()
let packed
while (!(packed = await reader.read()).done) {
let result = decoder.decode(packed.value) // uint8array转字符串
const lines = result.trim().split("\n\n") // 拆分返回的行
for (let i in lines) {
let line = lines[i].substring(6) // 去掉开头的 data:
if (line === '[DONE]') { // 结束
break
}
let data = JSON.parse(line)
let delta = data['choices'][0]['delta']
// 后面就是自己的业务逻辑了...
}
}