Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
uni-ai-chat
提交
64fb6005
U
uni-ai-chat
项目概览
DCloud
/
uni-ai-chat
通知
898
Star
11
Fork
8
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
2
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-ai-chat
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
2
Issue
2
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
64fb6005
编写于
4月 21, 2023
作者:
DCloud_JSON
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
文档完成
上级
80a06a88
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
235 addition
and
89 deletion
+235
-89
pages/chat/chat.vue
pages/chat/chat.vue
+37
-37
redme.md
redme.md
+24
-0
static/uni-ai.png
static/uni-ai.png
+0
-0
uniCloud-aliyun/cloudfunctions/atest/index.js
uniCloud-aliyun/cloudfunctions/atest/index.js
+0
-43
uniCloud-aliyun/cloudfunctions/uni-ai-chat-/index.js
uniCloud-aliyun/cloudfunctions/uni-ai-chat-/index.js
+0
-5
uniCloud-aliyun/cloudfunctions/uni-ai-chat-/package.json
uniCloud-aliyun/cloudfunctions/uni-ai-chat-/package.json
+12
-0
uniCloud-aliyun/cloudfunctions/uni-ai-chat/index.obj.js
uniCloud-aliyun/cloudfunctions/uni-ai-chat/index.obj.js
+161
-0
uniCloud-aliyun/cloudfunctions/uni-ai-chat/package.json
uniCloud-aliyun/cloudfunctions/uni-ai-chat/package.json
+1
-4
未找到文件。
pages/chat/chat.vue
浏览文件 @
64fb6005
...
...
@@ -219,43 +219,43 @@
await
SSEChannel
.
open
()
// 等待通道开启
}
uni
Cloud
.
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
"
)
uni
AiChat
.
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
(()
=>
{
...
...
redme.md
浏览文件 @
64fb6005
## 简介
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控制台,更改
`连接本地云函数`
为
`连接云端云函数`
。
static/uni-ai.png
0 → 100644
浏览文件 @
64fb6005
16.3 KB
uniCloud-aliyun/cloudfunctions/atest/index.js
已删除
100644 → 0
浏览文件 @
80a06a88
'
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
}
};
uniCloud-aliyun/cloudfunctions/uni-ai-chat/index.js
→
uniCloud-aliyun/cloudfunctions/uni-ai-chat
-
/index.js
浏览文件 @
64fb6005
'
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
"
:
"
请简要总结上述全部对话
"
,
...
...
uniCloud-aliyun/cloudfunctions/
atest
/package.json
→
uniCloud-aliyun/cloudfunctions/
uni-ai-chat-
/package.json
浏览文件 @
64fb6005
{
"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
uniCloud-aliyun/cloudfunctions/uni-ai-chat/index.obj.js
0 → 100644
浏览文件 @
64fb6005
// 云对象教程: 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
uniCloud-aliyun/cloudfunctions/uni-ai-chat/package.json
浏览文件 @
64fb6005
{
"name"
:
"uni-ai-c
f
"
,
"name"
:
"uni-ai-c
hat
"
,
"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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录