Botframework-solutions: 允许将数据从技能传递回 VA

创建于 2019-09-30  ·  25评论  ·  资料来源: microsoft/botframework-solutions

用户的故事

作为开发人员,我希望能够将数据从技能传回 VA。

我希望能够在技能完成时将数据从技能传回调用 VA,以便(例如)使用第一个机器人生成的信息继续与另一个机器人的对话。

我的用例如下:

我将 VA 连接到 2 个机器人,第一个机器人用于搜索人员,第二个机器人用于与这些人预约会议。 搜索人员机器人的功能之一是使用户能够与搜索到的人员建立会议。 这将要求搜索人员机器人将要与之创建会议的人员的引用返回给 VA。 据我所知,目前这是

如果可以从技能 -> VA 而不是仅用于 VA -> 技能获得类似 manifest/SkillContext/slots 机制的东西,那就太好了

Bot Services customer-replied-to customer-reported

最有用的评论

你好,

我们需要一个关于此的教程 :-) 作为我们 GA 工作的一部分(月底),最好在接下来的几天内在文档站点上添加它。 与此同时,希望以下信息有所帮助。

作为 Skills GA 的一部分,我们简化了数据共享,并将传输方法从 SemanticAction(由于旧的架构而使用起来很麻烦)转移到更简单的Value活动属性。

我也会得到一个代码示例并更新这个问题。

将数据传递给技能

要调用技能,将Event类型的活动发送到技能,从而触发动作样式调用,而不是通常的话语。

这是将数据放入您要发送的活动的示例

public class BookingDetails
{
        public string Destination { get; set; }
        public string Origin { get; set; }
        public string TravelDate { get; set; }
}

activity.Value = new BookingDetails { Destination = "New York" };

在技​​能中检索数据

此处和以下是从父项(例如虚拟助手或超级虚拟代理)传递信息的技能示例。 在这种情况下,“数据”在传入活动的Value属性上传递。 在这种情况下,“数据”被传递到技能(通过事件活动),然后被反序列化并进入状态——这意味着当对话被执行时,它拥有它需要的所有数据。

case Events.CreateEvent:
{
    state.IsAction = true;
    EventInfo actionData = null;
    if (ev.Value is JObject info)
    {
        actionData = info.ToObject<EventInfo>();
        // Process data here
    }

    return await stepContext.BeginDialogAsync(_createEventDialog.Id, options);

回传数据

在 Dialog 内(在您的技能范围内),当您完成处理并想要返回信息时,您可以通过 EndDialogAsync 上的重载来完成此操作。 然后,此数据将作为 Skill 基础结构发送的 EndOfConversation 消息的一部分编组回调用方。

    return await sc.EndDialogAsync(new TodoListInfo { ActionSuccess = true, ToDoList = todoList });

在调用方获取数据

在调用方,为了更好地支持这种情况,我们必须将 MainDialog 转为 Waterfall 而不是 ComponentDialog。 组件对话框没有提供“获取”对话框结果的方法。

正如您在此处看到的

if (stepContext.Result != null)
{
  var message = $"Skill \"{activeSkill.Id}\" invocation complete.";
  message += $" Result: {JsonConvert.SerializeObject(stepContext.Result)}";
}

所有25条评论

你好,

我们一直致力于为 Skills 提供“动作调用”支持,并在此过程中正式确定如何将数据返回给调用 Bot。 Activity有一个SemanticAction属性,用于启用此场景。

目前我们有一个概念可以在 PR 中证明这一点。 是设置此 SemanticAction 属性的示例,然后您可以在客户端将其拉出。

如果这有帮助,请告诉我,很高兴为您提供进一步帮助,并让您在此场景中前进,这是我们将在与 Ignite 会议一致的下一个版本中添加更多文档/支持的内容。

嘿达伦

谢谢你的快速反应。 是的, SemanticAction响应对于我的用例来说将是一个很好的解决方案。 然而,据我所知,从客户端 (VA) 端提取语义操作也需要对代码库进行一些更改,对吗? 因为目前,即使你在技能端调用sc.EndDialogAsync(semanticAction) ,这个调用的结果也会被 VA 端的 SkillTransport 转换为一个布尔值true ,表明技能已经完成并且没有其他的。

公平点 - 在您的场景中,您是否希望直接“调用”该技能,就像远程方法调用一样,或者改为传递话语,让技能完成它的事情,但能够将数据与任何活动一起返回(当前)被转发给用户而您无法拦截它。

动作调用方法我们有一个模式,几乎可以使用,而另一种感觉就像我们按照您的建议探索的东西,如果这是您所看到的场景。

有什么想法@marawanshalaby吗?

嘿达伦

抱歉回复晚了,最近被工作埋没了:)。 因此,就我而言,我会说第二个选项更有吸引力,因为它更松散耦合,对我来说理想的情况如下:

  • 用户发送话语,VA调度员将他发送到技能A。
  • 技能 A 处理用户的操作,直到技能 A 识别出“创建会议”意图
  • 一旦“创建会议”意图被技能 A 识别,它就会终止对话并将其本地状态(人名和 ID)连同话语一起发送回 VA,可能通过语义动作。
  • VA 将话语解析为技能 B,然后使用其插槽将最初从技能 A 的语义动作传递给技能 B

