完整示例在这
Stream API MDN
这里专门讨论流处理功能。
“/v1/chat/completions”是一个请求完成后才返回的接口,现在要将其转成流传输接口,实现逐字往外蹦的效果
下面是【JS 调用gpt3.5】的流步骤,用于帮助理解
getResponseFromAPI = async () => {
// 1.fetch,body携带stream: true属性
const response = await fetch(this.state.endpoint, {
signal,
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${this.state.apiKey}`,
},
body: JSON.stringify({
model: this.state.model,
messages,
max_tokens: this.state.max_tokens,
n: 1,
stop: null,
temperature: this.state.temperature,
stream: true,
}),
});
// 2. 获取reader对象
const reader = response.body.getReader();
const decoder = new TextDecoder("utf-8");
// 3. 定义流对象,相当于手动开启关闭流
const stream = new ReadableStream({
start(controller) {
return pump();
function pump() {
// 4. reader()
return reader.read().then(({ done, value }) => {
// When no more data needs to be consumed, close the stream
if (done) {
controller.close();
return;
}
let text = "";
// 5. 直接用utf-8的decoder解码,按照数据的格式处理转换
const str = decoder.decode(value);
const strs = str.split("data: ").filter((v) => v);
for (let i = 0; i < strs.length; i++) {
const val = strs[i];
if (val.includes("[DONE]")) {
controller.close();
return;
}
const data = JSON.parse(val);
data.choices[0].delta.content &&
(text += data.choices[0].delta.content);
}
// 6. 将下一个数据块加入我们的目标流
controller.enqueue(text);
return pump();
});
}
},
});
// 7. 创建一个流响应
return new Response(stream);
};
// 8. 调用封装好的流请求,即上面
this.getResponseFromAPI(input).then(async (response) => {
// 9. getReader()
const reader = data.getReader();
let done = false;
while (!done) {
// 10. reader(),操作做实际想做的事
const { value, done: readerDone } = await reader.read();
if (value) {
this.addMessage(value, "assistant");
this.scrollToBottom();
}
done = readerDone;
}
});
版权声明:本文为betterAndBetter_原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。