chatgpt 逐字输出 使用fetch/eventSource/fetchEventSouce进行sse流式处理

在这里插入图片描述
前端使用vue

1.逐字输出 闪动css样式

<span id="response_row" class="result-streaming">{{ item.assistantContent }}</span>
.result-streaming:after {-webkit-animation: blink 1s steps(5, start) infinite;animation: blink 1s steps(5, start) infinite;content: "▋";margin-left: 0.25rem;vertical-align: baseline;
}

2.使用fetch/eventSource/fetchEventSource进行sse流式处理

先贴最后成功使用的
使用fetchEventSource方法
参考代码:https://blog.csdn.net/cuiyuchen111/article/details/129468291
参考/下载文档:https://www.npmjs.com/package/@microsoft/fetch-event-source?activeTab=readme

以下为后端接口要求
在这里插入图片描述
前端代码

<p v-if="item.requestFlag" class="content robot_content"><span id="response_row" class="result-streaming">{{ item.assistantContent }}</span></p>
<p class="content robot_content"><span v-html="item.assistantContent"></span></p>
 async getResponseFromAPI() {const that = this;this.sendLoading = true;// 用户提问时间let userTime = that.getNowTime();const form = JSON.parse(JSON.stringify(this.form));console.log(form, "请求里的form");//物理添加 页面that.conversations.push({userContentId: "",userContent: form.prompt,userContentDatetime: userTime,assistantContentId: "",assistantContent: "",assistantContentDatetime: userTime,requestFlag: true,});// 对话请求const abortController = new AbortController();let formData = new FormData();formData.append("chatid", this.currentChatId);formData.append("clientid", form.clientid);formData.append("prompt", form.prompt);const url = "xxxxx";const headers = new Headers();const body = formData;const eventSource = fetchEventSource(url, {method: "POST",headers,body,signal: abortController.signal,onmessage(e) {that.handleScrollBottom();that.form.prompt = "";const response_row = document.getElementById("response_row");console.log(e.data);let res = JSON.parse(e.data);let index = that.conversations.length - 1;if (res.message == "[DONE]") {res.data = JSON.parse(res.data);console.log(res.data);let obj = {userContentId: res.data.userContentId,userContent: res.data.userContent,userContentDatetime: userTime,assistantContentId: res.data.assistantContentId,assistantContent: res.data.assistantContent,assistantContentDatetime: that.getNowTime(),requestFlag: false,};console.log(obj);that.$set(that.conversations, index, obj);that.sendLoading = false;abortController.abort();eventSource.close();console.log("我是结束!!");} else {var content = res.data;response_row.innerText += content;// console.log(content)// if (content.includes("[ENTRY]")) {//   content = content.replaceAll("[ENTRY]", "\n");// }}},onclose() {console.log("close");that.sendLoading = false;abortController.abort();eventSource.close();},onerror(error) {let index = that.conversations.length - 1;that.conversations.splice(index, 1);that.sendLoading = false;console.log("error", error);abortController.abort();eventSource.close();},});}

遇到的问题:
1.只调用一次事件 但fetch请求发送了两次或多次且终止失败

//按照fetchEventSource文档内的写法 请求暂停无效
const ctrl = new AbortController();
fetchEventSource('/api/sse', {method: 'POST',headers: {'Content-Type': 'application/json',},body: JSON.stringify({foo: 'bar'}),signal: ctrl.signal,
});//而后看到一种说法,fetchEventSource是针对EventSource API的,而不是xhr或fetch API
//因此定义EventSource存储接口所返回的数据 使用EventSource的暂停方法 =》 fetchEventSource暂停成功
const eventSource = fetchEventSource(url, {method: "POST",headers,body,signal: abortController.signal,onmessage(e) {eventSource.close();},onclose() {eventSource.close();},onerror(error) {eventSource.close();},});

以下为fetch/eventSource使用过程中遇到的问题

1.使用fetch方式进行sse流式处理
优点:可以使用post请求
缺点:获取到的数据处理困难 获取事件返回格式或有错误
参考代码:https://blog.csdn.net/betterAndBetter_/article/details/129900233
     http://681314.com/A/YaHyYpjoPF

async function send() {const input = document.getElementById("input").value;const output = document.getElementById("output");output.innerText = "";const url = "/api/stream";const data = { "Prompt": input };
//直接获取 Fetch 的response, 无法使用 await的话, Promise的方式也是可以的。const response = await fetch(url, {method: "POST",body: JSON.stringify(data),headers: {"Content-Type": "application/json"}})//获取UTF8的解码const encode = new TextDecoder("utf-8");//获取body的readerconst reader = response.body.getReader();// 循环读取reponse中的内容while (true) {const { done, value } = await reader.read();if (done) {break;}// 解码内容const text = encode.decode(value);// 当获取错误token时,输出错误信息if (text === "<ERR>") {output.innerText = "Error";break;} else {// 获取正常信息时,逐字追加输出output.innerText += text;}}
}

【记得补截图】

2.使用eventSource进行sse流式处理
优点:获取到的数据格式规范 易处理
缺点:无法使用post请求
参考b站视频:https://www.bilibili.com/video/BV1QA411C7mN/?spm_id_from=333.880.my_history.page.click&vd_source=384646ea9baa6985ceb5331bff5b87b0

var rsource = (this.rsource = new EventSource(`/api/chat/repeat/${this.cid}`));rsource.addEventListener("open", function () {console.log("connect");});//如果服务器响应报文中没有指明事件,默认触发message事件rsource.addEventListener("message", function (e) {console.log(`resp:(${e.data})`);var rconv = that.conversation[that.conversation.length - 1];if (e.data == "[DONE]") {rsource.close();rconv["loading"] = false;that.convLoading = false;that.refrechConversation();that.rsource = undefined;return;}var content = e.data;if (content.includes("[ENTRY]")) {content = content.replaceAll("[ENTRY]", "\n");}// 滚动到最下面that.handleScrollBottom();var idx = rconv.idx;rconv["speeches"][idx] += content;that.refrechConversation();});//发生错误,则会触发error事件rsource.addEventListener("error", function (e) {console.log("error:" + e.data);rsource.close();that.rsource = undefined;});

由于eventSource获取到的数据比fetch流畅许多,所以研究过eventSource能否使用post请求,使用过以下代码,但失败了
在这里插入图片描述
3.fetch和eventSource同时使用
优点:可以很顺利的请求并且获取到数据
缺点:fetch支持post eventSource不支持post 对接口请求方式有要求 几乎不太能兼容

// 获取表单元素
const form = document.querySelector('#my-form');// 监听表单提交事件
form.addEventListener('submit', (event) => {event.preventDefault(); // 阻止默认提交行为const formData = new FormData(form); // 创建 FormData 对象// 发送 POST 请求并接收 SSE 流式输出fetch('/api/submit-form', {method: 'POST',body: formData}).then((response) => {// 如果请求成功,则创建 EventSource 对象监听 SSE 输出if (response.ok) {const eventSource = new EventSource('/api/stream');eventSource.onmessage = (event) => {const data = JSON.parse(event.data);console.log(data); // 处理接收到的数据};eventSource.onerror = (error) => { // 监听错误事件console.error(error);};}}).catch((error) => {console.error(error);});
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/16624.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【python】数据预处理:分位数归一化 Quantile Normalization + INSCODE AI创作助手测试

文章目录 写在前面标准化/归一化z-score标准化示例 python模块qnorm实现分位数归一化R代码实现分位数归一化分位数归一化 - NSCODE AI创作助手的回答*Q1&#xff1a;Quantile Normalization是什么&#xff1f;**Q2-1: 什么时候用Quantile normalization&#xff1f;**Q2-2: 什么…

解决Postman发起请求一直转圈加载没有反应的问题

问题描述 Postman像下面这样一直在发起请求&#xff0c;等待响应 可能的原因 路径写错了&#xff0c;找不到路径存在跨域问题 第一个问题很容易排查&#xff0c;这里说下第二个问题&#xff0c;跨域问题通常有两种解决方案&#xff0c;如下&#xff1a; (1)CORS技术 : 现…

vite首次打开界面加载慢问题/解决

写在前面 网上都说vite要比webpack快&#xff0c;但个人感受&#xff0c;默认情况下, vite项目的启动确实比webpack快&#xff0c;但如果某个界面是首次进入&#xff0c;且依赖比较多/比较复杂的话&#xff0c;那就会比较慢了。 这篇文章就是用来记录&#xff0c;关于vite慢的…

【机器学习 吴恩达】2022课程笔记(持续更新)

一、机器学习 1.1 机器学习定义 计算机程序从经验E中学习&#xff0c;解决某一任务T&#xff0c;进行某一性能P&#xff0c;通过P测定在T上的表现因经验E而提高 eg&#xff1a;跳棋程序 E&#xff1a; 程序自身下的上万盘棋局 T&#xff1a; 下跳棋 P&#xff1a; 与新对手下…

AutoCV番外:Transformer

目录 Transformer注意事项一、2023/5/16更新前言1. Self-attention1.1 前置知识1.2 Self-attention机制1.3 矩阵乘法角度理解1.4 Multi-head Self-attention1.5 Positional Encoding1.6 Many application 2. Transformer2.1 前置知识2.2 Encoder2.3 AT Decoder2.4 NAT Decoder2…

Transformer算法解读(self-Attention/位置编码/多头注意力/掩码机制/QKV/Transformer堆叠/encoder/decoder)

本文主要从工程应用角度解读Transformer&#xff0c;如果需要从学术或者更加具体的了解Transformer&#xff0c;请参考这篇文章。 目录 1 自然语言处理 1.1 RNN 1.2 Transformer 1.3 传统的word2vec 2 Attention 2.1 Attention是什么意思 2.2 self-Attention是什么 2…

AI|用过的AI工具都给你整理好了

AI&#xff5c;用过的AI工具都给你整理好了 最近两周冷静下来了&#xff0c;而且个人状况因为二阳有所影响&#xff0c;没有过多关注这些AI工具&#xff1b;前两天给公司伙伴分享的契机&#xff0c;整理了一下这两个月用过的一些AI工具&#xff0c;部分是日常工作也在使用的&a…

GPT提示词系统学习-第一课-你竟然想不到一个3位数乘法GPT会算错的原因

开篇 在我这个系统的开篇“GPT使我变成超人”中说过,什么样的人使用AI才是起到决定作用的。AI只是工具,它不是万能。使用的人决定了AI可以带什么样的效果。一个很强的人当使用GPT时会形成1+1>2的效果。 因此,提示词的系统化学习是非常重要。这一门课是任何目前国内市面…

【前沿技术】文心一言 PK Chat Gpt

目录 写在前面 一、文心一言 二、Chat GPT 三、对比 四、总结 写在前面 随着人工智能技术的不断发展和普及&#xff0c;越来越多的智能应用走入了人们的日常生活&#xff0c;如智能语音助手、智能客服、机器翻译等等。在这些应用中&#xff0c;自然语言生成&#xff08;…

【对比】文心一言对飚ChatGPT实操对比体验

前言 &#x1f34a;缘由 百度【文心一言】体验申请通过 本狗中午干饭时&#xff0c;天降短信&#xff0c;告知可以体验文心一言&#xff0c;苦等一个月的实操终于到来。心中这好奇的对比心理油然而生&#xff0c;到底是老美的【ChatGPT】厉害&#xff0c;还是咱度娘的【文心一…

ChatGLM ptuning 的实战方案

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

Vicuna-13B云服务器部署

Vicuna概述 Vicuna由一群主要来自加州大学伯克利分校的研究人员推出&#xff0c;仍然是熟悉的配方、熟悉的味道。Vicuna同样是基于Meta开源的LLaMA大模型微调而来&#xff0c;它的训练数据是来自ShareGPT上的7万多条数据&#xff08;ShareGPT一个分享ChatGPT对话的谷歌插件&am…

Chat-GLM 详细部署(GPU显存>=12GB)

建议配置: ( Windows OS 11 部署 )CPU-i7 13700F ~ 13700KF RAM: 16GB DDR4 GPU: RTX3080(12G) 安装 conda: 1. 下载安装 miniconda3 &#xff1a; https://docs.conda.io/en/latest/miniconda.html conda是一个包和环境管理工具&#xff0c;它不仅能管理包&#xff0c;还能隔…

“本草”大模型开源,ChatGPT时代,连AI私人医生都出现了?

大家好,我是千与千寻,也可以叫我千寻,今天给大家分享的ChatGPT新应用项目,是ChatGPT模型在医学领域的应用,什么,医学领域? 是的,没错,是医学领域的ChatGPT应用,我们都知道ChatGPT是OpenAI开源的一个智能对话式引擎,今天给大家分享的项目叫“本草”。 “本草”模型是…

linux下打开对外开放端口号

第一种方式 &#xff08;1&#xff09;查看对外开放的端口状态 查询已开放的端口 netstat -ntulp | grep 端口号&#xff1a;可以具体查看某一个端口号 查询指定端口是否已开 firewall-cmd --query-port666/tcp 提示 yes&#xff0c;表示开启&a…

chatgpt赋能python:Python怎么装中文?

Python怎么装中文&#xff1f; 介绍 Python是一种非常流行的编程语言&#xff0c;用于各种不同类型的任务&#xff0c;包括应用程序开发、数据科学和人工智能等等。但是&#xff0c;如果您在安装Python时遇到了一些困难&#xff0c;比如无法输入中文&#xff0c;那么阅读本文…

GitHub万星大佬做出纳?开发OpenAI工具必用知识集;ChatGPT最新速查表;6万字AI Prompt教程 | ShowMeAI日报

&#x1f440;日报合辑 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; GitHub 万星大佬&#xff0c;生活所迫接连转行&#xff0c;外卖送过了&#xff0c;现在要去做出纳&#xff0c;买瓶可乐都得犹豫 &#x1f30f;…

AutoGPT使用

windows和mac都可以使用 1&#xff0c;安装python 10 https://www.tutorialspoint.com/how-to-install-python-in-windows 2&#xff0c;下载AutoGPT代码 通过git克隆AutoGPT项目&#xff0c;git clone https://github.com/Torantulino/Auto-GPT.git如果没有安装git的同学就…

如何用Stable Diffusion模型生成个人专属创意名片?

目录 1 什么是二维码&#xff1f;2 什么是扩散模型&#xff1f;3 Stable Diffusion环境搭建4 开始制作创意名片结语 1 什么是二维码&#xff1f; 二维码是一种用于存储和传输信息的方便而广泛使用的图像编码技术。它是由黑色方块和白色空白区域组成的二维图形&#xff0c;可以…

chatgpt赋能python:用Python生成带照片的二维码,让你的业务变得更有效!

用Python生成带照片的二维码&#xff0c;让你的业务变得更有效&#xff01; 当谈到数字营销和交流业务时&#xff0c;二维码已经成为了一种流行的选择。二维码可以将大量的信息储存到一个小小的图像中&#xff0c;方便让消费者扫描后获取信息&#xff0c;例如&#xff1a;产品…