ChatGPT-UI
最近看到了 川虎 ChatGPT 的项目,感觉很有意思,但是整个项目都是python写的,那咱大前端不也得整一个玩玩?
项目/预览
看了川虎的项目,真心感觉不错,但是UI毕竟是用python写的,确实差点儿意思 然后看到了 New Bing 的聊天页面,感觉确实还不错,那就:拿来吧你[狗头]
实现分析
其实搞一个ui体验模板倒是不难,问题就在于很多人注册不了openAi的账号,科学上网和手机好的问题就困扰了很多人,本篇文章就不做介绍这些前置的东西了,网上很多文章都介绍的很详细。
介绍一下 api 调用的整体流程吧 (一个vue的项目搭建这里就省略了吧)
1、安装 openAi 的依赖
npm install openai
2、按官方文档的介绍 初始化
import { Configuration, OpenAIApi } from "openai";
let openAiInstance
function initChatAi() {
const configuration = new Configuration({ apiKey: 'sk-xxxxxxxxxx' });
const openAi = new OpenAIApi(configuration);
openAiInstance = openAi
}
3、初始化之后就是调用接口了,调用创建聊天的 api
const params = {
model: modelMap.chat,
messages: [{role: 'user', content: 'hello' }],
};
openAiInstance.value
.createChatCompletion(params)
.then((res) => {
const [response] = res.data.choices;
// 拿到了返回的信息
console.log(response)
})
这里调用成功的话接口便会返回聊天内容啦,但是发现回复的内容并不像官网那样,是实时的聊天,文字是一个一个展示的。
4、配置接口返回模式为实时返回模式
这里就用到了 接口返回数据 content-type: text/event-stream
格式的,需要特殊处理一下了。整体就是利用 fetch
请求数据, 然后使用TextDecoder
来解析响应数据
这个咱一开始也是不知道怎么解析,也是问了ChatGPT解决的 🐶
const params = {
model: modelMap.chat,
messages: [{role: 'user', content: 'hello' }],
stream: true
};
const openAiHeaders = openAiInstance.value.configuration.baseOptions.headers;
fetch(openAiInstance.value.basePath + "/chat/completions", {
method: "POST",
body: JSON.stringify(params),
headers: {
"Content-Type": "application/json",
Authorization: openAiHeaders.Authorization,
},
})
.then((response) => {
const stream = response.body;
const reader = stream.getReader();
let buffer = "";
// 逐行读取数据
reader.read().then(function processText({ done, value }) {
if (done) return;
buffer += new TextDecoder().decode(value);
const lines = buffer.split("\n");
// 处理数据流
lines.forEach((line) => {
if (line.length < 1) return;
const value = line.slice(6);
if (value === "[DONE]") {
pending.value = false;
return;
}
const result = JSON.parse(value);
const [content] = result.choices;
// ToDo 这里可以设置结果文本啦
});
buffer = lines.pop();
return reader.read().then(processText);
});
})
核心逻辑差不多就这么多啦,感兴趣的小伙伴可以看一下 GitHub 的源码