这样,技能 A 对技能 B 一无所知,它们之间的唯一联系是通过调度员处理的话语发生的,而不是在 VA/技能 A 中对远程方法调用进行硬编码,因此它也很容易扩展到其他技能。 你认为这有意义吗?

是的,完全和我们今天所拥有的SemanticAction可以实现这一点。 事实上,此示例显示了调用三种技能将数据聚合到一张每日摘要卡中。 它没有显示将数据传递回然后将数据传递回另一个技能,但我们已经证明,在一些场景中,最显着的体验是检索您的任务、分类类型,然后提供通过商店将您路由到解决(例如杂货店、药房)。

SemanticAction 提供了执行这种交换的机制,我们将在接下来的几周内添加一些进一步的文档来更详细地概述这种模式

嘿达伦

看起来很棒,我这边有两个问题:

  • 您是否有发布 SemanticAction 功能的大致日期?
  • 是否会在添加 C# 支持的同时添加 typescript 支持?

嘿达伦,

我们只是通过示例调用技能来聚合数据,但没有看到数据从技能传递到 VA,我知道您在评论中提到了它。 但是你介意让我们知道是否有任何机制可以将数据从技能传递到 vA。 感谢您

@darrenj能否请您提供上述问题的更新

你好

是在将信息返回给调用机器人的技能中设置语义操作的示例。

我们已经在技能中尝试过这个,但是我们如何在虚拟助手中再次获取数据。 无法得到任何样品。 如果您能分享 vA 代码工具,不胜感激

@darrenj能否请您也告诉我们 VA 代码

@darrenj ,我现在正在尝试实现这一点,我看到它已在 C# 版本https://github.com/microsoft/botframework-solutions/blob/4619333ec086ca7c42a697022c9e01dfcafab824/lib/csharp/microsoft 中的 VA 端修复https://github.com/microsoft/botframework-解决方案/blob/4619333ec086ca7c42a697022c9e01dfcafab824/lib/typescript/botbuilder-skills/src/skillDialog.ts#L244 。 您是否也估计何时将其添加到打字稿中?

这对我们来说是一个障碍,因为在我们正在实施的当前流程中,我们需要确保对话在技能端成功结束(例如不是取消),以便在 VA 端触发反馈对话。 在我们等待 TS 支持时,对于如何实施此方案有任何建议吗?

@darrenj关于何时在打字稿https://github.com/microsoft/botframework-solutions/blob/master/sdk/typescript/libraries/botbuilder-skills/src/skillDialog.ts#L382 中修复此问题的任何更新? 这是否与此问题有关: https :

你好, @darrenj

你能分享一下如何在VA中再次处理数据吗? 您在 CalendarSummaryDialog 中共享了示例,但这只是技巧方面。 在 EndDialogAsync 中发送技能后如何在 VA 中处理该问题?

感谢那

问题已关闭,因此我们没有收到通知,重新打开。 抱歉耽搁了,我可以在这里澄清一下情况吗?

  • VA 和 Skill 使用 Javascript/Typescript 而不是 C#?
  • 作为“结束对话”模式的一部分,您希望将“数据”从子技能返回给父 VA?

感谢那。

我的问题仍然是如何将技能上下文发送回 VA(均在 C# 中)。 我想做一些类似于@marawanshalaby之前所说的

如何最好地做到这一点? 看看这里讨论的内容,我仍然不知道如何在 VA 端处理语义操作。

你好,

我们需要一个关于此的教程 :-) 作为我们 GA 工作的一部分(月底),最好在接下来的几天内在文档站点上添加它。 与此同时,希望以下信息有所帮助。

作为 Skills GA 的一部分,我们简化了数据共享,并将传输方法从 SemanticAction(由于旧的架构而使用起来很麻烦)转移到更简单的Value活动属性。

我也会得到一个代码示例并更新这个问题。

将数据传递给技能

要调用技能,将Event类型的活动发送到技能,从而触发动作样式调用,而不是通常的话语。

这是将数据放入您要发送的活动的示例

public class BookingDetails
{
        public string Destination { get; set; }
        public string Origin { get; set; }
        public string TravelDate { get; set; }
}

activity.Value = new BookingDetails { Destination = "New York" };

在技​​能中检索数据

此处和以下是从父项(例如虚拟助手或超级虚拟代理)传递信息的技能示例。 在这种情况下,“数据”在传入活动的Value属性上传递。 在这种情况下,“数据”被传递到技能(通过事件活动),然后被反序列化并进入状态——这意味着当对话被执行时,它拥有它需要的所有数据。

