国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

袋鼠云數(shù)棧產品中 AI+ 實現(xiàn)原理剖析

這篇具有很好參考價值的文章主要介紹了袋鼠云數(shù)棧產品中 AI+ 實現(xiàn)原理剖析。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

我們是袋鼠云數(shù)棧 UED 團隊,致力于打造優(yōu)秀的一站式數(shù)據(jù)中臺產品。我們始終保持工匠精神,探索前端道路,為社區(qū)積累并傳播經驗價值。

本文作者:修能

生產力工具 + AI 是不可逆轉的趨勢,慢慢的大模型能力通過 AI Agent 落地的工程化能力也開始趨于成熟。作為大數(shù)據(jù)產品的數(shù)棧也必然是需要借助 AI 能力提升產品競爭力。
去年 12 月,我們在產品中上線了 AI+ 的功能,借助已經開源的大模型的能力,幫助我們探索和落地更多地應用場景。在初版 AI+ 的功能中,我們實現(xiàn)了基礎功能的通話。

SSE

在 ChatGPT 中,我們在等待大模型生成回答的時間通常不需要很久。這是因為 ChatGPT 通過 server-sent events(SSE)來實現(xiàn)將生成的部分回答通過事件流傳遞到前端。而這就讓前端不必等回答全部生成后再獲取,也就使得不需要請求等待很久。

SSE 是一種基于 HTTP 協(xié)議的單向通信機制,用于服務端向客戶端推送數(shù)據(jù)。

SSE WebSocket
基于 HTTP 協(xié)議 基于 TCP 連接,本身是一種協(xié)議
單向通信 雙向通信
簡單易用 復雜

入門使用

// 創(chuàng)建 SSE 的實例
const evtSource = new EventSource("http://api.example.com/ssedemo.php", {
  withCredentials: true,
});

// 添加監(jiān)聽事件
evtSource.onmessage = (event) => {
  const newElement = document.createElement("li");
  const eventList = document.getElementById("list");

  newElement.textContent = `message: ${event.data}`;
  eventList.appendChild(newElement);
};

// 錯誤處理
evtSource.onerror = (err) => {
  console.error("EventSource failed:", err);
};

// 關閉事件流
evtSource.close();

需要注意的是,SSE 請求的服務端響應信息頭的 MIME 類型必須是text/event-stream,否則會無法監(jiān)聽到事件。
另外,由于是基于 HTTP 協(xié)議的,所以在 HTTP/1.1 或更低的時候,會受瀏覽器最大連接數(shù)的限制。


Fields

收到的消息格式一定是具有以下字段的某種組合,其他字段名都將忽略,每行一個:

  • event
  • data
  • id
  • retry
: this is a test stream // 第一條消息,這會被解析會注釋

data: some text // 第二條消息

data: another message // 第三條消息
data: with two lines

event: userconnect // 第四條消息
data: {"username": "bobby", "time": "02:33:48"}

如上所示,默認瀏覽器的 EventSource API 雖然可用,但是限制比較多。

  1. 只支持 url 和 withCredentials 參數(shù)。不支持往 body 里傳參數(shù)。而通常來說 URL 是有最大長度限制的。
  2. 無法自定義請求頭。
  3. 只能發(fā)起 GET 請求。

其實,我們也可以通過 Fetch 來實現(xiàn) SSE 的通信,只不過需要額外自行處理數(shù)據(jù)流的傳遞。

實現(xiàn)

首先,我們借助 Fetch 的能力來實現(xiàn)請求。

const response = await fetch(url, options);

通過接受用戶提供的 url 和 options 發(fā)起一個 fetch 的請求。
然后,我們需要排除掉非 SSE 的請求類型,我們可以直接拿響應的 header 中拿 content-type進行判斷。

const contentType = response.headers.get('content-type');
if (!contentType?.startsWith('text/event-stream')) {
    throw new Error('SSE 請求必須設置 content-type 為 text/event-stream');
}

接著,我們業(yè)務場景中通常直接通過 response.json()獲取 JSON 格式的數(shù)據(jù)了,但這里我們由于是事件流,所以我們通過 response.body 拿到的是一個 ReadableStream。我們需要借助相關的 API 進行流的讀取。

const reader = response.body.getReader();
let result: ReadableStreamDefaultReadResult<Uint8Array>;
while (!(result = await reader.read()).done) {
  	// 假定每一次 read 的 value 都是完整的消息
    onmessage(onChunk(result.value));
}

其中 onChunk 函數(shù)就是處理事件流中的每一份數(shù)據(jù)的。

// 偽代碼
function onChunk(arr: Uint8Array){
  const links = seekLinks();
  // 待完善
}

在實現(xiàn) seekLinks 方法之前,我們需要先知道到什么時候算每一行的結束。


