readme.md 8.5 KB

AI助手

快速安装

依赖

安装前需要补全依赖库。

package.json

"dependencies": {
	"@google/genai": "^0.13.0",
	"vue-router": "^3.5.2",
}
"devDependencies": {
	"raw-loader": "^4.0.2",
}

事件总线

需要在Vue对象新建前安装事件总线用于跨组件通信。

main.js

Vue.prototype.$bus = new Vue()
new Vue({
  
})

引用入口组件

然后在合适的位置引入这个组件

index.vue

<template>
    <ai-helper></ai-helper>
</template>
<script>
    import AiHelper from "@/aiHelper/index.vue";
    export default {
      name: 'AppMain',
      components: {
        AiHelper
      }
    }
</script>

引入完成

不出意外助手已经成功引入了

recording

目录结构

系统插件和普通插件本身并无区别。一般与业务无关的可通用的插件放置在系统插件的目录,业务相关的插件放在最外层的插件目录。此外,系统插件会先于普通插件加载。

Clip_2025-08-05_15-02-07

整体结构

整个助手是由一个个插件组合而成,每个插件相互独立,分别为助手提供不同的能力。

扩展AI能力

AI能力本质是一个JS方法,AI会自行判断并且自由调用这些方法。为了安全起见AI能力只能编写一些数据获取的方法,扩展保存数据的能力将在扩展AI技能部分讲到。

我们以一个获取当前时间的能力为例子介绍如何扩展AI能力。

AI模型本身是不能联网的,所以它无法获取到目前的时间。我们可以为AI扩展这个能力。

Clip_2025-08-05_16-14-13

因为获取时间是一个通用的能力,与具体业务无关,所以在system/plugin下新建插件。首先建立一个插件文件夹。

Clip_2025-08-05_16-16-28

再依次建立两个文件,prompt.md用于存放提示词,tool.vue用于编写代码。

Clip_2025-08-05_16-18-46

根据以下格式编写提示词

prompt.md

## 获取当前时间
获取当前的系统时间。utc属性为true时返回utc时间,为false时返回本地时间。
tool_name:getCurrentTime
data:{utc: boolean}

根据以下格式编写代码

tool.vue

<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>

现在回到助手再试一下,已经可以正常获取当前时间了。

Clip_2025-08-05_16-37-59

Clip_2025-08-05_16-39-02

扩展用户交互

可以编写vue组件来丰富AI与用户的交互。

这里以AI对话框为例子,介绍如何扩展用户交互。

与扩展能力一样,先建立文件夹和两个文件。

Clip_2025-08-05_16-47-46

编写提示词

prompt.md

## 展示选项对话框
展示一个选项对话框,然后你能获取到用户选择的选项,使用此工具时需要在context中解释这个操作。
tool_name:initSelect
data:[{label:string,value:string}]
说明:data中需要至少一项

编写组件

index.vue

<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可以唤起对话框了,可以看到我们编写的组件会被渲染至消息中间。

Clip_2025-08-05_16-59-20

添加附属页面

还是一样建立文件夹和新建文件

Clip_2025-08-05_17-05-28

编写提示词,这里是共用了gotoUrl工具

prompt.md

## 前往AI模型基础配置页面
tool_name:gotoUrl
data:{name:'AiModelSetting',query:{tabindex:number,highlight:number}}
说明:
- tabindex为0时为模型基础配置:apiKey与模型配置(0)在此处
- tabindex为1时为调用配置:调试模式开关(1),模型输出语言(2),总失败重试次数(3),单项任务失败重试次数(4)在此处
- highlight:高亮对应的控件

像普通页面一样编写就行

model.vue

<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初始化,所以地址是无法直接通过链接跳转的。

Clip_2025-08-05_17-18-49

扩展AI技能

先建立好插件的目录结构

Clip_2025-08-05_17-30-02

扩展AI技能的编写方式与扩展AI能力是一样的,只有type不同。

task.vue

data() {
    return {
      type: 'task',
      prompt:'',
    }
  },

因为AI技能不能由AI自行执行,需要先编写一个用户交互扩展,编写相关的操作逻辑。然后在界面上使用runWork将任务发送至任务队列。当处理完成后使用sentAi通知AI用户已完成操作。

task.vue

<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>