-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
如何添加一个新的 AI 对话机器人
为 ChatALL 增加新的 AI 对话机器人,最简单情况只需要三步:
- 在
src/bots/
,复制TemplateBot.js
创建一个XXXXBot.js
文件 - 在
XXXXBot.js
中实现_sendPrompt()
- 把对
XXXXBot.js
的引用添加到src/App.vue
中
下面开始一步步介绍。假定已经 clone 了最新代码。
假定你要支持的 AI 大模型叫「KnowNothing」,那么按以下步骤可以快速跑起一个 Hello world。
在 src/bots/
,复制 TemplateBot.js
创建一个 KnowNothingBot.js
文件。
修改 KnowNothingBot.js
的类名和前两个成员变量的初始值如下:
export default class KnowNothingBot extends Bot {
static _brandId = "KnowNothing"; // Brand id of the bot, should be unique. Used in i18n.
static _className = "KnowNothingBot"; // Class name of the bot
...
修改 src/App.vue
,找到如下代码:
// Bots
import ChatGPT35Bot from "./bots/ChatGPT35Bot";
import ChatGPT4Bot from "./bots/ChatGPT4Bot";
import BingChatPreciseBot from "./bots/BingChatPreciseBot";
import BingChatBalancedBot from "./bots/BingChatBalancedBot";
import BingChatCreativeBot from "./bots/BingChatCreativeBot";
import SparkBot from "./bots/SparkBot";
import BardBot from "./bots/BardBot";
import OpenAIAPI35Bot from "./bots/OpenAIAPI35Bot";
import OpenAIAPI4Bot from "./bots/OpenAIAPI4Bot";
import MOSSBot from "./bots/MOSSBot";
import WenxinQianfanBot from './bots/WenxinQianfanBot';
任意位置增加一行:
import KnowNothingBot from './bots/KnowNothingBot';
再找到:
bots: [
ChatGPT35Bot.getInstance(),
ChatGPT4Bot.getInstance(),
OpenAIAPI35Bot.getInstance(),
OpenAIAPI4Bot.getInstance(),
BingChatCreativeBot.getInstance(),
BingChatBalancedBot.getInstance(),
BingChatPreciseBot.getInstance(),
WenxinQianfanBot.getInstance(),
SparkBot.getInstance(),
MOSSBot.getInstance(),
BardBot.getInstance(),
],
把你的 bot 放进去。注意,这里对各个 bot 的引用顺序,决定了它们在图标栏出现的顺序。比如,你希望你的 bot 在 ChatGPT 和 Bing Chat 之间,那么:
bots: [
ChatGPT35Bot.getInstance(),
ChatGPT4Bot.getInstance(),
KnowNothingBot.getInstance(), // You are here
OpenAIAPI35Bot.getInstance(),
OpenAIAPI4Bot.getInstance(),
...
],
是的,hello world 已经完成了。在项目目录下,执行下面命令(假定你已经安装了 npm):
npm install
npm run electron:serve
图标栏里看到它了吗?选择它,然后发个消息试试吧!
需要在设置组件里实现登录、API key 配置等功能,这是完成其它核心功能的基础。但如果你的 bot 不需要登录,或者不在意把 key 直接放到代码里(非常不建议这么做),那么可以跳过本节。
设置组件要建在 src/components/BotSettings/
下,文件名是 KnowNothingBotSettings.vue
。
现有的设置组件可以当做模板:
- 如果只需要登录能力,那么可以复制
BardBotSettings.vue
,修改import Bot from "@/bots/BardBot";
为import Bot from "@/bots/KnowNothingBot";
就完工了。(有些网站做了不少安全防范阻止 ChatALL 之类的客户端访问。如果遇到这种情况,那要做很多 hack 工作) - 如果只需要配置 key,那么可以复制
WenxinQianfanBotSettings.vue
,但要做的工作就有点儿多了。 - 如果有复杂的多项配置,那么要做的工作就更多了。
ChatALL 的设置组件使用 Vuetify 3 实现。访问官方文档可以查看和测试它支持的丰富组件。通过参考已有代码,基本可以完成开发工作,这里不再赘述。
ChatALL 的设置参数通过 vuex-persist
库保存在 local storage 中。这个库很好用,虽然文档不太好读。简要介绍下怎么用。
首先,在 src/store/index.js
中添加两段代码:
export default createStore({
state: {
...
knowNothing: {
setting1: "",
setting2: "",
},
...
},
mutations: {
...
setKnowNothing(state, { setting1, setting2 }) {
state.knowNothing = { setting1, setting2 };
},
...
},
...
});
setting1
和 setting2
可以根据你的情况进行任意增删修改,包括建立下级对象。但一定在最顶层是个 knowNothing
对象,哪怕只有一个配置项。
然后在 KnowNothingBotSettings.vue
中,添加:
export default {
...
methods: {
...mapMutations(["setKnowNothing"]),
setSetting1(value){
this.setKnowNothing({
...this.knowNothing,
setting1: value
})
},
setSetting2(value){
this.setKnowNothing({
...this.knowNothing,
setting2: value
})
},
},
computed: {
...mapState(["knowNothing"])
}
}
最后,把 Vuetify 组件的 v-model
指向对应的 knowNothing.xxx
,生效动作指向对应的 setXxx()
函数。例如:
<v-text-field
v-model="knowNothing.setting1"
@change="setSetting1($event.target.value)"
></v-text-field>
完工!运行后,打开 DevTools,可以在 Application 下查看存储是否正确。
在 KnowNothingBot.js 中使用设置的参数非常简单:
...
import store from "@/store";
...
store.state.knowNothing.setting1
store.state.knowNothing.setting2
const { setting1, setting2 } = store.state.knowNothing;
...
ChatALL 会在首次启动、页面刷新(Command+R 或 Ctrl+R)和完成设置等时,调用此函数,来刷新这个 bot 的可用状态。
一般情况,它完成如下工作:
- 检查登录是否有效
- 检查 API key 是否配置正确
- 检查其它影响运行的条件是否满足
如果一切正常,要执行:
this.constructor._isAvailable = true;
否则执行:
this.constructor._isAvailable = false;
最后一定要:
return this.isAvailable();
这是最核心的功能,完成发送和接收消息。
现有代码是不错的参考:
- 如果接口是普通 http 调用,可以参考
BardBot.js
- 如果接口是 SSE,可以参考
ChatGPTBot.js
- 如果接口是 WebSocket,可以参考
BingChatBot.js
发送消息和解析接收到的消息要根据 bot 的具体情况而处理。得到响应,或者出错了,要这么处理:
- 收到返回的部分文本,调用
onUpdateResponse(text, callbackParam, false);
- 如果返回数据中并不包含目前为止的所有文本,而是每次只返回最新的那部分,需要自己完成所有文本的拼装,再调用
onUpdateResponse
- 得到所有文本后,调用
onUpdateResponse(text, callbackParam, true);
完成所有数据的更新。如果文本之前已经都onUpdateResponse
过,那么调用onUpdateResponse(null, callbackParam, false);
可以达到同样效果 - 正常结束,最后调用
resolve()
- 如果出错,需要调用
reject(error)
。这个error
既可以是个异常,也可以是个错误信息字符串。ChatALL 会自动处理它,把它显示给用户
ChatALL 将来会实现历史消息保存功能,且支持多个 chat/thread/session/conversation(随便叫哪个)。实现 createConversation()
主要是为了兼容未来,现在不做也可以。
所以,这段就不写了吧……
图标文件放到 src/assets/bots/knownothing-logo.png
,修改 KnowNothingBot.js
:
static _logoFilename = "knownothing-logo.png";
多语言资源放在 src/i18n/locales
下,用语言代码命名的 .json 文件中。你需要至少为你的 bot 添加:
en.json
"knowNothing": {
"name": "Know Nothing"
},
zh.json
"knowNothing": {
"name": "啥都不懂"
},
以及其它字符串。
在 JavaScript 代码里这样调用多语言:
import i18n from "@/i18n";
...
i18n.global.t("knowNothing.stringName")
...
在 HTML 代码里是这样:
{{ $t("knowNothing.stringName") }}
有些网站会限制特定浏览器才能访问,所以需要在 KnowNothingBot.js
中:
static _userAgent = "THE_RIGHT_USER_AGENT";
没了...欢迎提交 PR!