fetch('这儿替换你的接口', {
method: 'POST',
headers: {
...getHeaders(),//请求头
'Content-Type': 'application/json'
},
body: JSON.stringify({
messages: this.messages, //详细看下面
stream: true,//返回流式数据
response_format: 'json_object', system: '你问他是谁的时候想让他回答什么,具体可参考千帆大模型'
}),
})
.then(response => {
if (response.ok) {
return response.body
}
}).then((stream) => {
const reader = stream.getReader();
const decoder = new TextDecoder();
let that = this
function read() {
return reader.read().then(({ value, done }) => {
// console.log(value, done);
if (done) {
// 数据流结束
console.log('Done reading the stream');
return;
}
let data11 = decoder.decode(value);
try {
data11 = data11.trim()
if (that.lastText == '') {
JSON.parse(data11.trim())
if (that.isJSON(data11.trim())) {
that.texts +=JSON.parse(data11.trim()).result
if (!that.aiStop) {
that.type();
}
}
} else {
data11 = that.lastText + data11;
that.lastText = "";
JSON.parse(data11.trim())
if (that.isJSON(data11.trim())) {
that.texts +=JSON.parse(data11.trim()).result
if (!that.aiStop) {
that.type();
}
}
}
} catch (e) {
that.lastText = data11
data11 = "";
}
return read();
});
}
return read()
})
}
打字机效果,不是很精细,可以做个参考,隔50毫秒会打印一次
type(index) {
if (this.typingTimer) {
clearTimeout(this.typingTimer);
}
if (this.char_index < this.texts.length) {
let txt = this.messages[index ? index : this.messages.length - 1].content;
let cursor = enableCursor ? "|" : "";
if (enableCursor && txt.endsWith("|")) {
txt = txt.slice(0, -1);
}
this.messages[index ? index : this.messages.length - 1].content = txt + this.texts.charAt(this.char_index) + cursor;
this.char_index++;
// this.type(index ? index : '')
this.typingTimer = setTimeout(() => { this.type(index) }, 50);
}
},
关于message的话,是个数组,里面放着我们的问题以及ai的回复,大概就下面这样,每次请求的时候数组必须是奇数,也就是说最后一条一定是你问他的
[{ role: "user", content: '我们问的问题' },{ role: "assistant", content: 'ai回复的文本', realText: row.content }]
具体传参什么的可以参考千帆大模型文档,鉴权什么的可以交给后端处理
最后的效果如下
最后总结:ai回复的文本可能需要支持Markdown格式,我使用的是vue-markdown,有更好的选择也可以使用别的,仅供参考有更好的处理方法也可以随时交流。