欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解微信小程序如何實(shí)現(xiàn)類似ChatGPT的流式傳輸

 更新時間:2023年03月27日 08:56:54   作者:掃地盲僧  
這篇文章主要為大家介紹了微信小程序如何實(shí)現(xiàn)類似ChatGPT的流式傳輸示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

最近指導(dǎo)群里小兄弟技術(shù)問題,發(fā)現(xiàn)一個讓我也棘手的難題。于是激發(fā)了我潛意識精神力-干到底。 由于最近沉浸在chatgpt中,很久不用google和百度搜索東西了,正如我所料一般,他們也沒有這方面的解決方案。于是,記錄一下探索研究的過程,給各位水友一個分享擴(kuò)展。

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

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

什么是流式傳輸?

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

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

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

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

此外,小程序?qū)W(wǎng)絡(luò)請求的限制也是一個因素。小程序中的網(wǎng)絡(luò)請求必須使用微信提供的API,這些API通常只支持完整的請求和響應(yīng)。這就使得小程序無法使用流式傳輸。

我的解決方案

  • 使用WebSocket協(xié)議 , WebSocket是一種網(wǎng)絡(luò)協(xié)議,它提供了雙向通信的功能,并且支持流式傳輸。在小程序中,我們可以使用WebSocket協(xié)議來實(shí)現(xiàn)流式傳輸?shù)墓δ堋?/li>
  • 調(diào)整數(shù)據(jù)格式 , 如果您的應(yīng)用程序需要傳輸大量數(shù)據(jù),可以將數(shù)據(jù)分成更小的塊,以便小程序可以處理它們。這樣可以避免一次性傳輸過多數(shù)據(jù)而導(dǎo)致的問題。
  • 使用分段下載 , 分段下載是一種在下載大文件時很常用的技術(shù)。在小程序中,我們也可以使用這種技術(shù)來避免一次性下載大量數(shù)據(jù)。我們可以將數(shù)據(jù)分成多個部分,每次下載一個部分,并在所有部分下載完畢后將它們合并起來。

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

常規(guī)方案Axios

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

重點(diǎn):

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

他們又問我要打字機(jī)效果,我的方案:接收到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,瀏覽器沒問題,小程序調(diào)試工具沒問題,我依舊自信我的方案

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

另辟蹊徑:onChunkReceived方案

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

重點(diǎn):

  • 小程序 wx.request 中開啟 enableChunked; text或stream
  • 當(dāng)然,OpenAI接口,也要開啟 stream;
  • 解碼分段內(nèi)容為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ā)起了流式傳輸請求,當(dāng)然后端也要支持的,后面我會舉例子。

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

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

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

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

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

最終版:

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
  })

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

后端接口配置

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

public static function prompt($message)
    {
        $openAi = self::getOpenAI();
        header('Access-Control-Allow-Credentials: true');
        // 設(shè)置響應(yīng)頭信息
        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);
        });
    }

至此,整個瀏覽已完成,相信有技術(shù)嗅覺的小伙伴一定會大有所用。目前,還沒有看到太多小程序支持流的平替方案,至少md格式,代碼高亮,打字效果處理成和官網(wǎng)一樣的交互,還是比較棘手的。不過可以試試這個,我用著還挺好,起碼交互上。后面還會發(fā)一個整合所有平替的分享,大家可以嫖到老。

以上就是詳解小程序如何實(shí)現(xiàn)類似ChatGPT的流式傳輸?shù)脑敿?xì)內(nèi)容,更多關(guān)于小程序ChatGPT流式傳輸?shù)馁Y料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論