赞
踩
ChatGPT
的参考API
地址API
介绍 下图是正常请求时候的请求头和body
体,这样请求的话是等结果都加载出来后一起出现,并且返回的结果也是标准的json
格式。
如果想要实现和ChatGPT
一样的效果,官网的这样推荐的,如下图
从上图可以看到它用的是sse
实现的,并且请求的body
体加上Stream:true
就可以。请求过来的格式可以看到不是标准的json
格式,如下图,所以我们要处理成json
格式,并拿到数据
我们要怎么拿到数据并实现流式输出,具体代码如下:
// 发送消息的方法 // 参数 content 是发送的消息 function sendAnswer(content) { // 请求的body体 const data = JSON.stringify({ model: 'gpt-3.5-turbo', messages: [{ role: 'user', content: content }], stream: true }) fetch('https://api.openai.com/v1/chat/completions', { method: 'POST', // 这个headers包括 "Content-Type":"application/json" 和 "Authorization", `Bearer ${key}` // 其中这个key是你的登录密钥 headers: headers, body: JSON.stringify({ model: 'gpt-3.5-turbo', messages: [{ role: 'user', content: content }], // 启用流式处理 stream:true }), }) .then( response => { // 创建一个可读取响应体数据的读取器对象 const reader = response.body.getReader(); let buffer = ''; // 这一部分是创建了一个装回复聊天信息的盒子 const layoutBox = document.createElement("div"); layoutBox.classList.add("layout"); // dialogue 是创建的一个大的父盒子的名称 dialogue.appendChild(layoutBox); const answerBox = document.createElement("span") answerBox.classList.add("answerList","list") layoutBox.appendChild(answerBox) // 因为流式输出会逐个字出来,所以定义 answers 存放回复的消息,不存放的话后续用innerHTML插入的时候会被覆盖,只显示最后一个字符 let answers = []; // 这是一个JavaScript Promise的语法,表示当读取器(reader)读取完成后,执行一个函数(processResult)来处理结果(result) return reader.read().then(function processResult(result){ // 解码,并将解码后的数据存放到buffer buffer += new TextDecoder().decode(result.value || new Uint8Array(), {stream: !result.done}); // 这是以换行符将字符串分为多个部分,并过滤掉以[DONE]结尾的部分 const parts = buffer.split('\n').filter(part => !part.endsWith('[DONE]'));; buffer = parts.pop(); for(const part of parts){ if(part.trim()){ try { const response = JSON.parse(part.slice('data:'.length)); console.log(response.choices[0].delta.content); answerContent = response.choices[0].delta.content; // 将内容存放到数组中,这个判断是answerContent 开头和结尾存在JSON解析不成功的部分,会在聊天记录的开始和结尾显示undefined if (answerContent !== undefined) { answers.push(answerContent) } } catch (error) { console.error(`Failed to parse JSON: ${error.message}`); continue; } } } // 将数组中的内容以html的形式插入到聊天回复框中,如果不加join("")数组中的每一个字符都会被逗号隔开 // 引入第三方库 marked 进行markdown格式化 import {marked} from "marked"; answerBox.innerHTML = marked( answers.join(""),{ headerIds: false, mangle: false }); // 引入第三方库 hljs ,实现代码块高亮 import hljs from 'highlight.js' hljs.highlightAll(); if(result.done){ return; } return reader.read().then(processResult); }) }) }
实现效果如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。