【JavaScript】fetch 处理流式数据,实现类 chatgpt 对话

本文只包含最基础的请求后端大佬给得对话接口,大部分模型的传参是差不多的,核心还是如何处理 fetch 获取的流数据

ts 复制代码
import { defineStore } from 'pinia';
import { ElMessage } from 'element-plus';

type Role = 'system' | 'user' | 'assistant';
export interface Message {
  role: Role;
  content: string;
}
interface ChatStore {
  model: 'Gnosis' | 'chatglm2-6b' | 'cc-13b-chat';
  chatApi: string;
  messages: Message[];
  done: boolean | null;
}
const DEFAULT_PROMPT = `你应该根据用户回答生成答案。答案必须尽可能简明扼要。字数控制在512个字符以内`;

export const useChatStore = defineStore({
  id: 'chatStore',
  state: (): ChatStore => {
    return {
      model: 'cc-13b-chat',
      chatApi: 'chat_api/chat/knowledge_base_chat',
      messages: [
        {
          role: 'system',
          content: DEFAULT_PROMPT,
        },
      ],
      done: null,
    };
  },
  actions: {
    async fetchChat(query: string) {
      this.messages.push({
        role: 'user',
        content: query,
      });
      let response: any = null;
      try {
        response = await fetch(this.chatApi, {
          headers: {
            'Content-Type': 'application/json',
          },
          method: 'POST',
          body: JSON.stringify({
            query: query,
            history: this.messages,
            model_name: this.model,
            stream: true,
            knowledge_base_name: 'lb_test',
            top_k: 1,
            score_threshold: 1,
            temperature: 0.7,
            max_tokens: 4096,
            prompt_name: 'default',
          }),
        });
      } catch (error) {
        console.log(error);
        ElMessage.error('请求失败');
        return;
      }
      const data = response.body;
      this.messages.push({
        role: 'assistant',
        content: '',
      });
      // 处理流式数据
      if (data) {
        const reader = data.getReader();
        const decoder = new TextDecoder('utf-8');
        this.done = false;
        while (!this.done) {
          const { value, done: readerDone } = await reader.read();
          // value值
          // {"answer": "帮助解决"}
          if (value) {
            const char = decoder.decode(value);
            console.log(char);
            // if (char === '\n') {
            //   this.messages[this.messages.length - 1].content += '\n';
            //   continue;
            // }
            if (char) {
              const res = JSON.parse(char);
              this.messages[this.messages.length - 1].content += res.answer ?? '';
            }
          }
          if (!this.done) {
            this.done = readerDone;
          }
        }
      }
      // 对话结束
      this.done = null;
    },
  },
  // persist: {
  //   key: 'store',
  //   storage: window.localStorage,
  // },
});
相关推荐
q5673152327 分钟前
在 Bash 中获取 Python 模块变量列
开发语言·python·bash
阿伟来咯~37 分钟前
记录学习react的一些内容
javascript·学习·react.js
吕彬-前端42 分钟前
使用vite+react+ts+Ant Design开发后台管理项目(五)
前端·javascript·react.js
学前端的小朱1 小时前
Redux的简介及其在React中的应用
前端·javascript·react.js·redux·store
许野平1 小时前
Rust: 利用 chrono 库实现日期和字符串互相转换
开发语言·后端·rust·字符串·转换·日期·chrono
guai_guai_guai1 小时前
uniapp
前端·javascript·vue.js·uni-app
也无晴也无风雨1 小时前
在JS中, 0 == [0] 吗
开发语言·javascript
狂奔solar1 小时前
yelp数据集上识别潜在的热门商家
开发语言·python
水豚AI课代表1 小时前
分析报告、调研报告、工作方案等的提示词
大数据·人工智能·学习·chatgpt·aigc
blammmp2 小时前
Java:数据结构-枚举
java·开发语言·数据结构