溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

微信小程序怎么實現(xiàn)類似ChatGPT的流式傳輸

發(fā)布時間:2023-03-27 09:33:39 來源:億速云 閱讀:249 作者:iii 欄目:開發(fā)技術

這篇文章主要介紹“微信小程序怎么實現(xiàn)類似ChatGPT的流式傳輸”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“微信小程序怎么實現(xiàn)類似ChatGPT的流式傳輸”文章能幫助大家解決問題。

小程序上實現(xiàn)流失傳輸

模擬ChatGPT的效果,實現(xiàn)流式傳輸,通過處理流數(shù)據(jù),實現(xiàn)打字機的效果。

微信小程序怎么實現(xiàn)類似ChatGPT的流式傳輸

什么是流式傳輸?

在解決問題之前,我們需要了解什么是流式傳輸。流式傳輸指的是將數(shù)據(jù)分成多個數(shù)據(jù)流,通過網絡傳輸,以減少網絡延遲和提高性能。在某些情況下,流式傳輸也可以用于將視頻流和音頻流傳輸?shù)娇蛻舳恕A魇絺鬏斒且环N高效的數(shù)據(jù)傳輸方式,常用于大文件下載和在線視頻播放等場景。

為什么小程序不支持流式傳輸?

盡管流式傳輸在某些情況下非常有用,但小程序目前不支持流式傳輸。主要原因是小程序的架構和限制。

小程序的開發(fā)框架提供了一個小程序的開發(fā)和調試環(huán)境。在這個環(huán)境中,小程序的代碼和資源都是打包在一個文件中的。這意味著小程序依賴此框架的環(huán)境,無法調用瀏覽器標準的API,需要框架的整體升級和支持。

此外,小程序對網絡請求的限制也是一個因素。小程序中的網絡請求必須使用微信提供的API,這些API通常只支持完整的請求和響應。這就使得小程序無法使用流式傳輸。

我的解決方案

  • 使用WebSocket協(xié)議 , WebSocket是一種網絡協(xié)議,它提供了雙向通信的功能,并且支持流式傳輸。在小程序中,我們可以使用WebSocket協(xié)議來實現(xiàn)流式傳輸?shù)墓δ堋?/p>

  • 調整數(shù)據(jù)格式 , 如果您的應用程序需要傳輸大量數(shù)據(jù),可以將數(shù)據(jù)分成更小的塊,以便小程序可以處理它們。這樣可以避免一次性傳輸過多數(shù)據(jù)而導致的問題。

  • 使用分段下載 , 分段下載是一種在下載大文件時很常用的技術。在小程序中,我們也可以使用這種技術來避免一次性下載大量數(shù)據(jù)。我們可以將數(shù)據(jù)分成多個部分,每次下載一個部分,并在所有部分下載完畢后將它們合并起來。

但這些都是常規(guī)方案,實現(xiàn)也比較麻煩,把正常的請求復雜化了。拋棄~

常規(guī)方案Axios

基礎html模式就不列舉了,axios更便捷,我很自信這個方案可行性。

重點:

  • headers 設置為流失請求

  • responseType:stream

request({
    url: '/api/prompt',
    //請求頭需要改為stream模式
    headers: {
      Accept: 'text/event-stream',
    },
    //響應類型設置stream
    responseType: 'stream',
    method: 'POST',
    data: {
      prompt: prompt,
    },
  }).then(res => {
      console.log(res)
  }).catch(err => {
    console.log(err)
  })

他們又問我要打字機效果,我的方案:接收到ArrayBuffer以后解碼數(shù)據(jù)。

.then((res) => {
  const arrayBuffer = res.data;
  const uint8Array = new Uint8Array(arrayBuffer);
  const textDecoder = new TextDecoder('utf-8');
  const text = textDecoder.decode(uint8Array);
  for (let i = 0; i < text.length; i++) {
    setTimeout(() => {
      resultText += text[i];
      console.log(resultText);
    }, i * 100);
  }
})

