[译]使用Oscova在C#中创建本地脱机Bot
By robot-v1.0
本文链接 https://www.kyfws.com/ai/creating-an-on-premise-offline-bot-in-csharp-using-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 27 分钟阅读 - 13159 个词 阅读量 0使用Oscova在C#中创建本地脱机Bot(译文)
原文地址:https://www.codeproject.com/Articles/5258706/Creating-an-On-Premise-Offline-Bot-in-Csharp-using
原文作者:DaveMathews
译文由本站 robot-v1.0 翻译
前言
Using Oscova and Oryzer FBP platform, we’ll build an on-device table reservation bot to understand the concepts behind today’s offline bot development standards.
使用Oscova和Oryzer FBP平台,我们将构建一个设备上的表预订机器人,以了解当今离线机器人开发标准背后的概念.
In this post, we are going to create a Table Reservation Bot and for it, I’ll be using freely available tools, especially a freely available Flow-Based Programming platform called Oryzer Studio and will make an attempt to drive the audience through the concepts one step at a time. By the end of the article, we would have successfully created a table reservation bot, tested it in Oryzer and even imported it into a Console app.
在这篇文章中,我们将创建一个Table Reservation Bot,为此,我将使用免费提供的工具,尤其是一个名为Oryzer Studio的免费提供的基于流程的编程平台,并将尝试通过这些概念来吸引观众一步一步来.到本文结尾,我们将成功创建一个表预订机器人,并在Oryzer中对其进行测试,甚至将其导入控制台应用程序.
- 下载bot-csharp-project.zip-91.9 KB(Download bot-csharp-project.zip - 91.9 KB)
- 下载bot-workspace-project.zip-7.5 KB(Download bot-workspace-project.zip - 7.5 KB)
介绍(Introduction)
之前(前一段时间),我解释了如何使用bot接口与他们的数据库对话.在本文中,我们将浏览具有最少后端编码开销的脱机(设备上/本地)机器人的一般概念.(Previously (a while back), I explained how one can talk to their database using a bot interface. In this article, we’ll skim through the general concepts of an offline (on-device / on-premise) bot with the least amount of backend coding overheads.)
我们将创建一个(We are going to create a)**餐桌预订机器人(Table Reservation Bot)**为此,我将使用免费提供的工具,尤其是一个名为Oryzer Studio的免费提供的基于流程的编程平台,并将尝试一次一步地使观众了解这些概念.但是,我将尽量避免在此处直接发布链接,因此您可能需要在此处和此处进行一些谷歌搜索.尽管我会尽量减少这种情况.(and for it, I’ll be using freely available tools, especially a freely available Flow-Based Programming platform called Oryzer Studio and will make an attempt to drive the audience through the concepts one step at a time. I’ll however try to refrain from directly posting links here so you might have to do a little bit of Googling here and there. Although I’ll try to minimize such circumstances.)
尽管读者可能对当今的bot架构如何工作有一般的了解,但我仍将尝试介绍一些在Bot开发平台中已广泛建立的基本概念.(Though the audience may have general knowledge of how today’s bot architectures work, I’ll still try to introduce some of the basic concepts that are now widely established among Bot development platforms.)
背景(Background)
在深入探讨之前,我强烈建议读者看一下我以前的文章,其中我创建了一个用于与数据库交互的Bot.本文重点介绍了本文中使用的许多基本概念.(Before diving in, I highly recommend that the audience takes a look at my previous article where I created a Bot for interacting with a database. The article highlights a lot of basic concepts that are used in this article.)
- 使用Oscova构建数据库Bot(Build a Database Bot using Oscova) 本文内容非常全面,带您了解Bot Development,WPF GUI的基础知识,设置数据库实用程序类以及将bot的操作绑定到数据库.(The article is quite comprehensive and takes you through the basics of Bot Development, WPF GUI, setting up a database utility class and binding the bot’s actions to a database.)
先决条件(Prerequisites)
要启动并运行,您必须具有以下技能,或者可能需要稍加磨练才能快速阅读本文.(To fire up and get running, you’ll have to have the following skill sets or maybe you’ll have to polish them a little bit to get through the article swiftly.)
-
基于流的编程构造知识(组件/节点,端口和连接)(Knowledge of Flow-based Programming constructs (Components/Nodes, Ports and Connections))
-
在Visual Studio中工作的知识(Knowledge of working in Visual Studio)
-
C#/.NET编程的基本知识(Basic knowledge of programming in C#/.NET)
-
Bot架构的基础知识(Basic knowledge of Bot architectures) 对于本文,您只需要以下内容:(For this article, you’ll just need the following:)
-
Visual Studio 2019社区版(Visual Studio 2019 Community Edition) 或以上(or above)
-
Oryzer Studio(Oryzer Studio) for Workspace-可免费使用的基于流程的编程平台(for Workspace - Freely available flow-based programming platform)
术语(Terminologies)
在本文的整个过程中,我可能会使用以下术语及其缩写形式(缩写),为了更好地理解,建议您熟悉一下.(I may use the following terms and their short-forms (acronyms) throughout the course of this article and for better comprehension, I recommend that you familiarize yourself with it.)
- 知识库(KB)-Bot可以进行对话的集合.(Knowledge-Base (KB) - A collection of dialogues the Bot can engage with.)
- 组件/节点-这些术语在整篇文章中可以互换使用.(Components/Nodes - These terms maybe used interchangeably throughout the article.)
- 基于流的编程(FBP)-一种编程结构,其中通过连接功能组件来构建逻辑.(Flow-based programming (FBP) - A programming construct where logic is built by connecting functional components.)
- 工作区-一种将您的节点放置在其中并与其他节点连接的图形画布.(Workspace - Sort of a graph canvas where your nodes will be placed and connected with other nodes.)
文章的方法(Article’s Approach)
为了简洁和介绍基于流程的编程,我们将使用Oryzer Studio来开发Bot基本交互的框架知识库,而不是使用任何编程语言对机器人进行脚本化或硬编码.(Instead of scripting or hard coding the bot in any programming language, we will for the sake of brevity and introduction to Flow-Based Programming, use Oryzer Studio to develop a skeleton knowledge-base of our Bot’s basic interactions.)
成功建立Bot的知识库(KB)之后,我们将在Oryzer Studio本身中进行测试,然后将KB导入简单的C#Console应用程序中.(Once we’ve successfully built the knowledge-base (KB) of the Bot, we will test in within Oryzer Studio itself and later import the KB into a simple C# Console application.)
由于本文可能涉及很多FBP,因此我将采用以下方法进行澄清:(As this article may have a lot of FBP involved, I’ll take the following approach for clarification:)
- 说明要添加/使用的组件(Explain the component being added/used)
- 初步解释连接组件的步骤(Verbally explain the steps of connecting components (initially))
- 提供带有屏幕截图的可视提示,以显示组件的连接方式.(Provide a visual cue with a screenshot that shows how components are connected.) 机器人开发背后的行业和研究已经标准化.在本文中,我们将学习有关机器人开发的一些常见术语.像对话框,意图,上下文和实体.(The industry and research behind bot development is getting a bit standardized. In this article, we’ll learn some of the common terms circulating around bot development. Like Dialogs, Intents, Contexts and Entities.)
让我们开始吧(Let’s Get Started)
假设您已下载(Assuming you’ve downloaded)Oryzer Studio(Oryzer Studio)从上面提到的链接开始,首先创建一个对话框.(from the link mentioned above, let’s get started by first creating a Dialog.)
为了创建此漫游器,我们将在对话流程中从用户收集以下信息:(In order to create this bot, we’ll collect the following information from the user during the conversation flow:)
- 预定的日期(The date for which the reservation is to be made)
- 时间安排(早餐,午餐或晚餐)(The timing (Breakfast, Lunch or Dinner))
- 可供预订的人数(Number of people to reserve the table for)
- 用户号码确认预订(User number to confirm the reservation)
对话框(greet_dialog)(Dialog (greet_dialog))
对话是意图的集合,更像是对话主题.例如,如果您的机器人必须说"嗨",“你好”,“嘿”,您可以将它们分组到一个名为(A dialog is a collection of intents, more like a topic of conversation. For example, if your bot has to say Hi, Hello, Hey there, you’ll group them into a dialog named) Greetings
.对话是在唯一标识符下将相似意图分组的好方法.(. A dialog is a good way to group similar intents under a unique identifier.)
创建对话框:(To create a dialog:)
- 启动Oryzer Studio.(Launch Oryzer Studio.)
- 展开(Expand the)奥斯科瓦(Oscova)右侧"节点资源管理器"中的"类别".(category from the right Node Explorer.)
- 选择(Select the)对话(Dialog)节点并将其拖动到工作区.(node and drag it onto the Workspace.)
- 如果您不小心拖动了错误的节点,只需按一下(If you accidentally dragged a wrong node, simple press)删除(Delete)并应将其移除.(on it and it shall be removed.) 您刚刚拖动的是一个节点,将其拖动到的位置称为工作区.(What you’ve just dragged is a Node and to where you’ve dragged it is called the Workspace.)
一种(A)节点(Node)在Oryzer Studio中,它是执行特殊任务的功能单元.节点包括:(in Oryzer Studio is a functional unit that performs a specialized task. A Node comprises:)
- 输入端口-左侧的蓝色框(Input Ports - The blue boxes on the left)
- 输出端口-右侧的蓝色框(Output Ports - The blue boxes on the right) 输入口(Input ports)通常存储某些变量值,这些变量值使节点能够执行其专门任务.(usually store certain variable values that enable a node to perform its specialized task.)
输出口(Output ports)另一方面,当节点完成执行任务时,返回该节点的值.或者在某些情况下,输出端口也可以是Node本身.(on the other hand, are returned values of a Node when it has completed performing a task. Or in some cases, the output port can also be the Node itself.)
因此,我们现在创建了一个Dialog节点,该节点将帮助我们开始与用户进行对话,并提供用于保留表的第一组选项.(So we’ve now created a Dialog node that will assist us in starting a dialogue with our user and provide the first set of options for reserving a table.)
您可以看到"对话框"节点具有几个"输入和输出端口":(You can see that the Dialog node has a couple of Input and Output Ports:)
- 输入端口-(Input Ports -)
Name
,(,)Intent Alias
,(,)Domain
和(and)Intents
- 输出端口-(Output Port -)
(self)
-返回节点本身作为输出(- Returns the node itself as an output) 我们将此对话框称为(We’ll call this dialog the)greet_dialog
然后将2个意图连接到该意图要在对话框中命名对话框(and we’ll connect 2 intents to it. To name the dialog in the)Name
端口,只需键入(port, simply type)greet_dialog
.(.)
通过按保存此工作区(Save this workspace by pressing)CTRL + S(CTRL+S)并命名文件(and naming the file)table-reservation-bot.west(table-reservation-bot.west).(.)
意向(greet_intent)(Intent (greet_intent))
意图是在给定意图的表达式(用户查询示例)匹配时将用户查询绑定到响应以及(可选)将动作绑定到某种东西的东西.为了启动对话,我们将添加一个名为(An intent is something that binds a user query to a response and optionally an action when a given intent’s expression (user query example) matches. In order to initiate our conversation, we’ll add an intent called) greet_intent
给我们(to our) greet_dialog
.(.)
我们的(Our) greet_intent
将向用户打招呼,进行自我介绍,并收集我们进行预订所需的初始信息.(will greet the user, introduce itself a bit and collect the initial set of information we need to proceed with the reservation.)
要将意图添加到对话框,我们将执行以下操作:(To add an intent to a dialog, we’ll do the following:)
- 拖一个(Drag an)
Intent
节点浏览器中的节点(在右侧).(node from Node Explorer (on the right).) - 单击并从输出中拖动(Click and drag from the output)
(self)
的港口(port of the)Intent
节点(node to the)Intents
对话框节点的输入端口.(input port of the dialog node.)
现在,我们已经创建了一个对话框并将意图连接到该对话框.(We’ve now created a dialog and connected an intent to it.)
表达方式(Expressions)
在Bot开发领域,(In the field of Bot development,)**表达式是一组用户查询示例(expressions are sets of user query examples)**帮助机器人引擎训练自己以找到用于相似性检测的模式.您提供的表达式示例数量越多,机器人在检测相似用户查询方面的能力就越强.(that help a bot engine train itself to find patterns for similarity detection. The more the number of expression examples you provide, the better a bot gets in detecting similar user queries.)
表达式将用户查询映射到意图,然后将其映射到响应或动作.为了简洁起见,我们在这里不会添加太多的表达方式,而只是为了说明这个概念而添加几个.(An expression maps a user query to an intent which then maps it to a response or an action. We won’t be adding too many expressions here for brevity but just a couple of them to clarify the concept.)
我们将继续添加4个表达式示例(请记住这些是用户查询的示例).(We’ll go ahead and add 4 expression examples (remember these are examples of user queries).)
-
嗨,您好(Hi there)
-
你好(Hello there)
-
嘿,我可以订一张桌子吗(Hey can I book a table)
-
我想预定一张桌子(I would Iike to book a table please) 现在,将表达式节点添加到工作空间中,并将其连接到上述意图节点:(Now let’s add expression nodes to the workspace and connect them to the aforementioned intent node:)
-
拖动(Drag)
Expression
节点浏览器中的节点.(node from node explorer.) -
在里面(In the)
Value
端口的文本框,为每个新的表达式节点输入上述表达式示例.(port’s text box, enter the above expression samples for each new expression node.) -
连接输出端口(Connect the output ports of the)
Expression
节点(nodes to the)greet_intent
如下图所示:(as shown in the image below:)
现在,我们已经向bot系统提供了一些用户查询示例,我们将必须指定匹配示例查询(表达式)时bot的响应.(Now that we’ve provided some samples of user query to the bot system, we’ll have to specify what will be the response of the bot when an example query (expression) is matched.)
响应(Response)
响应是用户查询与与意图相关联的表达式匹配时调用的操作的一部分.我们已经添加了4个表达式,所以现在如果用户查询与我们添加的表达式之一匹配,我们就添加一个响应.(A response is a part of an action that is invoked when a user query matches an expression that’s associated with an intent. We’ve already added 4 expressions so now let’s add a response if the user query matches one of our added expressions.)
我们的响应将执行以下操作:(Our response is going to do the following:)
- 发送一条文字消息,向您打招呼,并要求用户提供一些信息(Send a Textual message that will greet and ask the user to provide some information)
- 向用户提供选项以快速选择机器人消息的后续响应(Provide options to the user to swiftly select a follow-up response for the bot’s message)
- 设置上下文(Set up a context)创建一个流程(我们将在下一节中了解它)(to create a flow (we’ll learn about it in the next section))
所以现在让我们拖动一个(So now, let’s drag a)
Response
节点并将其连接到(node and connect it to the)greet_intent
如下所示:(as shown below:)
由于我们的第一个任务是添加文本消息,因此我们将拖动另一个名为(Since our first task is to add a textual message, we’re going to drag in another node called the)输入文本(Input Text)节点并将其连接到(node and connect it to the) Text
的港口(port of the) Response
节点.(node.)
文本节点的内容将为:(The content of the text node is going to be:)
文字部分(The Text part)
嗨,您好!我在这里是为了帮助您预订餐桌.(Hi there! I am here to help you book a table.) 因此,让我们先告诉您您什么时候要预定桌子?(So let’s begin by letting me know for when would you like to book a table?)
我们还将添加两个输入选项,以在用户的"提示"框中用竖线分隔它们以显示给用户.(We’ll also add 2 input options to be displayed to the user by separating them with a vertical bar in the Hint box of the) Response
节点(node)
提示部分(The Hint part)
今天|明天(Today|Tomorrow)
除了询问用户何时需要预订外,我们还需要准备另一个意图,以准备接受用户对我们提出的问题的回答.(Apart from asking the user for when they’ll need the reservation for, we’ll need to prepare another intent to be ready to take the answer the user provides to our opening question.)
我们将继续删除(We’ll go ahead and drop a) Context Add
节点并将其连接到响应节点.因此,在调用响应时,将添加相关上下文.(node and connect it to the response node. So when the response is invoked, the relevant context gets added.)
上下文(table-date-con)(Context (table-date-con))
机器人开发中的上下文通常是添加到称为(A context in bot development is usually a string label added to something called the)**聊天会话(chat session)**创建对话的分层流程.这些上下文字符串的存在与否决定了意图的激活.(to create a hierarchical flow of conversation. The existence or non-existence of these contextual strings govern the activation of intents.)
如下所示,我拖放了一个(As seen below, I’ve dragged and dropped a) Context Add
节点并将其连接到(node and connected it to the output port of the) Response
节点.每当意图生成响应时,该节点都会被执行,并且上下文项(node. Whenever a response is being generated by the intent, this node will get executed and a context item) table-date-con
将被添加到会话中,并在接下来的2个用户查询中存在.由于我们选择了(will get added in the session and will exist for the next 2 user queries. As we’ve selected the) Lifespan
的价值(value of) 2
.(.)
目的(table_date_intent)(Intent (table_date_intent))
如果您还记得我们(If you recall in our) greet_intent
的响应,我们已经询问用户何时要保留该表.好吧,如果用户随后指定一个日期,例如(’s response, we’ve asked the user for when he would like to have the table reserved for. Well, if the user then specifies a date like)今天(Today)**要么(or)明天(Tomorrow)**,(,)**我们需要有一个意图去捕捉这一点.(we need to have an intent to capture just that.)
此意图有两个任务要完成:(This intent has a couple of tasks to complete:)
- 捕获用户指定的日期.(Capture the user specified date.)
- 将用户指定的日期值存储在称为(Store the user specified date value in something called a)用户变量(user variable).(.)
- 提示用户指定餐食类型/时间(早餐,午餐或晚餐)(Prompt the user to specify the meal type/timing (Breakfast, Lunch or Dinner))
- 创建另一个名为(Create another context named)
table-time-con
帮助实现跟进意图.(to help enable the follow up intent.) 既然您知道如何拖放,连接节点,那么我将不需要多余地重新解释这样做的步骤.(Now that you know how to drag, drop and connect nodes, I won’t be needing to redundantly re-explain the steps of doing so.)
语境与表达(Context and Expression)
让我们继续并指定此意图需要上下文项(Let’s go ahead and specify that this intent requires that the context term) table-date-con
存在于用户聊天会话中,然后我们继续指定一个表达式,以确保它仅捕获来自用户输入的日期值.(exists in user chat session and then we’ll go ahead and specify an expression that ensures it captures only date values from the user input.)
在上面的屏幕截图中,您可以看到我使用以下名称指定了上下文(In the screenshot above, you can see that I’ve specified a context with the name) table-date-con
,如果您还记得此上下文是我们添加的(, if you may recall this context was added by our) greet_intent
.(.)
现在,通过在该意图中指定上下文名称,我们告诉机器人系统在且仅当该上下文匹配该意图的表达式(Now by specifying the context name in this intent, we are telling the bot system to match this intent’s expressions if and only if the context) table-date-con
存在于用户聊天会话中.(exists in user chat session.)
表达方式(The expression) @sys.date
是与日期匹配的预建系统实体.有关详细信息,请访问Oscova的开发人员门户.您现在可以只搜索那个.(is a pre-built system entity that matches dates. More info on this is available in Oscova’s developer portal. You can just Google that one out for now.)
响应(Response)
此意图的响应包括三个部分:(The response of this intent has three parts to it:)
-
将日期值存储到某个用户变量中(我们将在响应中使用该值).(Store the date value to some user variable (we’ll use the value in our response).)
-
创建新的跟进环境(Create a new follow up context)
table-time-con
这样下一个意图就可以捕获膳食类型.(so that the next intent can capture the meal type.) -
提示用户指定餐食类型.(Prompt the user to specify the meal type.) 为了这:(For this:)
-
拖一个(Drag a)
Response
节点并将其连接到意图(node and connect it to the intent) 首先,我们将继续存储用户指定的日期部分.请注意,只有在用户指定了日期值之后,才调用此意图(Firstly, we’ll go ahead and store the date part specified by the user. Note, this intent is invoked only if the user specifies a date value following the)greet_intent
为此:(To do so:)
- 拖动(Drag)
Entity Get
节点,并将实体类型指定为(node and specify the entity type as)sys.date
- 然后拖一个(Then drag a)
Variable Set
节点并连接(node and connect the)Value
的港口(port of)Entity Get
节点(node to the)Variable Value
的输入端口(input port of the)Variable Set
节点.(node.) - 将变量名称指定为(Specify the variable name as)
table-date
确保在(Make sure that in the) Entity Get
节点的(node’s) Get
属性,您已设置(property, you have set) Value
作为获取类型并在(as the get type and in the) Variable Set
节点选择(node select) User
作为目标.(as the Target.)
瞧!现在设置好了.每当调用此响应节点时,一个名为(Voila! We are now set. Whenever this response node is called, a variable named) table-date
将保存在(will be saved in the)用户变量(user variables).(.)
语境和文本回应(Context and Textual Response)
我们必须为下一个意图添加新的上下文,以捕获膳食类型或时间安排.因此,让我们继续并拖动并连接一个(We’ll have to add a new context for the next intent that will capture the meal type or timing. So let’s go ahead and drag and connect a)上下文添加(Context Add)节点(node to the) call
的输出端口(output port of the)响应节点(Response node).(.)
我们将上下文作为(We’ll have the context as) table-time-con
如以下屏幕截图所示:(as shown in the screenshot below:)
除了为下一个后续意图添加上下文外,我们还将提供文本响应,该文本响应将显示如下消息:(Apart from adding a context for the next follow-up intent, we’ll provide a textual response that will display some message like the following:)
好了,桌子摆在午餐上了,您想来几顿饭?(Alright so the table’s set for Lunch and for which meal would you like to come?)(如果用户指定((If the user specifies)午餐(Lunch)作为用餐类型/时间)(as the meal type/timing))
请注意,我们已经使用(Note that we’ve used) $sys.user.table-date
在我们的回复文字中.这是一个特殊的参数,告诉机器人系统用存储的用户变量(称为"(in our response text. This is a special parameter that tells the bot system to replace the value with a stored user variable called) table-date
.(.)
如果您出于某种原因在机器人的变量集合中存储了一个变量,则参数为(If you, for some reason, stored a variable in the bot’s variable collection, then the parameter would be) $sys.bot.table-date
.(.)
实体创建(Entity Creation)
出于上述目的,我们提供了选择(In the above intent, we are giving the options) Breakfast|Lunch|Dinner
给用户用餐时间.当用户输入以上任一值时,我们需要捕获它.(to the user for meal timing. When the user enters any one of the above values, we’ll need to capture it.)
一个简单的解决方法是将它们简单地转换为已知的实体类型.为了创建一个类型的实体说(An easy workaround here is to simply convert them to a known entity type. In order to create an entity of type say) @meal-type
,我们将按照以下步骤操作:(, we’ll follow the steps below:)
- 拖放(Drag and drop an)
Entity Recognizer
节点.(node.) - 连接(Connect the)
(self)
该节点的输出端口到输入(output port of this node to the input)Recognizer
的港口(port of)Oscova Bot
节点.(node.) - 将实体类型指定为(Specify the entity type as)
meal-type
在里面(in the)Entity Type
端口编辑器.(port editor.)
接下来,通过以下方式为此实体识别器节点指定3个输入值:(Next let’s specify 3 entry values to this Entity Recognizer node by:)
- 拖动3个Entry节点.(Dragging 3 Entry nodes.)
- 指定(Specifying)
Breakfast
,(,)Lunch
和(and)Dinner
作为其输入值.(as their Entry Values.) - 连接他们的(Connecting their)
(self)
输入的输出端口(output port to the input)Entries
的港口(port of the)Entry Recognizer
节点.(node.)
让我们测试一下机器人(Let’s Test the Bot)
到现在为止还挺好.现在我们的两个意图已经准备就绪,我们可以继续尝试与Bot进行交互.为了测试Bot,我们首先必须连接(So far so good. Now that our 2 intents are ready, we can go ahead and try interacting with the Bot. In order to test the Bot, we’ll firstly have to connect the) Dialog
节点(node to an)奥斯科瓦博特(*Oscova Bot*)节点,然后将其连接(*node and then connect this*)奥斯科瓦
博特(Oscova Bot) `` 节点(node to an)Oscova测试面板(Oscova Test Panel)节点.(node.)
连接你的(To connect your) greet_dialog
节点(node to an) Oscova Bot
节点:(node:)
- 只需拖动(Simply drag the)奥斯科瓦`博特(Oscova Bot) `` 对话框节点旁边的节点.(node next to the dialog node.)
- 连接(Connect the)
(self)
对话框节点的输出端口到(output port of the dialog node to the)Dialogs
输入口(input port of)奥斯科瓦`博特(Oscova Bot)节点.(node.)
的(The)奥斯科瓦`博特(Oscova Bot)node是实际代表整个bot的实际节点.该节点具有几个输入端口,您可以将几个其他节点类型连接到这些输入端口.(node is the actual node that represents the bot in entirety. This node has a couple of input ports to which you can connect a couple of other node types.)
现在,让我们将该节点连接到(For now, let’s just connect this node to)Oscova测试面板(Oscova Test Panel)节点以测试我们的漫游器的响应.(node to test the response of our bot.)
连接后(After you’ve connected)奥斯科瓦`博特(Oscova Bot) 和(*and*)Oscova测试面板(*Oscova Test Panel*)
节点:(node:)
- 按(Press)火车机器人(Train Bot)完成培训过程.(to complete the training process.)
- 类型(Type)**嗨,您好(hi there)**您应该会看到我们对选项的第一反应.(and you should see our first response with options.)
- 选择或输入(Select or type)**今天(Today)**并且应该显示第二个意图的响应.(and the second intent’s response should be displayed.)
继续(Moving On)
既然您(最有可能)已经看到并测试了机器人的响应,那么在下一阶段,我们将向其他重要意图迁移,这些意图将捕获用户的一些其他信息.(Now that you’ve (most probably) seen and tested the response of your bot, in this next phase, we’ll migrate towards other important intents that will capture some additional information from the user.)
所以我们采取了(So we’ve taken the)日期(Date)现在要求用户向我们提供(and now have asked the user to provide us with the)膳食(Meal)定时.接下来的两个意图将很简单.他们的任务是:(timing. Our next 2 intents are going to be simple. Their task at hand is to:)
- 记录我们先前意图所要求的用餐时间.(Capture the meal time requested by our previous intent.)
- 要求用户提供表应保留的人数.(Request the user to provide the number of people the table should be reserved for.) 在这两个意图之后,将有我们的最终确认意图,它将向用户显示关闭消息.(After these 2 intents, there will be our final confirmation intent that will display our closing message to the user.)
为了使事情易于理解,我们将限制将更多信息存储在变量中,因为您已经知道该怎么做.因此,添加这样的额外层不会对我们的学习过程有所帮助.(To keep things comprehensible, we’ll limit storing any further information in variables because you already know how to do so. So adding such an extra layer wouldn’t contribute to our learning process.)
对话框(table_config_dialog)(Dialog (table_config_dialog))
从这里开始,它将变得更加简单.再次,让我们添加一个(It’s going to simpler from here point onwards. Again, let’s add a) Dialog
节点到工作区,将其连接(node to the workspace, connect its) (self)
输出端口到(output port to)奥斯科瓦博特(*Oscova Bot*)节点的(*node's*)
Dialogs` 输入端口.(input port.)
在里面(In the) Name
端口编辑器,指定(port editor, specify) table_config_dialog
作为名称.(as the name.)
目的(table_time_intent)(Intent (table_time_intent))
新增一个(Add a new) Intent
节点,命名意图(node, name the intent) table_time_intent
.此意图将捕获我们先前意图所请求的进餐类型(早餐,午餐或晚餐),并将提示用户指定要预订桌子的人数.(. This intent is going to capture the meal type (breakfast, lunch or dinner) requested by our previous intent and will prompt the user to specify the number of people to book the table for.)
- 放下(Drop an)
Intent
节点(node) - 在里面(In the)
Name
节点的端口编辑器,指定(port editor of the node, specify)table_time_intent
作为名字(as the name) - 将其连接到(Connect it to the)
table_config_dialog
对话框节点.(Dialog node.) 由于先前的意图添加了(Since the previous intent added a)table-time-con
上下文项.我们将指定此意图要求该上下文存在,并且还将添加一个(context item. We’ll specify that this intent requires that context to exist and also, we’ll add an)Expression
节点将捕获类型的实体(node which will capture entities of the type)@meal-type
.(.)
所以请继续:(So, go ahead:)
- 拖放一个(Drag and drop a)
Context
节点并连接其(node and connect its)(self)
Intent节点的输出端口.(output port to the Intent node.) - 将上下文名称指定为(Specify the context name as)
table-time-con
.(.) - 拖放一个Expression节点并指定(Drag and drop an Expression node and specify)
@meal-type
在里面(in the)Value
端口编辑器.这是因为我们希望在用户指定早餐,午餐或晚餐作为响应时调用此意图.(port editor. This is because we want this intent to be called whenever the user specifies breakfast, lunch or dinner as a response.)
接下来,让我们为下一个后续意图简单添加一个响应和一个上下文项,该意图将捕获为其保留表的人数.(Next, let’s simply add a response and a context item for our next follow-up intent that will capture the number of people to reserve the table for.)
- 新增一个(Add a new)
Response
节点,将其连接到意图.(node, connect it to the intent.) - 新增一个(Add a new)
Context Add
节点,指定(node, specify)table-num-con
作为上下文名称(as the Context name) - 添加一个(Add an)
Input Text
节点,指定(node, specify)**完善!我要为多少人预定桌子?(Perfect! How many people shall I book the table for?)**作为文本值.(as the text value.) - 连接(Connect the)
Input Text
节点(node to the)Response
节点.(node.)
目的(table_num_intent)(Intent (table_num_intent))
现在,按照这个意图,让我们捕获用户对我们的问题的回答,该问题要求用户提供表必须保留的人数.(Now in this intent, let’s capture the user’s response to our question that requests the user to provide the number of people the table has to be reserved for.)
- 添加一个(Add an)
Intent
节点,命名意图(node, Name the intent)table_num_intent
.(.) - 添加一个(Add a)
Context
节点和(node and an)Expression
节点并将其连接到意图节点的输入端口.(node and connect it to the input ports of the intent node.) - 组(Set)
table-num-con
作为上下文名称.(as the context name.) - 组(Set)
@sys.number
作为"表达式"节点的值.(as the Expression node’s value.) 我想到现在为止,您将获得我们一直干预的所有连接和节点的精髓.(I guess by now you are getting the gist behind all the connections and nodes we keep meddling with.)
让我们添加一个响应节点,存储人数的值,并为最终确认意图设置上下文.(Let’s add a response node, store the value for the number of people and set the context for our final confirmation intent.)
- 新增一个(Add a new)
Response
节点并将其连接到意图节点(node and connect it to the intent node) - 放一个新的(Drop a new)
Context Add
节点,指定(node, specify)table-phone-con
作为上下文名称,并将其连接到"响应"节点.(as the context name and connect it to the Response node.) - 放一个新的(Drop a new)
Entity Get
和(and)Variable Set
节点.配置它们以存储(node. Configure them to store the)@sys.number
实体.(entity.) - 添加一个(Add an)
Input Text
带有响应文本的节点.(node with the response text.)太棒了!然后,我为$ sys.number人设置表.我们都准备好了.您能否分享您的电话号码,以便我确认您的预订.(Awesome! I’ll set the table for $sys.number people then. We are all set. Could you please share your number so that I can confirm your booking.) 响应包含(The response contains the)$sys.number
参数,该参数将由用户为要保留表的人数指定的值替换.(parameter which will be replaced with the value specified by the user for the number of people the table is to be reserved for.)
对话框(确认对话框)-结局!(Dialog (confirm_dialog) - Finale!)
我们与用户的最终对话是显示有关预订的确认消息.以下是我们的最终(Our final dialog with the user is to show a confirmation message regarding the reservation. The following is our final) confirm_dialog
建立.(setup.)
- 新增一个(Add a new)
Intent
节点并命名(node and name it)confirm_intent
.(.) - 我们添加一个(We add a)
Context
指定应该存在的上下文术语.(to specify the context term that should exist.) - 我们使用(We capture a number using the)
@sys.number
预建实体类型.(pre-built entity type.) - 最后发表文字回应,内容为(Finally deliver a textual response that says)**非常感谢!现在确认您为$ sys.user.table-num预订的$ sys.user.table-date日期.您很快就会收到手机号码$ sys.number的通知.(Thank you so much! Your table booking for $sys.user.table-date for $sys.user.table-num is now confirmed. You’ll receive a notification on your mobile number $sys.number soon.)**我们使用两个参数(We use two parameters,)
$sys.user.table-date
和(and)$sys.user.table-num
它将替换为用户指定的日期和表格计数.(that will be replaced with the date and table count specified by the user.)
让我们测试一下(Let’s Test It)
继续,再次点击(Go ahead, again tap on) Train Bot
上(on) Oscova Test Panel
节点并按照对话流程进行操作.如果一切顺利,那么您与机器人的对话应该看起来像以下内容:(node and follow the conversation flow. If all’s well, then your conversation with the bot should end up looking something like the following:)
您还可以观看一个简短的视频,该视频显示了最终如何寻找我.(You can also see a short video that shows how it ended up looking for me.)
导入控制台应用程序(Importing into a Console App)
现在我们已经准备好该机器人的知识库(KB),为什么不检查如何将此类KB导入应用程序.如果仅在Oryzer中创建KB并将其保留在那里,显然没有任何意义.(Now that our knowledge-base (KB) for the bot is ready, why not check out how to import such a KB into an application. It wouldn’t obviously make any sense if we just created the KB within Oryzer and left it there.)
创建一个C#控制台项目(Creating a C# Console Project)
在计算机中启动Visual Studio 2019或更高版本.(Fire up Visual Studio 2019 or above in your machine.)
-
启动Visual Studio 2019.(Launch Visual Studio 2019.)
-
选择(Select)控制台应用程序(.NET Core)(Console App (.NET Core))作为您的项目类型.(as your project type.)
-
您可以为项目命名.我碰巧选择了(You can name the project anything. I happened to have chosen)
TableReservationBot
作为项目名称.(as the project name.)
导入NuGet包(Importing NuGet Package)
到目前为止,我们开发的知识库是针对Bot开发平台的(The knowledge-base we’ve developed so far is for a Bot development platform called) Oscova
这是(which is part of) Syn.Bot
NuGet中可用的框架.(framework which is available in NuGet.)
导入NuGet包:(To import the NuGet package:)
- 打开项目后(Once your project is opened)
- 点击(Click on)工具类(Tools), 选择(, select)NuGet软件包管理器(NuGet Package Manager)然后选择(and choose)程序包管理器控制台(Package Manager Console)
- 类型(Type)
Install-Package Syn.Bot
安装所需的软件包及其参考.(to install the required packages and its references.) 替换中的代码(Replace the code in the)**Program.cs(Program.cs)**具有以下内容的类文件:(class file with the following:)
using System;
using Syn.Bot.Oscova;
namespace TableReservationBot
{
class Program
{
static void Main(string[] args)
{
var bot = new OscovaBot();
bot.ImportWorkspace(@"C:\Users\Workstation\Documents\table-reservation-bot.west");
bot.Trainer.StartTraining();
bot.MainUser.ResponseReceived += (sender, eventArgs) =>
{
Console.WriteLine($"Bot: {eventArgs.Response.Text}");
};
while (true)
{
var request = Console.ReadLine();
var evaluationResult = bot.Evaluate(request);
evaluationResult.Invoke();
}
}
}
}
在上面的代码中,我们创建了一个实例(In the code above, we’ve created an instance of) OscovaBot
类,称为(class, called the) ImportWorskspace
方法,并传入基于工作空间的知识库文件的位置.(method and passed in the location of our workspace based knowledge-base file.)
在接下来的几行中,我们只是在接受用户输入,对其进行处理并显示机器人的输出消息.(In the lines that follow, we are simply taking in user inputs, processing it and displaying the bot’s output message.)
生成并运行项目,然后输入第一个输入为(Build and Run the project and type in the first input as)**你好(Hi)**让对话畅通无阻.(and let the conversation flow.)
在那里!我们已经成功创建了一个表预订机器人,并在Oryzer中对其进行了测试,甚至将其导入了控制台应用程序.啊,这是一段漫长的旅程! :)(And there you are! We’ve successfully created a table reservation bot, tested it in Oryzer and even imported it into a Console app. Ah, what a long journey it has been! :))
兴趣点(Points of Interest)
好吧!所以我个人认为我在这里几乎还没有刮过表面.与我以前的以代码为中心的文章相比,这篇文章有所不同.与上一篇文章不同,我避免使用任何后端C#代码,因为我想完全保留基于流的编程结构.(Alrighty! So I personally think I’ve barely scratched the surface here. Comparatively to my previous articles that were code centric, this one took a different dive. I refrained from using any back-end C# code unlike my previous article as I wanted to in entirety stay with flow-based programming constructs.)
在现实世界的逻辑中,确实会有一个后端代码,该代码实际上会对机器人收集的信息有所帮助.令我惊讶的是,我使用节点创建的任何逻辑也可以使用纯C#后端代码创建.(In real world logic, one would indeed have back-end code that would actually do something about the information collected by the bot. It may come as a surprise to many that whatever logic I created using nodes can also be created using pure C# backend code.)
为简洁起见,我很不情愿地不再扩展Oryzer Studio的工作方式,而是选择坚持我们的机器人开发.然而,人们可以自由地测试驱动该平台,以构建他们心目中的任何东西.(For brevity, I reluctantly had to stay away from expanding more on how Oryzer Studio works, instead I chose to stick with our bot development. One can however freely test drive the platform to build absolutely anything to their hearts content.)
历史(History)
- 10(10)日(th)2020年3月:初始版本(March, 2020: Initial release)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C# .NET bot AI 新闻 翻译