ProChat 如何接入 SSE

ProChat专注于快速构建大型语言模型聊天对话框框架,ProChat 作为 AI 会话的前端解决方案,自然默认集成了这项流式输出的能力。只需要在 request 中配置一个返回流式文本的 Response (Web标准的 Response 对象),就可以轻松实现流式效果的集成。
非流式读取
对于非流式的请求,只需要返回一个进过 Response 包装的 String 即可。

<ProChat
 request={async (messages) => {
 const text = await delay(
 `这是一条模拟非流式输出的消息的消息。本次会话传入了${messages.length}条消息`,
          );

 return new Response(text);
        }}
 style={{ height: '100vh' }}
 />

流式读取
Server-Sent Events(SSE)是一种让服务器能够向浏览器实时推送更新数据的技术。SSE允许服务器在事件发生时通过HTTP连接主动将数据发送到客户端,而不需要客户端发起请求。这种技术基于一个持久化的单向连接,客户端通过创建EventSource对象与服务器建立连接,并监听来自服务器的事件流。
SSE的数据格式是简单的文本格式,每条消息由数据字段承载,内容类型为text/event-stream。每个消息块遵循特定的语法,可以包含事件类型、事件ID以及自定义数据等信息。例如:

data: message1
data: message2

event: update
data: {"key": "value"}

id: 12345
data: some other data

对于流式请求处理,ProChat的核心关注点在于从返回的字节流中读取并解析内容。可以通过Reader对象来逐步读取响应流中的数据,并将其转换为所需格式的字符串信息。最终,尽管底层处理的是复杂的流式数据,但组件对外提供的接口仍简洁明了,仅暴露包含处理后内容的Stream流给上层调用者,从而实现对流式数据的有效封装与利用。

<ProChat
        request={async (messages: any) => {
          // 正常业务中如下:
          const response = await fetch('/api/chat/completion', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json;charset=UTF-8',
            },
            body: JSON.stringify({
              messages,
              stream: true,
            }),
          });
          console.log('messages', messages);

          // 确保服务器响应是成功的
          if (!response.ok || !response.body) {
            throw new Error(`HTTP error! status: ${response.status}`);
          }

          // 获取 reader
          const reader = response.body.getReader();
          const decoder = new TextDecoder('utf-8');
          const encoder = new TextEncoder();

          const readableStream = new ReadableStream({
            async start(controller) {
              function push() {
                reader
                  .read()
                  .then(({ done, value }) => {
                    if (done) {
                      controller.close();
                      return;
                    }
                    const chunk = decoder.decode(value, { stream: true });
                    const message = chunk.replace('data: ', '');
                    const parsed = JSON.parse(message);
                    controller.enqueue(encoder.encode(parsed.choices[0].delta.content));
                    push();
                  })
                  .catch((err) => {
                    console.error('读取流中的数据时发生错误', err);
                    controller.error(err);
                  });
              }
              push();
            },
          });
          return new Response(readableStream);
        }}
      />

代码中需要,数据需要通过TextEncoder再次编码,否则组件无法识别数据:
controller.enqueue(encoder.encode(parsed.choices[0].delta.content));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值