從 Fields 可以知道,每一行是以\n作為區(qū)分的。

function seekLinks(arr: Uint8Array){
  const lines = [];
  const buffer = arr;
  const bufLength = buffer.length;
  let position = 0;
  let lineStart = 0;
  while(position < bufLength){
    // '\n'.charCodeAt() === 10;
    if(buffer[position] === 10){
      lines.push(buffer.slice(lineStart, position));
      lineStart = position;
    };
    position += 1;
  }
  return lines;
}

在獲取到所有行后,針對每一行做處理。

// 偽代碼
function onChunk(arr: Uint8Array){
  const links = seekLinks();
  const decoder = new TextDecoder();
  let message = {
    data: '',
    event: '',
    id: '',
    retry: undefined,
  }:
  links.forEach((line) => {
    // ':'.charCodeAt() === 58;
    const colon = line.findIndex(l => l === 58);
    const fieldArr = line.slice(0, colon);
    const valueArr = line.slice(colon);
    if(colon === -1){
      // 當冒號作為開頭的時候,解析成注釋
      return;
    }
    const field = decoder.decode(fieldArr);
    const value = decoder.decode(valueArr);
    switch (field) {
      case 'data':
          message.data = message.data
              ? message.data + '\n' + value
              : value;
          break;
      case 'event':
          message.event = value;
          break;
      case 'id':
          message.id = value;
          break;
      case 'retry':
          const retry = parseInt(value, 10);
          message.retry = retry
          break;
  	}
  });
  return message;
}

大致完成了最簡單的基礎功能的解析,而以上偽代碼參考 fetch-event-source 的源碼。


借助 fetch-event-source 的能力,在數(shù)棧產品中調用的方式和 HTTP 請求基本保持一致。

function sse(url: string, params: any, options: FetchEventSourceInit) {
  const headers = {
    'Content-Type': 'application/json',
    accept: 'text/event-stream',
  };
  fetchEventSource(url, {
    method: 'POST',
    body: JSON.stringify(params),
    headers,
    ...options,
  });
}

打字機效果

接著,我們實現(xiàn)具備科技感的打字機效果:
袋鼠云數(shù)棧產品中 AI+ 實現(xiàn)原理剖析

輸出

這里我們不能直接將響應的消息直接打印到屏幕上,因為響應的消息通常是好多字,這樣子會導致打字機效果顯得非??D,用戶體驗不佳。
在數(shù)棧產品中,我們通過將響應的消息收集到暫存區(qū)中,然后通過每秒從暫存區(qū)中取出若干個字符打印到屏幕上,優(yōu)化打字機卡頓的效果。

function AIGC(){
   const typing = useTyping({
      // 暫存區(qū)啟動后,每個 delay 的時間都會執(zhí)行該方法將消息打印到屏幕上
      onTyping(val) {
        // ...
      },
  });
	const handleChat = (message: string) => {
      // 標志暫存區(qū)需要開始存響應的消息了
      typing.start();
      requestChat(params, {
        onmessage(event: { data: string }) {
           	const { data } = event;
            // 把響應的消息存入暫存區(qū)中
            typing.push(data);
        },
        onclose() {
            // 關閉或失敗的話,釋放暫存區(qū)的數(shù)據(jù)
            typing.close();
        },
        onerror() {
            typing.close();
        },
    });
  };
}

其中,相關暫存區(qū)的代碼整理成 useTyping 實現(xiàn)。

export default function useTyping({
    onTyping,
    onEnd,
}: {
    onTyping: (val: string) => void;
    onEnd: () => void;
}) {
    const interval = useRef<number>();
    const queue = useRef<string>('');
    const isStart = useRef<boolean>(false);

    function startTyping() {
        if (interval.current) return;
        let index = 0;
        interval.current = window.setInterval(() => {
            if (index < queue.current.length) {
                const str = queue.current;
                onTyping(str.slice(0, index + 1));
                index++;
            } else if (!isStart.current) {
                // 如果發(fā)送了全部的消息且信號關閉,則清空隊列
                window.clearInterval(interval.current);
                interval.current = 0;
                onEnd();
            }
            // 如果發(fā)送了全部的消息,但是信號沒有關閉,則什么都不做繼續(xù)輪訓等待新的消息
        }, 50);
    }

    useEffect(() => {
        return () => {
            window.clearInterval(interval.current);
            interval.current = 0;
        };
    }, []);

    function start() {
        isStart.current = true;
        window.clearInterval(interval.current);
        interval.current = 0;
        queue.current = '';
    }

    function push(str: string) {
        if (!isStart.current) return;
        queue.current += str.replace(/\\n/g, '\n');
        startTyping();
    }

    // 關閉的時候不需要清空隊列,因為可能還有一些消息沒有發(fā)送完畢,統(tǒng)一等消息發(fā)送完畢后關閉
    function close() {
        isStart.current = false;
    }

    return { start, push, close };
}

