lemooljiang avatar

使用推流(streaming)让ChatGPT更丝滑 / ai #7

lemooljiang

Published: 14 Mar 2023 › Updated: 14 Mar 2023使用推流(streaming)让ChatGPT更丝滑 / ai #7

使用推流(streaming)让ChatGPT更丝滑 / ai #7

https://ai.ilark.io

对比ChatGPT接受数据的方法是逐字逐字地传输,它得到第一个字就开始输出,这让用户体验更佳。相比,得到全部结果再一次输出,虽然时间都一样,但等待还是太煎熬了!一边输出一边看,这才是最佳打开方式嘛。

这种边看边输的方式其实就是现在的推流(streaming)模式,像现在的视频站、直播等,肯定都是用的数据流,都是边看边播的。ChatGPT API也是可以实现同样的功能的。

服务器端实现

//nodejs

try {
    res.setHeader('Cache-Control', 'no-cache')
    res.setHeader('Content-Type', 'text/event-stream')
    res.setHeader('Access-Control-Allow-Origin', '*')
    res.setHeader('Connection', 'keep-alive')
    res.flushHeaders() // flush the headers to establish SSE with client

    const response = openai.createChatCompletion({
      model: "gpt-3.5-turbo",
      messages: query,
      max_tokens: 3000,
      temperature: 0.2,
      stream: true,    //推流模式打开
    }, { responseType: 'stream' })

    response.then(resp => {
      resp.data.on('data', data => {
          const lines = data.toString().split('\n').filter(line => line.trim() !== '')
          for (const line of lines) {
              const message = line.replace(/^data: /, '')
              if (message === '[DONE]') {
                // console.log(996, "done")
                  res.end()
                  return
              }
              let strTemp = getReg(message)
              if(strTemp != null){
                // console.log(1188, "strTemp", strTemp)
                res.write(strTemp)
              }
          }
      })
    })
  }

用户端

//浏览器

let query = [{role: "user", content: data.get('prompt')}]
let dataObj = {
     method: 'POST',
     headers: {
          'Content-Type': 'application/json',
     },
     body: JSON.stringify({
          query: query,
          })
}

const response = await fetch(url, dataObj)
let that = this
messageDiv.innerHTML = " "
if (response.ok) {  
let i = 0
let getStream = function (reader) {
     return reader.read().then(function (result) {
          // 如果数据已经读取完毕,直接返回
          if (result.done) {
               console.log(889, "result done")
               that.clickFlag = false
               clearInterval(loadInterval)  
               loading.textContent = ''
               return
          }
          // 取出本段数据(二进制格式)
          let chunk = result.value
          let text = that.utf8ArrayToStr(chunk)
          if(i === 0){
               text = text.replace(/\\n/g,'')  //去除首段换行
          } else{
               text = text.replace(/\\n/g,'
'
) } // console.log(5667, "i", i, text) // 将本段数据追加到网页之中 messageDiv.innerHTML += text i ++ // 递归处理下一段数据 return getStream(reader) }) } getStream(response.body.getReader())

用户端方面是折腾了许久,用axios尝试了半天 ,也是没搞定。用fetch也是尝试了半天,才发现可行。然后是慢慢完善,几天时间竟然就这样过去了!

折腾的结果还不赖,现在AI·Joe流畅了不少,再接再励,慢慢完善。

Leave 使用推流(streaming)让ChatGPT更丝滑 / ai #7 to:

Written by

Designer , Poet , Technology enthusiasts

Read more #cn posts


Best Posts From lemooljiang

We have not curated any of lemooljiang's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.

More Posts From lemooljiang