提交 64fb6005 编写于 作者: DCloud_JSON's avatar DCloud_JSON

文档完成

上级 80a06a88
......@@ -219,43 +219,43 @@
await SSEChannel.open() // 等待通道开启
}
uniCloud.callFunction({
name: "uni-ai-chat",
data: {
messages,
SSEChannel
}
})
.then(res => {
let index = this.msgList.length - 1
let lastItem = this.msgList[index]
lastItem.state = 100
this.msgList.splice(index, 1, lastItem)
if (!SSEChannel) {
console.log(res, res.result.reply);
this.msgList.push({
isAi: true,
content: res.result.reply,
summarize: res.result.summarize,
create_time: Date.now()
})
this.showLastMsg()
}
})
.catch(e => {
console.log(e);
let index = this.msgList.length - 1
let lastItem = this.msgList[index]
lastItem.state = -100
this.msgList.splice(index, 1, lastItem)
uni.showModal({
content: JSON.stringify(e.message),
showCancel: false
});
})
const uniAiChat = uniCloud.importObject("uni-ai-chat")
uniAiChat.send({
name: "uni-ai-chat",
data: {
messages,
SSEChannel
}
})
.then(res => {
let index = this.msgList.length - 1
let lastItem = this.msgList[index]
lastItem.state = 100
this.msgList.splice(index, 1, lastItem)
if (!SSEChannel) {
console.log(res, res.result.reply);
this.msgList.push({
isAi: true,
content: res.result.reply,
summarize: res.result.summarize,
create_time: Date.now()
})
this.showLastMsg()
}
})
.catch(e => {
console.log(e);
let index = this.msgList.length - 1
let lastItem = this.msgList[index]
lastItem.state = -100
this.msgList.splice(index, 1, lastItem)
uni.showModal({
content: JSON.stringify(e.message),
showCancel: false
});
})
},
showLastMsg() {
this.$nextTick(() => {
......
## 简介
uni-ai-chat是基于[uni-ai](https://uniapp.dcloud.net.cn/uniCloud/uni-ai.html)的云端一体AI项目模板
视频效果:
<video controls src="https://web-assets.dcloud.net.cn/unidoc/zh/uni-ai-chat/uni-ai-stream.mov" style="max-width: 100%; max-height: 70vh;"></video>
包含一个前端页面(路径:`/pages/chat/chat.vue`)和一个云对象(路径:`uniCloud-aliyun/cloudfunctions/uni-ai-chat/index.obj.js`)
## 体验步骤
1. 如之前未使用过uni-app,那请重头学起。[uni-app官网](https://uniapp.dcloud.net.cn)
2. 如果你还没有开通uniCloud,需要登录[https://unicloud.dcloud.net.cn/](https://unicloud.dcloud.net.cn/),创建一个服务空间。
3. 打开`uni-ai-chat`插件下载地址:[https://ext.dcloud.net.cn/plugin?name=uni-ai-chat](https://ext.dcloud.net.cn/plugin?name=uni-ai-chat)
4. 点击`使用HBuilderX导入示例项目`
5. 对项目根目录uniCloud点右键选择“云服务空间初始化向导”界面按提示部署项目
6. 在uni-app项目点右键创建uniCloud环境,关联之前创建的服务空间。
## 注意事项
uni-ai-chat支持[stream](https://uniapp.dcloud.net.cn/uniCloud/uni-ai.html#%E6%B5%81%E5%BC%8F%E5%93%8D%E5%BA%94-chat-completion-stream)
模式,该模式会接收uni-ai的流式响应的数据,再通过[sse-channel](https://uniapp.dcloud.net.cn/uniCloud/sse-channel.html)即:云函数(云对象)请求中的中间状态通知通道向客户端推送消息
而使用`sse-channel`需要先[开通uni-push](https://uniapp.dcloud.net.cn/unipush-v2.html#%E7%AC%AC%E4%B8%80%E6%AD%A5-%E5%BC%80%E9%80%9A)
,目前uni-push2.0不支持本地调试(后续版本会支持),需要再在HBuilderX控制台,更改`连接本地云函数``连接云端云函数`
'use strict';
exports.main = async (event, context) => {
const llmManager = uniCloud.ai.getLLMManager({
// provider: 'minimax'
provider: 'openai',
apiKey: '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',
proxy: 'sgoa.dcloud.io'
// provider: 'baidu',
// accessToken: '24.3989d9fc6f2ff40813f9f9f8b006d72b.2592000.1682688547.282335-31576157'
})
try {
const response = await llmManager.chatCompletion({
// model: 'gpt-3.5-turbo',
messages: [{
role: 'user',
content: '介绍一下uni-app,100字以内,分为两段'
}],
tokensToGenerate: 200,
stream: true
})
return new Promise((resolve, reject) => {
response.on('line', (line) => {
console.log('---line----', line)
})
response.on('message', (message) => {
console.log('---message----', message)
})
response.on('end', () => {
console.log('---end----')
resolve({errCode: 0})
})
response.on('error', (err) => {
console.log('---error----', err)
reject(err)
})
})
} catch (e) {
//TODO handle the exception
console.log(e.errCode);
console.log(e.errMsg);
throw e
}
};
'use strict';
exports.main = async (event, context) => {
// 这里你可以自己拦截执行,比如限制只能登录后的用户可用
//event为客户端上传的参数
console.log('event', event)
......@@ -114,10 +113,6 @@ async function chatCompletion({
}
}
async function getSummarize(messages) {
messages.push({
"content": "请简要总结上述全部对话",
......
{
"name": "atest",
"name": "uni-ai-cf",
"dependencies": {},
"extensions": {
"uni-cloud-jql": {},
"uni-cloud-ai": {}
"uni-cloud-ai": {},
"uni-cloud-push": {}
},
"cloudfunction-config": {
"path": "/uni-ai-demo"
}
}
\ No newline at end of file
// 云对象教程: https://uniapp.dcloud.net.cn/uniCloud/cloud-obj
// jsdoc语法提示教程:https://ask.dcloud.net.cn/docs/#//ask.dcloud.net.cn/article/129
module.exports = {
_before: function() {
// 这里是云函数的前置方法,你可以在这里加入你需要逻辑,比如:拦截用户必须登录才能访问等
/*
例如:使用uni-id-pages(链接地址:https://ext.dcloud.net.cn/plugin?id=8577)搭建账户体系。
然后再使用uni-id-common的uniIdCommon.checkToken判断用户端身份,验证不通过你可以直接`throw new Error(“token无效”)`抛出异常拦截访问。
如果验证通过了可以获得用户id,可以记录每一个用户id的调用次数来限制,调用多少次后必须充值(推荐用uni-pay,下载地址:https://ext.dcloud.net.cn/plugin?id=1835)
或者看一个激励视频广告(详情:https://uniapp.dcloud.net.cn/uni-ad/ad-rewarded-video.html)后才能继续使用
*** 激励视频是造富神器。行业经常出现几个人的团队,月收入百万的奇迹。 ***
*/
},
/**
* send方法描述
* @param {messages}
* @param {SSEChannel}
* @returns {object} 返回值描述
*/
send(messages,SSEChannel) {
// 初次调试时,可不从客户端获取数据,直接使用下面写死在云函数里的数据
// messages = [{
// role: 'user',
// content: 'uni-app是什么,20个字以内进行说明'
// }]
// 校验客户端提交的参数
let res = checkMessages(messages)
if (res.errCode) {
throw new Error(res.errMsg)
}
// 向uni-ai发送消息
return await chatCompletion({
messages,
SSEChannel
})
async function chatCompletion({
messages,
summarize = false,
SSEChannel = false
}) {
const llmManager = uniCloud.ai.getLLMManager({
// provider: 'openai',
// apiKey: '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',
// proxy: 'sgoa.dcloud.io',
provider: 'minimax',
// provider: 'baidu',
// accessToken: '24.3989d9fc6f2ff40813f9f9f8b006d72b.2592000.1682688547.282335-31576157'
})
let res = await llmManager.chatCompletion({
messages,
tokensToGenerate: 3000,
stream: SSEChannel !== false
})
if (SSEChannel) {
let reply = ""
return new Promise((resolve, reject) => {
const channel = uniCloud.deserializeSSEChannel(SSEChannel)
res.on('message', async (message) => {
// await channel.write(message)
// console.log('---message----', message)
})
res.on('line', async (line) => {
reply += line
await channel.write(line)
// console.log('---line----', line)
})
res.on('end', async () => {
console.log('---end----',reply)
messages.push({
"content": reply,
"role": "assistant"
})
let totalTokens = messages.map(i => i.content).join('').length;
if (!summarize && totalTokens > 500) {
let replySummarize = await getSummarize(messages)
// console.error('replySummarize',replySummarize)
await channel.end({summarize:replySummarize})
}
resolve({
errCode: 0
})
})
res.on('error', (err) => {
console.error('---error----', err)
reject(err)
})
})
} else {
if(summarize == false){
messages.push({
"content": res.reply,
"role": "assistant"
})
let totalTokens = messages.map(i => i.content).join('').length;
if (totalTokens > 500) {
let replySummarize = await getSummarize(messages)
res.summarize = replySummarize
}
}
return res
}
}
//获总结
async function getSummarize(messages) {
messages.push({
"content": "请简要总结上述全部对话",
"role": "user"
})
// 获取总结不需要再总结summarize和stream
let res = await chatCompletion({
messages,
summarize: true,
stream: false,
SSEChannel:false
})
return res.reply
}
function checkMessages(messages) {
try {
if (messages === undefined) {
throw "messages为必传参数"
} else if (!Array.isArray(messages)) {
throw "参数messages的值类型必须是[object,object...]"
} else {
messages.forEach(item => {
if (typeof item != 'object') {
throw "参数messages的值类型必须是[object,object...]"
}
let itemRoleArr = ["assistant", "user", "system"]
if (!itemRoleArr.includes(item.role)) {
throw "参数messages[{role}]的值只能是:" + itemRoleArr.join('')
}
if (typeof item.content != 'string') {
throw "参数messages[{content}]的值类型必须是字符串"
}
})
}
return {
errCode: 0,
}
} catch (errMsg) {
return {
errSubject: 'ai-demo',
errCode: 'param-error',
errMsg
}
}
}
}
}
\ No newline at end of file
{
"name": "uni-ai-cf",
"name": "uni-ai-chat",
"dependencies": {},
"extensions": {
"uni-cloud-jql": {},
"uni-cloud-ai": {},
"uni-cloud-push": {}
},
"cloudfunction-config": {
"path": "/uni-ai-demo"
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册