微软机器人框架的演变

623 篇文章 16 订阅
516 篇文章 54 订阅

目录

世代

概述

用例

GenX

概念

实现

代码示例

GenY

概念

实现

代码示例

GenZ

概念

实现

代码示例

商业聊天机器人

结论


世代

聊天机器人是一个软件程序,可以模拟与人的交谈。最早也是最著名的聊天机器人之一(在网络出现之前)是Eliza,这是一个假装是心理治疗师并用其他问题回答问题的程序。

RedAndrette是两个早期程序的名称,可以定制以回答寻求产品服务的用户的问题。此类程序有时称为虚拟代表或虚拟服务代理。

概述

根据Microsoft Bot Framework的开发演变,我个人分为三代:

  1. X世代——核心(代表机器人编码的基础)
  2. Y世代——协作(与外部业务服务的接口)
  3. Z世代——认知(涉及业务逻辑中的人工智能)

它以图表方式表示为:

用例

为了说明微软机器人框架的增量生成,让我选择股票价格柜员聊天机器人用例。

股票价格柜员是一个简单的业务用例,最终用户在其中查询给定股票报价的最新价格。例如,如果最终用户想知道IBM的收盘价/最新股价,此应用程序将响应价格值作为结果。

GenX

GenX涵盖了聊天机器人基础及其基本通信框架的开发。

概念

Microsoft机器人连接器是一种通信服务,可帮助你将机器人与任何一个通信渠道(如Skype、短信、电子邮件等)连接。如果编写对话机器人或代理并在Internet上公开与Microsoft机器人框架兼容的API,则机器人框架连接器服务会将消息从机器人转发给用户,并将用户消息发送回机器人。

实质上,建议开发人员编写自己的具有机器人连接器功能的机器人应用服务。此自定义服务旨在完全利用Microsoft Bot Framework API

机器人框架模拟器是此包的一部分,用于模拟客户端组件。

实现

代码级实现在下面的序列图中起草。

实现从微软服务的基础类开始,即System.Web.HttpApplication。创建所有核心ASP.NET对象后,将创建HttpApplication对象来为请求提供服务。如果您的系统中有一个global.asax(继承自HttpApplication),则将创建global.asax文件的对象。

首次将ASP.NET页附加到应用程序时,将创建一个新的HttpApplication实例。为了最大限度地提高性能,HttpApplication实例可以重用于多个请求。它在生命周期图中进行了描述。

HttpConfiguration类位于System.Web.Http库中,这是一个用于构建Web API的框架。

代码示例

作为启动点,在请求基于Web的应用程序中的第一个资源时调用Application_Start。该Application_Start方法在应用程序的生命周期中仅调用一次。

此方法用于执行启动任务,例如将数据加载到缓存中和初始化static值。

/// It's an optional file that contains code for responding
/// to application-level events raised by ASP.NET or by HttpModules
/// by Ganesan Senthilvel
public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        GlobalConfiguration.Configure(WebApiConfig.Register);
    }
}

这里的RouteConfig.cs文件与任何MVC项目中的文件相同,并为MVC框架设置路由。WebApiConfig.cs文件是我们的Web API路由配置发生的位置。

我们的WebApiConfig static类看起来像下面的源代码:

