赞
踩
最近捣鼓小程序,突然发现小程序好像没怎么有ai对话,就突然想写一个对话小程序,记录一下走过的坑。
前端:uniapp 后端:express openai-node
本来后端用的是egg.js,但是我写的时候发现egg时候使用body返回PassThrough数据就会等待全部数据返回后一起返回,具体原因使用for循环就会出现这种情况,使用setTimeout模拟流数据就不会出现这种情况,由于我对egg不是很熟悉就没有研究这是为什么,知道的朋友可以留言告知我为什么下面是egg.js的代码
ctx.set('Content-Type', 'text/event-stream');
const PassThrough1 = new PassThrough()
ctx.body = PassThrough1
const stream = await openai.chat.completions.create({
messages: [{role: 'user', content: prompt}],
model: 'qwen-plus',
stream: true,
});
for await (const chunk of stream) {
try {
PassThrough1.write(`${JSON.stringify(chunk)}\n\n`)
}catch (e) {
console.log(e)
}
}
随后我又尝试了几次后无法解决就开始改用express,由于现在ChatGPT全面禁用咱们,所以我用的通义千问,虽然还没有node版本的jdk,但是还好支持opneai库只需要修改链接就可以,这样我们只要访问/ai这个接口就会得到流式数据并且渲染他。
const express = require('express') const {OpenAI} = require('openai') const app = express() const port = 3000 const openai = new OpenAI({ apiKey: '********', baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1", }); app.get('/ai', async (req, res) => { res.writeHead(200, { 'Content-Type': 'text/event-stream' }) // 'tex const prompt = req.query.prompt const stream = await openai.chat.completions.create({ messages: [{role: 'user', content: prompt}], model: 'qwen-plus', stream: true, }); for await (const chunk of stream) { // console.log(chunk) res.write(`${JSON.stringify(chunk.choices[0]?.delta?.content || '')}`) } req.on('close', () => { console.log('req close...') }) }) app.listen(port, () => { console.log(`Example app listening on port ${port}`) })
小程序现在并不支持sse,所以我只能用以下方法来进行获取流数据,前端只写了核心代码。
const requestTask = uni.request({ url: 'http://127.0.0.1:3000/ai', timeout: 15000, responseType: 'text', method: 'GET', enableChunked: true, //配置这里 data: { prompt: this.content }, success: response => { console.log(response) }, fail: error => {} }) requestTask.onHeadersReceived(function(res) { console.log(res.header); }) requestTask.onChunkReceived((res)=> { //二进制数据转为字符串 const uint8Array = new Uint8Array(res.data); let text = String.fromCharCode.apply(null, uint8Array); text = decodeURIComponent(escape(text)).replace(/\"/g, ""); })
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。