安装前需要补全依赖库。
"dependencies": {
"@google/genai": "^0.13.0",
"vue-router": "^3.5.2",
}
"devDependencies": {
"raw-loader": "^4.0.2",
}
需要在Vue对象新建前安装事件总线用于跨组件通信。
Vue.prototype.$bus = new Vue()
new Vue({
})
然后在合适的位置引入这个组件
<template>
<ai-helper></ai-helper>
</template>
<script>
import AiHelper from "@/aiHelper/index.vue";
export default {
name: 'AppMain',
components: {
AiHelper
}
}
</script>
不出意外助手已经成功引入了
系统插件和普通插件本身并无区别。一般与业务无关的可通用的插件放置在系统插件的目录,业务相关的插件放在最外层的插件目录。此外,系统插件会先于普通插件加载。
整个助手是由一个个插件组合而成,每个插件相互独立,分别为助手提供不同的能力。
AI能力本质是一个JS方法,AI会自行判断并且自由调用这些方法。为了安全起见AI能力只能编写一些数据获取的方法,扩展保存数据的能力将在扩展AI技能部分讲到。
我们以一个获取当前时间的能力为例子介绍如何扩展AI能力。
AI模型本身是不能联网的,所以它无法获取到目前的时间。我们可以为AI扩展这个能力。
因为获取时间是一个通用的能力,与具体业务无关,所以在system/plugin下新建插件。首先建立一个插件文件夹。
再依次建立两个文件,prompt.md用于存放提示词,tool.vue用于编写代码。
根据以下格式编写提示词
## 获取当前时间
获取当前的系统时间。utc属性为true时返回utc时间,为false时返回本地时间。
tool_name:getCurrentTime
data:{utc: boolean}
根据以下格式编写代码
<script>
import Vue from 'vue'
import Prompt from '!!raw-loader!./prompt.md' //导入刚刚写的提示词
export default Vue.extend({
name: "getCurrentTime", //这个名字建议修改,虽然重名不会报错
data() {
return {
type: 'tool', //类型为tool,必填
prompt: Prompt //定义提示词,必填
}
},
methods:{
//像写普通的js方法一样书写代码即可,注意因为这些代码并不会被vue初始化,所以需要注意this指向。
getCurrentTime(data) {//函数名不能与任何已存在的AI能力重名
// 返回一个Promise
return new Promise((resolve, reject) => {
if(data.utc){
//返回数据需要使用一个对象包裹
resolve({data:new Date().toUTCString()})
}else{
resolve({data:new Date().toLocaleString()})
}
})
}
//一个文件内是可以定义多个方法的
}
})
</script>
现在回到助手再试一下,已经可以正常获取当前时间了。
可以编写vue组件来丰富AI与用户的交互。
这里以AI对话框为例子,介绍如何扩展用户交互。
与扩展能力一样,先建立文件夹和两个文件。
编写提示词
## 展示选项对话框
展示一个选项对话框,然后你能获取到用户选择的选项,使用此工具时需要在context中解释这个操作。
tool_name:initSelect
data:[{label:string,value:string}]
说明:data中需要至少一项
编写组件
<script>
import Prompt from '!!raw-loader!./prompt.md' //导入提示词
import Vue from 'vue'
export default Vue.extend({
name: "initSelect",
data() {
return {
type: 'comp', //类型,必填
prompt: Prompt //提示词,必填
}
},
props: [
'tool_name', //当前正在被调用的能力的名称
'tool_input', //一个公用的prop
'tool_data' //AI传入的数据,具体需要什么样的数据需要在提示词里描述。
]
})
//接下来的部分和普通的vue组件一样
</script>
<template>
<div class="init-select">
使用$emit向AI发送数据
<div @click="$emit('sentAi',{...item})" v-for="item in tool_data" class="button">{{item.label}}</div>
</div>
</template>
<style scoped lang="scss">
.init-select{
max-height: 600px;
//根容器需要一个overflow: hidden,否则即使没有被调用也会显示,可以用来调试
overflow: hidden;
.button{
width: 100%;
background: #c0d7f6;
padding: 8px 16px;
border-radius: 64px;
color: #2b2677;
font-size: 16px;
transition-duration: 300ms;
cursor: pointer;
&:hover{
background: #b4cbec;
}
&:not(:last-child){
margin-bottom: 6px;
}
}
}
</style>
现在AI可以唤起对话框了,可以看到我们编写的组件会被渲染至消息中间。
还是一样建立文件夹和新建文件
编写提示词,这里是共用了gotoUrl工具
## 前往AI模型基础配置页面
tool_name:gotoUrl
data:{name:'AiModelSetting',query:{tabindex:number,highlight:number}}
说明:
- tabindex为0时为模型基础配置:apiKey与模型配置(0)在此处
- tabindex为1时为调用配置:调试模式开关(1),模型输出语言(2),总失败重试次数(3),单项任务失败重试次数(4)在此处
- highlight:高亮对应的控件
像普通页面一样编写就行
<script>
import Vue from 'vue'
import Prompt from '!!raw-loader!./prompt.md'
export default Vue.extend({
name: "aiModelSetting",
data() {
return {
type: 'page', //类型,必填
parent: 'Ai', //父页面,Ai页面是由系统插件建立的
router: { //这个页面的路由注册信息,必填
path: '/AiModelSetting',
name: 'AiModelSetting',
meta: {
title: '员工基础配置',
affix: false,
roles: ['ai.model.seo']
}
},
prompt:Prompt, //提示词,必填
},
methods:{
runWork(){
//通过事件总线向Ai发送消息
this.$bus.$emit('runWork',{})
}
}
})
</script>
然后页面将会被自动注册。不过因为页面注册晚于vue初始化,所以地址是无法直接通过链接跳转的。
先建立好插件的目录结构
扩展AI技能的编写方式与扩展AI能力是一样的,只有type不同。
data() {
return {
type: 'task',
prompt:'',
}
},
因为AI技能不能由AI自行执行,需要先编写一个用户交互扩展,编写相关的操作逻辑。然后在界面上使用runWork将任务发送至任务队列。当处理完成后使用sentAi通知AI用户已完成操作。
<template>
<div class="init-translate">
<div v-for="(item,index) in tool_data" class="item">
<span>{{item.title}}</span>
<div class="button-list">
<div @click="delWork(index)" class="button">放弃</div>
<div @click="startWork('translate',index)" class="button">翻译</div>
</div>
</div>
<div class="button-list">
<div @click="delAllWork" class="button">翻译余下任务</div>
<div @click="startAllWork('translate')" class="button">优化余下任务</div>
</div>
</div>
</template>