case Events.CreateEvent:
{
    state.IsAction = true;
    EventInfo actionData = null;
    if (ev.Value is JObject info)
    {
        actionData = info.ToObject<EventInfo>();
        // Process data here
    }

    return await stepContext.BeginDialogAsync(_createEventDialog.Id, options);

回传数据

在 Dialog 内(在您的技能范围内),当您完成处理并想要返回信息时,您可以通过 EndDialogAsync 上的重载来完成此操作。 然后,此数据将作为 Skill 基础结构发送的 EndOfConversation 消息的一部分编组回调用方。

    return await sc.EndDialogAsync(new TodoListInfo { ActionSuccess = true, ToDoList = todoList });

在调用方获取数据

在调用方,为了更好地支持这种情况,我们必须将 MainDialog 转为 Waterfall 而不是 ComponentDialog。 组件对话框没有提供“获取”对话框结果的方法。

正如您在此处看到的

if (stepContext.Result != null)
{
  var message = $"Skill \"{activeSkill.Id}\" invocation complete.";
  message += $" Result: {JsonConvert.SerializeObject(stepContext.Result)}";
}

我已经验证了一种方法 - 在我提交文档之前让我的团队对此进行审查,但是使用Weather Skill作为示例,很容易使这个工作。

这假设您注册了一个名为 WeatherSkill 的技能 - 可以与任何其他技能一起使用,但需要确保它已配置。

  var skillSteps = new WaterfallStep[]
            {
                PreSkillStepAsync,
                PostSkillStepAsync,
            };

  AddDialog(new WaterfallDialog("WeatherActionInvoke", skillSteps));

启动动作调用

 return await innerDc.BeginDialogAsync("WeatherActionInvoke");

技能动作调用

PostSkillStepAsync 中的 stepContext.Result 将具有技能的返回值

        private async Task<DialogTurnResult> PreSkillStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var evt = stepContext.Context.Activity.AsEventActivity();
            if (evt != null)
            {
                LocationInfo location = new LocationInfo();
                location.Location = "51.4644018,-2.1177246,14";

                var activity = (Activity)Activity.CreateEventActivity();
                activity.Name = "WeatherForcast";
                activity.Value = location;

                // Create the BeginSkillDialogOptions
                var skillDialogArgs = new BeginSkillDialogOptions { Activity = activity };

                // Start the skillDialog instance with the arguments. 
                return await stepContext.BeginDialogAsync("WeatherSkill", skillDialogArgs, cancellationToken);
            }

            return await stepContext.NextAsync();
        }

        private async Task<DialogTurnResult> PostSkillStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            return await stepContext.NextAsync();
        }

关于@higoorc问题,我认为提议的实现涵盖了要求并且是可行的。

但是,有些技能交接场景可能会受益于适当的附加控制。 Value是一个非常通用的容器,VA 实现者可以利用它来实现他们认为合适的任何场景,但不会强制执行任何特定的行为。 在实现者将他们的 VA 实现连接到第一方(内部开发)和第三方技能(社区技能)的情况下,通常无法保证Value将成为技能交接的通用机制。

通过技能切换,我的意思是当一项技能的设计方式是,它的对话以这样一种方式结束,即使用另一项技能继续对话是很自然的。 以预订旅行的场景为例,在预订后,提供一项技能,该技能还为该特定目的地预订租车或当地旅游。 我什至可以想象技能交接不会是技能想要报告为结果的唯一可能的事情。 助理(谷歌/Alexa/...)交接可能是另一个。

处理此问题的一种可能方法是让技能移交工作发布目标意图及其已知实体/插槽作为EndOfConversation事件的一部分( SemanticAction ,虽然名称很奇怪,但将是一种表达方式,只要提前知道语义动作)。 鉴于技能的不连贯性,这意味着如果目标技能更改了其意图/实体/槽处理逻辑,则必须更新移交意图的技能,但这是一个更简洁的架构。 你怎么认为? 会有更好的方法吗?

@darrenj - 你能不能提供一个样本,它应该有一个 VA 和技能

@darrenj - 你能告诉我们什么时候更新文档吗?
感谢你的帮助。

@darrenj能否请您提供有关文件/样本更新的更新

将 PR 与问题相关联,并概述与 Skills 交换数据所需的步骤。

@darrenj 将数据从技能传递给父机器人

我正在使用以下代码段从 root bot 调用技能
var response = await _skillClient.PostActivityAsync(_botId, targetSkill, _skillsConfig.SkillHostEndpoint, turnContext.Activity, cancelToken);

我正在使用以下代码段来结束技能机器人中的对话

var endOfConversation = Activity.CreateEndOfConversationActivity();endOfConversation.Code = EndOfConversationCodes.CompletedSuccessfully;

此页面是否有帮助?
0 / 5 - 0 等级