光標

在實現(xiàn)了打字機效果后,我們還需要添加一個閃爍的光標。
原理比較簡單,就是在消息區(qū)域的最后一個元素的末尾添加元素即可。

.markdown {
  >*:last-child::after {
    content: " ";
    width: 2px;
    height: 13px;
    transform: translate(1px, 2px);
    font-family: Menlo, Monaco, "Courier New", monospace;
    font-weight: normal;
    font-size: 0;
    font-feature-settings: "liga" 0, "calt" 0;
    line-height: 13px;
    letter-spacing: 0;
    display: inline-block;
    visibility: hidden;
    animation: blinker 1s step-end infinite;
    background: #000;
  }

  @keyframes blinker {
    0% {
      visibility: inherit;
    }
    50% {
      visibility: hidden;
    }
    100% {
      visibility: inherit;
    }
  }
}

當然,這里有一些問題,在 markdown 解析出 Code Block 的時候會導致光標錯位,這個問題 ChatGPT 同樣也有。
袋鼠云數(shù)棧產品中 AI+ 實現(xiàn)原理剖析


那么到這里,我們就實現(xiàn)了一個具備基礎功能的 AI+ 的需求。

最后

歡迎關注【袋鼠云數(shù)棧UED團隊】~
袋鼠云數(shù)棧 UED 團隊持續(xù)為廣大開發(fā)者分享技術成果,相繼參與開源了歡迎 star文章來源地址http://www.zghlxwxcb.cn/news/detail-824272.html

  • 大數(shù)據(jù)分布式任務調度系統(tǒng)——Taier
  • 輕量級的 Web IDE UI 框架——Molecule
  • 針對大數(shù)據(jù)領域的 SQL Parser 項目——dt-sql-parser
  • 袋鼠云數(shù)棧前端團隊代碼評審工程實踐文檔——code-review-practices
  • 一個速度更快、配置更靈活、使用更簡單的模塊打包器——ko
  • 一個針對 antd 的組件測試工具庫——ant-design-testing