ok,瀏覽器沒問題,小程序調試工具沒問題,我依舊自信我的方案

微信小程序怎么實現(xiàn)類似ChatGPT的流式傳輸

但是,小程序報錯了,無法打印流數(shù)據(jù),無法支持TextDecoder方法。完犢子,顧問成瞎指揮了。

另辟蹊徑:onChunkReceived方案

微信官方文檔中提到, wx.request中支持onChunkReceived分段式傳輸

重點:

  • 小程序 wx.request 中開啟 enableChunked; text或stream

  • 當然,OpenAI接口,也要開啟 stream;

  • 解碼分段內容為string,使用其他方案代替TextDecoder

const requestTask = wx.request({
    url: '/api/prompt',
    //請求頭需要改為stream模式
    header: {
      "Transfer-Encoding": 'chunked'
    },
    timeout: 15000,
    responseType: 'text',
    method: 'POST',
    enableChunked: true,
    data: {
      prompt: prompt,
    },
  }).then(res => {
      console.log(res)
  }).catch(err => {
    console.log(err)
  })

這樣,我們就發(fā)起了流式傳輸請求,當然后端也要支持的,后面我會舉例子。

當他們執(zhí)行時,又出問題了,搞不定TextDecoder替代方案。我查了一下,好像有個方案,小不自信了。 使用"TextDecoder"替代庫,然后給出建議:

import {TextEncoder, TextDecoder} from "fastestsmallesttextencoderdecoder";
const encode = (new TextEncoder).encode;
const decode = (new TextDecoder).decode;

等了一天沒找我,哼哼,小菜一碟,完工。

這邊又來了,大佬你的方法不好使,引入執(zhí)行又又報錯了。

穩(wěn)住別慌... 試試手寫ArrayBuffer轉string方案:text-encoding 然后親自測試,搞不定就把chatgpt-plus關掉。

最終版:

let buffer=''
requestTask.onChunkReceived(function (response) {
    const arrayBuffer = response.data;
    const uint8Array = new Uint8Array(arrayBuffer);
    let text = String.fromCharCode.apply(null, uint8Array);
    buffer += text;
    full_command.value = buffer
  })

其實,第二個方案是可行的,只是我也沒時間具體看報了什么錯誤。最終使用了fromCharCode的方法,恰好可以處理,當然還一些過濾和解碼,根據(jù)業(yè)務需要寫了。

后端接口配置

后端配置教程比較多,主要是添加請求頭,支持分段傳輸?shù)姆绞健?/p>

public static function prompt($message)
    {
        $openAi = self::getOpenAI();
        header('Access-Control-Allow-Credentials: true');
        // 設置響應頭信息
        header('Transfer-Encoding: chunked');
        header('Content-Type: text/plain');
        header('Cache-Control: no-cache');
        header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
        header('Access-Control-Allow-Headers: Content-Type');
        header('Connection: keep-alive');
        $msg = "";
        $openAi->prompt([
            'messages' => $message,
            'model' => 'gpt-3.5-turbo',
            "stream" => true,
        ], function ($curl_info, $response) {
        //閉包函數(shù)處理流
            $data = [];
            $lines = explode("\n", $response);
            foreach ($lines as $line) {
                if (!str_contains($line, ':')) {
                    continue;
                }
                [$name, $value] = explode(':', $line, 2);
                if ($name == 'data') {
                    $data[] = trim($value);
                }
            }
            foreach ($data as $message) {
                if ('[DONE]' === $message) {
                    echo "0\r\n\r\n";
                } else {
                    $message = json_decode($message, true);
                    $input = $message['choices'][0]['delta']['content'] ?? '';
                    $msg .= $input;
                    echo dechex(strlen($msg)) . "\r\n" . $msg . "\r\n";
                }
            }
            ob_flush();
            flush();
            return strlen($response);
        });
    }

關于“微信小程序怎么實現(xiàn)類似ChatGPT的流式傳輸”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識,可以關注億速云行業(yè)資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI