MyShell 进阶 - 入门 Pro Config

前言

首先先来推荐一下 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 实践。

Copy
{
"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，我们直接来看以下代码：

Copy
{
"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 例子来解释工作流的使用方法。

Copy
{
"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 角色。

工作流解析

我们逐一来解释一下每一个模块的含义：

Copy
"inputs": {
"user_message": {
"type": "IM",
"user_input": true
}
}

在 inputs 模块中，type我们定义为 IM ，即即时消息类型。这个类型说明 Bot 能够接受以发送给 Bot 的消息形式的输入。

Copy
"transitions": {
"CHAT": "chat_page_state"
}

接下来我们立即来看这个状态转换的定义 transitions。在这里，我们将事件 CHAT 直接设置成上文定义的 chat_page_state。这个意思就是当用户在聊天中发送消息时，状态会重新价值，发送的消息将作为 input 传入给这个状态。然后将 user_message 将传递到 task 中。

Copy
"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，并准备好后，通过以下定义呈现给用户：

Copy
"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 创作指导」

「Pro Config Mode(beta) Origin Docs」

另外，希望更多的开发者来参加 MyShell 的 Bot 市场共建，邀请的连接点击这里。后续将会有更多的 Airdrop 活动等你来参与。