到了這里,關于袋鼠云數(shù)棧產品中 AI+ 實現(xiàn)原理剖析的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 實戰(zhàn)干貨|Spark 在袋鼠云數(shù)棧的深度探索與實踐

    實戰(zhàn)干貨|Spark 在袋鼠云數(shù)棧的深度探索與實踐

    Spark 是一個快速、通用、可擴展的大數(shù)據(jù)計算引擎,具有高性能、易用、容錯、可以與 Hadoop 生態(tài)無縫集成、社區(qū)活躍度高等優(yōu)點。在實際使用中,具有廣泛的應用場景: · 數(shù)據(jù)清洗和預處理:在大數(shù)據(jù)分析場景下,數(shù)據(jù)通常需要進行清洗和預處理操作以確保數(shù)據(jù)質量和一致

    2024年04月26日
    瀏覽(26)
  • 袋鼠云數(shù)棧前端從 Multirepo 到 Monorepo 研發(fā)效率提升探索之路

    袋鼠云數(shù)棧前端從 Multirepo 到 Monorepo 研發(fā)效率提升探索之路

    我們是袋鼠云數(shù)棧 UED 團隊,致力于打造優(yōu)秀的一站式數(shù)據(jù)中臺產品。我們始終保持工匠精神,探索前端道路,為社區(qū)積累并傳播經驗價值。 本文作者:星野 前端代碼管理一直是困擾著不少前端開發(fā)團隊的難題,從開發(fā)到發(fā)布的整體工作流程中,除了常規(guī)的技術問題外,往往

    2024年02月04日
    瀏覽(23)
  • 性能提升30%!袋鼠云數(shù)?;?Apache Hudi 的性能優(yōu)化實戰(zhàn)解析

    性能提升30%!袋鼠云數(shù)?;?Apache Hudi 的性能優(yōu)化實戰(zhàn)解析

    Apache Hudi 是一款開源的數(shù)據(jù)湖解決方案,它能夠幫助企業(yè)更好地管理和分析海量數(shù)據(jù),支持高效的數(shù)據(jù)更新和查詢。并提供多種數(shù)據(jù)壓縮和存儲格式以及索引功能,從而為企業(yè)數(shù)據(jù)倉庫實踐提供更加靈活和高效的數(shù)據(jù)處理方式。 在金融領域,企業(yè)可以使用 Hudi 來處理大量需要

    2024年02月09日
    瀏覽(22)
  • 袋鼠云數(shù)棧UI5.0設計實戰(zhàn)|B端表單這樣設計,不僅美觀還提效

    袋鼠云數(shù)棧UI5.0設計實戰(zhàn)|B端表單這樣設計,不僅美觀還提效

    我們是袋鼠云數(shù)棧 UED 團隊,致力于打造優(yōu)秀的一站式數(shù)據(jù)中臺產品。我們始終保持工匠精神,探索前端道路,為社區(qū)積累并傳播經驗價值。 本文作者:大喜 相關文章:袋鼠云出品!數(shù)棧UI 5.0全新體驗升級,設計背后的故事 表單是B端產品中最常見的組件之一,主要?于數(shù)據(jù)

    2024年02月03日
    瀏覽(24)
  • 袋鼠云產品功能更新報告05期|應有盡“優(yōu)”,數(shù)棧一大波功能優(yōu)化升級!

    袋鼠云產品功能更新報告05期|應有盡“優(yōu)”,數(shù)棧一大波功能優(yōu)化升級!

    這段時間,我們對產品本身以及客戶反饋的一些問題進行了持續(xù)的更新和優(yōu)化,包括對離線平臺數(shù)據(jù)同步功能的更新,數(shù)據(jù)資產平臺血緣問題的優(yōu)化等,力求滿足不同行業(yè)用戶的更多需求,為用戶帶來極致的產品使用體驗。 以下為袋鼠云產品功能更新報告第五期內容,更多探

    2024年02月04日
    瀏覽(42)
  • 深度剖析SpringBoot自動配置原理,為什么SpringBoot能為我們做那么多東西

    深度剖析SpringBoot自動配置原理,為什么SpringBoot能為我們做那么多東西

    本文基于 spring-boot-2.2.6.RELEASE 版本的源碼進行說明,不同版本的源碼可能會有一些區(qū)別。 要清楚SpringBoot自動配置原理,就要明白 @SpringBootApplication 注解的組成,此注解主要是這三個注解組成: @SpringBootConfiguration , @EnableAutoConfiguration , @ComponentScan 。 下面是源碼: @SpringBo

    2024年02月13日
    瀏覽(23)
  • 數(shù)棧產品中的代碼編譯器

    數(shù)棧產品中的代碼編譯器

    我們是袋鼠云數(shù)棧 UED 團隊,致力于打造優(yōu)秀的一站式數(shù)據(jù)中臺產品。我們始終保持工匠精神,探索前端道路,為社區(qū)積累并傳播經驗價值。 本文作者:奇銘 目前數(shù)棧的多個產品中都支持在線編輯 SQL 來生成對應的任務。比如離線開發(fā)產品和實時開發(fā)產品。在使用 MonacoEdito

    2024年02月05日
    瀏覽(25)
  • 數(shù)棧V6.0全新產品矩陣發(fā)布,數(shù)據(jù)底座 EasyMR 煥新升級

    數(shù)棧V6.0全新產品矩陣發(fā)布,數(shù)據(jù)底座 EasyMR 煥新升級

    4月20日,袋鼠云成功舉行了以“數(shù)實融合,韌性生長”為主題的2023春季生長大會。會上,袋鼠云自主研發(fā)的一站式大數(shù)據(jù)基礎軟件——數(shù)棧V6.0產品矩陣全新發(fā)布。對旗下大數(shù)據(jù)基礎平臺、大數(shù)據(jù)開發(fā)與治理、數(shù)據(jù)智能分析與洞察三大模塊的全線產品進行全新升級,并重點發(fā)

    2023年04月27日
    瀏覽(28)
  • 袋鼠云春季生長大會最新議程來啦!4月20日我們云上見

    袋鼠云春季生長大會最新議程來啦!4月20日我們云上見

    如今,數(shù)字經濟正逐步走向深化應用、規(guī)范發(fā)展、普惠共享的新階段,數(shù)字經濟與實體經濟深度融合、基礎軟件國產化替代成為數(shù)字時代主潮流。數(shù)字工具如何讓千行百業(yè)共同實現(xiàn)韌性生長? 「 2023 袋鼠云春季生長大會」乘風而起,帶來數(shù)實融合趨勢下的產品煥新升級剖析、

    2023年04月17日
    瀏覽(23)
  • 袋鼠云產品功能更新報告07期|智能、高效、安全,一個都不能少!

    袋鼠云產品功能更新報告07期|智能、高效、安全,一個都不能少!

    歡迎來到袋鼠云07期產品功能更新報告!在瞬息萬變的市場環(huán)境中,袋鼠云始終將客戶需求和反饋置于優(yōu)化工作的核心位置,本期也針對性地推出了一系列實用性強的功能優(yōu)化,以滿足客戶日益增長的業(yè)務需求。 以下為袋鼠云產品功能更新報告07期內容,更多探索,請繼續(xù)閱

    2024年02月08日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包