/// It's used for any Web API related configuration, including Web-API
/// specific routes, Web API services, and other Web API settings
/// by Ganesan Senthilvel
public static class WebApiConfig
{
    /// This method registers a dependency property with the
    /// specified property name, property type, owner type, property metadata,
    /// and a value validation callback for the property.
    public static void Register(HttpConfiguration config)
    {
        // Json settings
        config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling =
                                                      NullValueHandling.Ignore;
        config.Formatters.JsonFormatter.SerializerSettings.ContractResolver =
                          new CamelCasePropertyNamesContractResolver();
        config.Formatters.JsonFormatter.SerializerSettings.Formatting =
                          Formatting.Indented;
        JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            Formatting = Newtonsoft.Json.Formatting.Indented,
            NullValueHandling = NullValueHandling.Ignore,
        };

        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

如果您注意到,我们不是像在MVC RouteConfig类中那样调用Routes.MapRoutes,而是像上面那样调用Config.Routes.MapHttpRoutes

进入该Configuration部分时,当机器人注册到Microsoft机器人框架连接器时MicrosoftAppIdMicrosoftAppPassword生成,并且MicrosoftAppIdMicrosoftAppPassword用于对对话进行身份验证,并允许开发人员使用他们希望在其上可见的通道配置其机器人。您指定的BotId用于目录和开发人员门户中的URL

AppIdAppPasswordBot框架注册页面必须记录在项目的web.config

在谈到下一个方法——Post时,机器人模板的核心功能都在Controllers\MessagesController.cs中的Post函数中。在这种情况下,代码获取用户的消息文本,然后使用CreateReplyMessage函数创建回复消息。方法上的BotAuthentication修饰用于通过HTTPS验证机器人连接器凭据。

/// POST: api/Messages
/// Receive a message from a user and reply to it
public async Task<message> Post([FromBody]Message message)
{
    if (message.Type == "Message")
    {
        // calculate something for us to return
        int length = (message.Text ?? string.Empty).Length;

        // return our reply to the user
        return message.CreateReplyMessage("ServBot::You sent the message: " +
                            message.Text + " with " +
                            length + " characters at " + DateTime.Now);
    }
    else
    {
        return HandleSystemMessage(message);
    }

在执行GenX代码库时,结果为:

GenY

GenY介绍连接另一个服务器组件、提交请求以获取相关信息、将响应检索回Bot组件的其他步骤。它是GenX外部通信的延伸臂。

概念

作为机器人应用程序开发的下一个级别,该臂被扩展为连接其他服务以进行核心逻辑执行。在继续上一个GenX示例时,我们将展示案例GenY概念。

在自定义MyStockBot MyController对象中,Post方法接收来自最终用户的消息并回复。因此,它是构建核心业务逻辑的正确容器。

在此方法中,实例化了股票交易所价格查找器以接口股票价值查询过程。此应用服务器连接执行核心业务逻辑,并将匹配结果返回Post方法。反过来,结果会回到最终用户层。

实现

要构建的Microsoft Bot Framework有三个主要的 SDK 组件:

  1. 机器人生成器——托管在GitHub上的开源SDK,提供在Node.js-.NET或REST API的机器人中构建出色对话所需的一切。
  2. 开发人员门户——让我们将机器人无缝地将文本/短信连接到Skype,Slack,Facebook Messenger,Kik,Office 365邮件和其他流行服务
  3. 机器人目录——用户将能够发现、尝试机器人并将其添加到他们最喜欢的对话体验中

编写机器人的开发人员都面临着同样的问题:机器人需要基本I/O;他们必须具备语言和对话技巧;它们必须具有高性能、响应迅速且可扩展;他们必须与用户建立联系——最好是用户选择的任何对话体验和语言。

作为机器人应用执行的核心逻辑,组件图从Http.ApiController基类开始。应用程序的对象派生自ApiController并命名为MessageController

MessageController类的Post方法采用Message对象并切换到基于MessageType成员的操作。如果Type预定义System数据的一部分,如ping, BotAdded,UserAdded等,然后它们在一个名为HandleSystemMessage的单独方法中处理。自定义消息是单独处理/处理的。

在我们的示例中,处理非系统消息以计算字符数并返回给调用方。

代码示例

作为GenX机器人编码的扩展,GenY是在外部服务的协作努力下添加的。它主要是通过ApiController类的扩展来实现的,即MessageController

如前所述,MessageController有两个关键的异步方法,即:

  1. Post
  2. HandleSystemMessage

PostApiController对象的主条目。当从最终用户收到消息/请求时,它会被触发。消息上下文在方法参数中传递。此方法应该处理传入的请求并将输出响应发送给最终用户。

HandleSystemMessage是传入最终用户请求的非Message类型参数的处理程序方法。如上面的序列图所示,Handler节点处理任何类型的系统消息并采取适当的操作,如BotAddedUserAdded等。

namespace StockBot
{
    /// MessageController class processes incoming requests, 
    /// handles user input and interactions, and executes 
    /// the appropriate application logic.
    /// by Ganesan Senthilvel
    [BotAuthentication]
    public class MessagesController : ApiController
    {
        /// Invoking GetStockRateAsync to retrieve stock
        /// value for the given StockSymbol
        private async Task<string> GetStock(string StockSymbol)
        {
            try
            {
                String retStockValue = await YahooBot.GetStockRateAsync(StockSymbol);
                if (retStockValue.Trim() == "")
                {
                    return string.Format
                    ("This \"{0}\" is not an valid stock symbol", StockSymbol);
                }
                else
                {
                    return string.Format
                    ("Stock symbol : {0} has Name: {1} with Price : {2} as on : {3}",
                        StockSymbol,
                        retStockValue.Split(',')[3],
                        Convert.ToDouble(retStockValue.Split(',')[1]),
                        retStockValue.Split(',')[2]);
                }
            }
            catch(System.FormatException ex)
            {
                return string.Format
                ("This \"{0}\" is not an valid stock symbol", StockSymbol);
            }
        }
        /// POST: api/Messages
        /// Receive a message from a user and reply to it
        public async Task<message> Post([FromBody]Message message)
        {
            if (message.Type == "Message")
            {
                // Parse the last word on the sentence
                String stockRate = await GetStock(
                    message.Text.Split(' ').Select(s=>s.Trim()).Last());
                return message.CreateReplyMessage(stockRate);
            }
            else
            {
                return HandleSystemMessage(message);
            }
        }

        /// Bot's Incoming message is handled in this method
        /// based on Message Type
        private Message HandleSystemMessage(Message message)
        {
            if (message.Type == "Ping")
            {
                Message reply = message.CreateReplyMessage();
                reply.Type = "Ping";
                return reply;
            }
            else if (message.Type == "DeleteUserData")
            {
                // Implement user deletion here
                // If we handle user deletion, return a real message
                Message reply = message.CreateReplyMessage
                                ("ServBot::You opted to delete User Data");
                return reply;
            }
            else if (message.Type == "BotAddedToConversation")
            {
                Message reply = message.CreateReplyMessage
                ("ServBot::You opted to connect the conversation");
                return reply;
            }
            else if (message.Type == "BotRemovedFromConversation")
            {
                Message reply = message.CreateReplyMessage
                ("ServBot::You opted to disconnect the conversation");
                return reply;
            }
            else if (message.Type == "UserAddedToConversation")
            {
                Message reply = message.CreateReplyMessage
                ("ServBot::You opted to add User into conversation");
                return reply;
            }
            else if (message.Type == "UserRemovedFromConversation")
            {
                Message reply = message.CreateReplyMessage
                ("ServBot::You opted to remove User from conversation");
                return reply;
            }
            else if (message.Type == "EndOfConversation")
            {
                var hours = DateTime.Now.Hour;
                String partDay = (hours > 16) ? "Evening" : 
                (hours > 11) ? "Afternoon" : "Morning";
                Message reply = message.CreateReplyMessage
                ("ServBot::Good " + partDay + " User!!" +
                    Environment.NewLine + "Local Time is: " + 
                    DateTime.Now.ToString());
                return reply;
            }
            return null;
        }
    }
}

GenY模式下,添加外部App Service来查找给定股票上市报价的股票价格。在我们的示例中,它是在名为YahooBot的单独类中开发的,用于从Yahoo金融服务检索当前股票价格。

从我们的主入口MessageController类中,开发了一种新的异步方法,即GetStock,以调用AppServer YahooBotGetStock方法将StockSymbol作为输入参数并返回合并的价格输出作为返回值。

在执行GenY代码库时,结果为:

GenZ

GenZ是集成认知服务的微软机器人应用开发的高级阶段。它通过利用预构建的Azure服务具有高智能功能。

概念

在编程理念方面,GenZ具有自然语言理解的终端用户自由文本输入,在GenY应用服务器FinStock集成之前。它具有最终用户的优势,可以以自然的方式提问,而不是以预定义的股票输入参数查询机器人应用。

从逻辑上讲,MyStockBot类中有一个两步过程,如上面的概念图所示。

实现

GenZ认知BotApp开发的一步步实施,在下面的流程图中精心写。编码执行过程大致分为两个部分:

  1. Microsoft LUIS Azure App Setup
  2. 我的自定义.NET应用设置

基本上,自定义.NET代码应在Microsoft Azure LUIS门户中进行初始设置后编写。

根据luis.aiLUIS是一种语言理解智能服务,它提供了一种快速有效的方法来向应用程序添加语言理解。借助LUIS,你可以在适合你的用途和需要专用模型时使用必应和Cortana中预先存在的世界级预生成模型。

LUIS将指导你完成快速生成它们的过程。LUISMicrosoft认知服务的一部分。详细信息写在MSDN这里。

代码示例

GenZ编码方面,智能调用在源代码行被调用:

Rootobject StLUIS = await GetEntityFromLUIS(message.Text);

除此之外,GenZ编码是一种扩展GenY源代码。在调用FinStock服务之前,将在自定义GetEntityFromLUIS方法中调用认知服务。如果注意到GenZ源代码中的最后一个方法,它会调用预生成的Azure服务,并返回有关成功状态代码的正确响应。

此外,根据 Azure 服务中配置的意向,我们的代码将切换多个业务案例,如附加代码所示。

[BotAuthentication]
 public class MessagesController : ApiController
 {
     /// POST: api/Messages
     /// Receive a message from a user and reply to it
     public async Task<message> Post([FromBody]Message message)
     {
         if (message.Type == "Message")
         {
             string StockRateString;
             Rootobject StLUIS = await GetEntityFromLUIS(message.Text);
             if (StLUIS.intents.Count() > 0)
             {
                 switch (StLUIS.intents[0].intent)
                 {
                     case "StockPrice":
                         StockRateString = await GetStock(StLUIS.entities[0].entity);
                         break;
                     case "StockPrice2":
                         StockRateString = await GetStock(StLUIS.entities[0].entity);
                         break;
                     default:
                         StockRateString = "Sorry, I am not getting you...";
                         break;
                 }
             }
             else
             {
                 StockRateString = "Sorry, I am not getting you...";
             }

             // return our reply to the user
             return message.CreateReplyMessage(StockRateString);
         }
         else
         {
             return HandleSystemMessage(message);
         }
     }
     private async Task<string> GetStock(string StockSymbol)
     {
         double? dblStockValue = await FinStockBot.GetStockRateAsync(StockSymbol);
         if (dblStockValue == null)
         {
             return string.Format("This \"{0}\" is not an valid stock symbol",
                                   StockSymbol);
         }
         else
         {
             return string.Format("Stock Price of {0} is {1}",
                                   StockSymbol, dblStockValue);
         }
     }
     private static async Task<rootobject> GetEntityFromLUIS(string Query)
     {
         Query = Uri.EscapeDataString(Query);
         Rootobject Data = new Rootobject();
         using (HttpClient client = new HttpClient())
         {
             string RequestURI =
             "https://api.projectoxford.ai/luis/v1/application?id=7f626790-38d6-
             4143-9d46-fe85c56a9016&subscription-key=
             09f80de609fa4698ab4fe5249321d165&q=" + Query;
             HttpResponseMessage msg = await client.GetAsync(RequestURI);

             if (msg.IsSuccessStatusCode)
             {
                 var JsonDataResponse = await msg.Content.ReadAsStringAsync();
                 Data = JsonConvert.DeserializeObject<rootobject>(JsonDataResponse);
             }
         }
         return Data;
     }

如果你注意到,我们在LUIS服务的实体过程中有名为Rootobject的通信对象。它是作为Microsoft LUIS识别器创建的,它指向我们的模型,并将其添加为我们的Cortana机器人的根对话框。

除了新添加的GetEntityFromLUIS方法作为Microsoft认知服务的接口外,其他处理逻辑几乎与GenY代码库相同。

在执行GenZ代码库时,结果为:

商业聊天机器人

在人工智能中,聊天机器人扮演着一个关键工具,它向用户提供购买反馈,客户服务代理在手,以提供进一步的帮助。

在中国,微信不仅被近三分之二的16-24岁在线消费者使用,而且该服务利用其巨大的市场份额,通过提供远远超出简单消息的功能,试图在购买过程中插入尽可能多的站点。

作为数字消费者购买旅程和在线生活的主要部分,聊天机器人需要是非侵入性的,显然对用户有利,也许最重要的是,将自己表现为一个诚实的助手,而不是伪装的广告。

作为我的分析的总结,使用聊天机器人的两个关键业务优势:

  1. 人工联络中心业务自动化程度高;降低成本
  2. 通过在AI智能聊天机器人中使用机器学习,可以持续改进(使用)

聊天机器人将购物体验从浏览(网络/零售商店)转变为推荐。机器人了解您,就像值得信赖的朋友或个人购物者一样。

结论

目前,混合方法可能是深入研究聊天机器人的最佳方法。让技术执行最简单的任务,但有人工备份来处理更复杂的请求和问题。

您今天研究的内容最终可能会支持您如何尽快为您的企业部署成功的聊天机器人应用程序,一旦解决了所有问题。

https://www.codeproject.com/Articles/1120056/Evolution-of-Microsoft-Bot-Framework

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值