利用FetchEventSource在大模型流式輸出的應(yīng)用方式
FetchEventSource在大模型流式輸出應(yīng)用
先講講這個微軟開發(fā)的可以使用POST的SSE的api,github鏈接:GitHub - Azure/fetch-event-source: A better API for making Event Source requests, with all the features of fetch()
FetchEventSource
是微軟在 ASP.NET Core 中引入的一個功能,它允許開發(fā)者以一種更簡單和高效的方式處理 HTTP 請求和響應(yīng)。
這個功能是作為 ASP.NET Core 的一部分提供的,它利用了 System.Net.Http.Desktop
命名空間中的 FetchResult
類型。
在 ASP.NET Core 中,FetchEventSource
通常用于處理服務(wù)器發(fā)送的事件(Server-Sent Events,SSE),這是一種允許服務(wù)器向客戶端異步推送實時數(shù)據(jù)的技術(shù)。
使用 FetchEventSource
,開發(fā)者可以更容易地創(chuàng)建和消費這些實時數(shù)據(jù)流。
使用 FetchEventSource 的一些關(guān)鍵點
- 創(chuàng)建 EventSource 客戶端:開發(fā)者可以通過
FetchEventSource
創(chuàng)建一個EventSource
對象,該對象用于連接到服務(wù)器上的特定端點。 - 監(jiān)聽事件:一旦
EventSource
對象被創(chuàng)建,就可以通過注冊事件監(jiān)聽器來監(jiān)聽服務(wù)器發(fā)送的事件。 - 處理連接:
EventSource
對象可以處理連接的建立、重連和關(guān)閉,以及可能出現(xiàn)的錯誤。 - 接收數(shù)據(jù):當(dāng)服務(wù)器向客戶端推送數(shù)據(jù)時,可以通過注冊的事件監(jiān)聽器接收這些數(shù)據(jù)。
- 斷線重連:如果連接丟失,
EventSource
對象可以自動嘗試重新連接到服務(wù)器。 - 取消訂閱:開發(fā)者可以取消對特定事件的訂閱,或者完全關(guān)閉
EventSource
連接。
以調(diào)用Qwen大模型為例
import { fetchEventSource } from '@microsoft/fetch-event-source'; export default { data() { return { output: '', apiKey: '$your-dashscope-api-key', // 替換為你的 DashScope API-KEY url: 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation', body: { model: 'qwen-turbo', input: { messages: [ { role: 'system', content: 'You are a helpful assistant.' }, { role: 'user', content: '你好' } ] }, parameters: { incremental_output: true } } }; }, methods: { async startSSE() { const headers = { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.apiKey}`, 'X-DashScope-SSE': 'enable' }; try { this.eventSource = await fetchEventSource(this.url, { method: 'POST', headers: headers, body: JSON.stringify(this.body), onopen: (response) => { if (!response.ok) { throw new Error('Server returned an error'); } }, onmessage: (event) => { const data = JSON.parse(event.data); if (data.output && data.output.choices) { const content = data.output.choices[0].message.content; this.output += content; // 將內(nèi)容添加到輸出中 } }, onerror: (err) => { console.error('EventSource failed:', err); this.stopSSE(); } }); } catch (error) { console.error('Failed to start SSE:', error); } }, stopSSE() { if (this.eventSource) { this.eventSource.close(); this.eventSource = null; } } }, unmounted() { this.stopSSE(); } };
這樣就可以建立SSE的鏈接了。
那么有小伙伴就要問了,那前端怎么實時顯示接收到的輸出呢?
onmessage: (event) => { const data = JSON.parse(event.data); if (data.output && data.output.choices) { const content = data.output.choices[0].message.content; this.output += content; // 將內(nèi)容添加到輸出中 } }
- 事件處理器聲明:
onmessage: (event) => { // ... },
這里定義了一個 onmessage
事件處理器。
當(dāng)通過 SSE 連接接收到消息時,會觸發(fā)這個處理器。
- 解析接收到的數(shù)據(jù):
const data = JSON.parse(event.data);
event.data
包含了服務(wù)器發(fā)送的消息內(nèi)容,通常是以 JSON 格式的字符串。
JSON.parse
函數(shù)用于將這個 JSON 字符串解析為 JavaScript 對象。
- 檢查輸出數(shù)據(jù):
if (data.output && data.output.choices) { // ... }
這里使用 if
語句來確保 data
對象中存在 output
屬性,并且 output
屬性中存在 choices
數(shù)組。
這是一種防御性編程的做法,用來避免在數(shù)據(jù)結(jié)構(gòu)不完整時出現(xiàn)錯誤。
- 獲取消息內(nèi)容:
const content = data.output.choices[0].message.content;
這行代碼進一步從 choices
數(shù)組中的第一個元素(通常是最相關(guān)的或者默認的消息)中提取 message.content
。
這通常是服務(wù)器推送的有用信息或數(shù)據(jù)。
- 累加內(nèi)容:
this.output += content;
this.output
是 Vue 組件實例的一個數(shù)據(jù)屬性,用于累積從服務(wù)器接收到的所有消息內(nèi)容。
這里使用 +=
操作符將新接收到的 content
追加到 this.output
的當(dāng)前值上。
整個 onmessage
事件處理器的作用是:當(dāng)通過 SSE 接收到消息時,它將解析消息內(nèi)容,從中提取有用的信息,并將其追加到 Vue 組件的 output
數(shù)據(jù)屬性中。
這樣,組件的模板中的 <pre>{{ output }}</pre>
就可以顯示所有接收到的消息內(nèi)容,保持其原始的格式。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue循環(huán)中點擊選中再點擊取消(單選)的實現(xiàn)
這篇文章主要介紹了vue循環(huán)中點擊選中再點擊取消(單選)的實現(xiàn),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09Vue父組件調(diào)用子組件函數(shù)實現(xiàn)
這篇文章主要介紹了Vue父組件調(diào)用子組件函數(shù)實現(xiàn),全文通過舉例子及代碼的形式進行了一個簡單的介紹,希望大家能夠理解并且學(xué)習(xí)到其中知識2021-08-08Vue+Element-ui彈窗?this.$alert?is?not?a?function問題
這篇文章主要介紹了Vue+Element-ui彈窗?this.$alert?is?not?a?function問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10