当前位置:   article > 正文

写个Ai对话小程序SSE_uniapp sse

uniapp sse

前言

最近捣鼓小程序,突然发现小程序好像没怎么有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)
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

随后我又尝试了几次后无法解决就开始改用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}`)
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

uniapp编写小程序

小程序现在并不支持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, "");
  })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

至此一个简单的ai对话就完成了

在这里插入图片描述
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/971183
推荐阅读
相关标签
  

闽ICP备14008679号