fetcheventsource在大模型流式输出应用
先讲讲这个微软开发的可以使用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 中引入的一个功能,它允许开发者以一种更简单和高效的方式处理 http 请求和响应。
这个功能是作为 asp.net core 的一部分提供的,它利用了 system.net.http.desktop
命名空间中的 fetchresult
类型。
在 asp.net core 中,fetcheventsource
通常用于处理服务器发送的事件(server-sent events,sse),这是一种允许服务器向客户端异步推送实时数据的技术。
使用 fetcheventsource
,开发者可以更容易地创建和消费这些实时数据流。
使用 fetcheventsource 的一些关键点
- 创建 eventsource 客户端:开发者可以通过
fetcheventsource
创建一个eventsource
对象,该对象用于连接到服务器上的特定端点。 - 监听事件:一旦
eventsource
对象被创建,就可以通过注册事件监听器来监听服务器发送的事件。 - 处理连接:
eventsource
对象可以处理连接的建立、重连和关闭,以及可能出现的错误。 - 接收数据:当服务器向客户端推送数据时,可以通过注册的事件监听器接收这些数据。
- 断线重连:如果连接丢失,
eventsource
对象可以自动尝试重新连接到服务器。 - 取消订阅:开发者可以取消对特定事件的订阅,或者完全关闭
eventsource
连接。
以调用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; // 将内容添加到输出中 } }, 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; // 将内容添加到输出中 } }
- 事件处理器声明:
onmessage: (event) => { // ... },
这里定义了一个 onmessage
事件处理器。
当通过 sse 连接接收到消息时,会触发这个处理器。
- 解析接收到的数据:
const data = json.parse(event.data);
event.data
包含了服务器发送的消息内容,通常是以 json 格式的字符串。
json.parse
函数用于将这个 json 字符串解析为 javascript 对象。
- 检查输出数据:
if (data.output && data.output.choices) { // ... }
这里使用 if
语句来确保 data
对象中存在 output
属性,并且 output
属性中存在 choices
数组。
这是一种防御性编程的做法,用来避免在数据结构不完整时出现错误。
- 获取消息内容:
const content = data.output.choices[0].message.content;
这行代码进一步从 choices
数组中的第一个元素(通常是最相关的或者默认的消息)中提取 message.content
。
这通常是服务器推送的有用信息或数据。
- 累加内容:
this.output += content;
this.output
是 vue 组件实例的一个数据属性,用于累积从服务器接收到的所有消息内容。
这里使用 +=
操作符将新接收到的 content
追加到 this.output
的当前值上。
整个 onmessage
事件处理器的作用是:当通过 sse 接收到消息时,它将解析消息内容,从中提取有用的信息,并将其追加到 vue 组件的 output
数据属性中。
这样,组件的模板中的 <pre>{{ output }}</pre>
就可以显示所有接收到的消息内容,保持其原始的格式。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论