前言#
首先先来推荐一下 Robot 社区中脚哥的一篇对于 MyShell 入门教程「MyShell 工具类 bot 创作指导」。
教哥的这篇入门教程提供了一份关于如何在 MyShell 平台上创作工具类 bot 的指南。MyShell 是一个去中心化的生成式 AI 创作者平台,提供多种 AI 大模型供用户免费使用。作者分享了自己从 ChatGPT 转向 MyShell 的经验,强调了 MyShell 的优势,包括免费使用多种 AI 大模型、避免封号风险、获取积分奖励、社区支持以及节省成本。文章还介绍了如何编写有效的提示词(prompt)、定义角色、规则和工作流,以及如何选择模型和强化 prompt。
此外,脚哥分享了自己创作的一些工具类 bot,提供了有关如何测试、宣传和展望未来的建议。最后,文章介绍了 Claude3 模型的提示词编写技巧,包括使用 XML 标签和标记输入变量。
在我们使用 MyShell 来创造角色 Bot 的时候,掌握以上内容已经可以大体上来实现我们的角色。但美中不足的是,AI 在很多流程上是不可控的,我们在构建一个 Bot 的时候同样地也需要一些程序逻辑,以便于我们控制 Bot 在和用户交互时候的流程。
如此,正式本文将要讲述的 Pro Config 模式。这个模式将会平衡编程逻辑与 AI 提示逻辑交互的灵活方法。
Hello World#
第一个例子#
由于 Pro Config 模式与编程逻辑很像,所以也希望你有一定的代码基础,这样你会对 Pro Config 的描述 JSON 快速上手,并实现开发。
我们以一个 Coder 的习惯,快速进行一个 Hello World 实践。
{
"type": "automata",
"id": "hello_demo",
"initial": "home_page_state",
"inputs": {},
"outputs": {},
"transitions": {},
"states": {
"home_page_state": {
"inputs": {},
"tasks": [],
"outputs": {},
"render": {
"text": "Hello World! Welcome to this demo. Click 'Start' to chat!",
"buttons": [
{
"content": "Start",
"description": "Click to Start.",
"on_click": "start_demo"
}
]
},
"transitions": {
"start_demo": "home_page_state"
}
}
}
}
我们按照以上配置输入进我们 Bot 的开发者模式,会得到以下效果:
下面来解释一下上述 JSON 的含义是什么:
- 首先,我们定义这一段 JSON 就是一个自动机(Automata),在 Pro Config 中每个自动机都可以使用 JSON 来定义;
- 在这个自动机中,我们定义了 Bot 需要输出什么样的文案,即
text
字段;定义了一个 Button,在on_click
自动中,定义了点击后将转移到什么状态;
至此,我们完成了对于 Pro Config 模式的 Hello World 事例的编写。
原子态(AtomicState)与自动机(Automata)#
在上文的 Hello World 事例中,我们已经大概了解了什么是自动机。概括一下,他就是用来控制 Bot 进入不同状态的一个抽象。
下面我们来介绍一下原子态(AtomicState)的概念。用最简单的话来描述它和自动机的关系,就是一个自动机可以包含不同的原子态。如果说自动机是用来描述不同状态直接的切换关系,那么原子态就是用来描述某个复杂状态的抽象。
这里先简单了解下具有这样的概念,后文用到的时候将详细介绍。
当然如果你想了解更多,可以直接看 MyShell 的官方文档。
定义输入 / 输出#
在上面的 Hello World 事例中,我们定义的原子态处了我们使用的 text
字段和 Button
字段,我们看到还有其他的字段。
下面我们来介绍一下 inputs
和 outputs
字段的作用。
Talk is cheap,我们直接来看以下代码:
{
"type": "automata",
"id": "hello_demo",
"initial": "home_page_state",
"inputs": {},
"outputs": {},
"transitions": {},
"states": {
"home_page_state": {
"inputs": {
"intro_message": {
"type": "text",
"user_input": true,
"default_value": "Hi, this is your Pro Config Tutorial Bot"
},
"tts_widget_url": {
"type": "text",
"user_input": true,
"default_value": "https://app.myshell.ai/widget/mEjUNr"
}
},
"tasks": [],
"outputs": {
"intro_message": "{{intro_message}}",
"voice_id": "{{tts_widget_url}}"
},
"render": {
"text": "Hello Word! Welcome to this demo. Click 'Start' to chat!",
"buttons": [
{
"content": "Start",
"description": "Click to Start.",
"on_click": "start_demo"
}
]
},
"transitions": {
"start_demo": "home_page_state"
}
}
}
}
将代码直接覆盖掉之前 Hello World 的代码,我们会发现在用户点击 Start Button 后,会弹出一个交互表单:
这个表单就是我们通过上面的代码实现的效果。我们来解读下部分关键性代码的含义:
- inputs:这里我们设置了
intro_message
和tts_widget_url
两个字段,其实就是 Input 两个文本框的 Title,其中有type
字段是text
代表这是一个文本框,user_input
表示是否要用户输入,default_value
是预设值。
当我们如此设置后,用户填写完表达点击 save 之后,就会将输入值保存成 intro_message
和 tts_widget_url
两个变量,我们在其他的表达式可以使用变量表达式 {{<variable>}}
进行引用。
- outputs:这个变量就是用户填写完表达后,按照我们的文本模版向 Bot 发起的会话内容。就像这样:
由于我们上文已经说到了,可以使用 {{<variable>}}
的方式将我们构建的变量引用进来,其他也没有什么难度,相信你一看便知。
MyShell 官方使用双大括号
{{expression}}
来包裹表达式,以将输出变量的值赋给它。这个表达式应该使用 JavaScript 语言编写,遵循 ECMAScript 5.1 标准,因为 MyShell 目前只支持这个版本。
构建工作流(Workflow)#
制作一个 Chatbot#
在 Pro Config 中,工作流(Workflow)可以将多个模块连接,从而完成我们需要处理的事件。下文我们将用一个 Chatbot 例子来解释工作流的使用方法。
{
"type": "automata",
"id": "chat_demo",
"initial": "chat_page_state",
"inputs": {},
"outputs": {},
"transitions": {},
"states": {
"chat_page_state": {
"inputs": {
"user_message": {
"type": "IM",
"user_input": true
}
},
"tasks": [
{
"name": "generate_reply",
"module_type": "AnyWidgetModule",
"module_config": {
"widget_id": "1744214024104448000",
"system_prompt": "You are a teacher teaching Pro Config.",
"user_prompt": "{{user_message}}",
"output_name": "reply"
}
},
{
"name": "generate_voice",
"module_type": "AnyWidgetModule",
"module_config": {
"content": "{{reply}}",
"widget_id": "1743159010695057408",
"output_name": "reply_voice"
}
}
],
"render": {
"text": "{{reply}}",
"audio": "{{reply_voice}}"
},
"transitions": {
"CHAT": "chat_page_state"
}
}
}
}
这个代码会实现一个 Pro Config Teacher 角色。
工作流解析#
我们逐一来解释一下每一个模块的含义:
"inputs": {
"user_message": {
"type": "IM",
"user_input": true
}
}
在 inputs 模块中,type
我们定义为 IM
,即即时消息类型。这个类型说明 Bot 能够接受以发送给 Bot 的消息形式的输入。
"transitions": {
"CHAT": "chat_page_state"
}
接下来我们立即来看这个状态转换的定义 transitions
。在这里,我们将事件 CHAT
直接设置成上文定义的 chat_page_state
。这个意思就是当用户在聊天中发送消息时,状态会重新价值,发送的消息将作为 input 传入给这个状态。然后将 user_message
将传递到 task
中。
"tasks": [
{
"name": "generate_reply",
"module_type": "AnyWidgetModule",
"module_config": {
"widget_id": "1744214024104448000",
"system_prompt": "You are a teacher teaching Pro Config.",
"user_prompt": "{{user_message}}",
"output_name": "reply"
}
},
{
"name": "generate_voice",
"module_type": "AnyWidgetModule",
"module_config": {
"content": "{{reply}}",
"widget_id": "1743159010695057408",
"output_name": "reply_voice"
}
}
]
接下来我们来看 tasks
部分。这个部分包含了多个待执行 module
,对于每个 module
,我们都需要指定 module_type
和 module_config
。name
是 Optional 的选项,不是必填字段。
为了演示,在第一个 task 中,我们给了一个预置的 prompt - "You are a teacher teaching Pro Config."
,将这个 prompt 给到我们的 Bot,从而指定它的角色。
在第二个 task 中国呢,我们想去发一个回复的语音。这时候我们可以用到 MyShell 的 TSS Widget,就可以设置一个语音回复。如果你有更喜欢的 TSS 音色想使用,可以在 MyShell 的 workshop 中去寻找,通过它的 widget_id
引入即可完成使用。
这里我简单介绍了两种用于回复的 module ,如果你对处理事件的 module 感兴趣,可以访问官方文档来研究 module 模块。
在两个 task 执行完成后,则会根据我们的定义,产生两个变量 reply
和 reply_voice
,并准备好后,通过以下定义呈现给用户:
"render": {
"text": "{{reply}}",
"audio": "{{reply_voice}}"
}
在整个流程中,我们注意到其实 Bot 还默认的处理了一个 “黑盒” 事件 - CHAT
特殊事件。正因为执行了这个特殊事件,才能按照我们的规则进行转移到 chat_page_state
并执行对应的 task。
相信通过这个例子,你已经可以理解了使用 Pro Config 的 Bot 大致的全部工作流,当你学会这个之后就已经可以开始编写自己的 Bot,并实现一个大致的处理框架。
总结#
通过本文的介绍,我们了解了 MyShell 平台上 Pro Config 模式的基本概念和应用方法。通过一个 Hello World 实例和一个 Chatbot 实例,展示了如何使用 Pro Config 模式中的自动机(Automata)和原子态(AtomicState)来控制 Bot 进入不同状态,并处理用户输入和输出。通过这些例子,我们不仅能够快速上手 Pro Config 模式,还能够深入理解其工作原理。
在下一篇,我们将继续讨论一些细节字段,例如如何具体定义 transitions
、表达式和变量的具体使用方式、如何集成其他的 Widget 等等。共勉。
Reference#
另外,希望更多的开发者来参加 MyShell 的 Bot 市场共建,邀请的连接点击这里。后续将会有更多的 Airdrop 活动等你来参与。