【问题标题】:BotFramework: Passing data from skill to Virtual AssistantBotFramework:将数据从技能传递到虚拟助手
【发布时间】:2021-01-20 03:58:30
【问题描述】:

我有 2 个技能连接到一个虚拟助手,我正在尝试从技能 A 调用技能 B(在技能 A 结束时,用户没有进一步操作)。我知道为此我必须通过虚拟助手。我有两个问题需要处理:

  • 从技能 A 传递数据 -> VA
  • 从 VA 传递数据 -> 技能 B

对于第二个问题,使用带有插槽的 SkillContext 看起来是the way,但我似乎找不到第一个问题的解决方案,因为当技能返回 VA 时,它返回的只是一个布尔值,指示它是否已完成 https://github.com/microsoft/botframework-solutions/blob/853a7ccb940ec2c4d59433b6f2ca2cfa8d5264b4/lib/typescript/botbuilder-skills/src/skillDialog.ts#L229

我尝试做的是将我的数据保存在技能 A 的 SkillContext 中,然后在 VA 中获取该数据并将其传递给技能 B。但是,只有在技能 A 和 VA 都写入到相同的 Cosmos DB,这并不理想。

有没有更好的解决方案?

【问题讨论】:

标签: typescript botframework


【解决方案1】:

在不使用对话框的情况下将数据从技能传递给父机器人可以吗?

我正在使用下面的 sn-p 从 root bot 调用技能

var response = await _skillClient.PostActivityAsync(_botId, targetSkill, _skillsConfig.SkillHostEndpoint, turnContext.Activity, cancellationToken);

我正在使用下面的 sn-p 来结束技能机器人中的对话

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

【讨论】:

    【解决方案2】:

    就我而言,我使用的是 Bot Composer 而不是 PVA。我希望语法是相似的,并且这将适用于具有自定义创建技能的 PVA。

    我一直在寻求做类似的事情,并且能够使用以下语法获得可行的解决方案。

    在我的示例中,我有一个包含 2 个步骤的瀑布对话框。第一步显示带有几个选项的提示。最后一步检索选定的值并结束对话和对话。在我的情况下,我希望将所选值作为技能的输出返回,以便我可以将其保存到作曲家中的一个变量中,并在稍后的对话中使用它。

    我的对话代码是:

    public class ActiveFuelCardDialog : ComponentDialog
    {
        public ActiveFuelCardDialog() : base(nameof(ActiveFuelCardDialog))
        {
            InitializeWaterfallDialog();
        }
    
        public WaterfallStepContext StepContext { get; private set; }
    
        private void InitializeWaterfallDialog()
        {
            var waterFallSteps = new WaterfallStep[]
            {
                CardSelectionStepAsync,
                FinalStepAsync
            };
    
            AddDialog(new WaterfallDialog($"{nameof(ActiveFuelCardDialog)}.mainFlow", waterFallSteps));
            AddDialog(new ChoicePrompt($"{nameof(ActiveFuelCardDialog)}.cardSelection"));
    
            InitialDialogId = $"{nameof(ActiveFuelCardDialog)}.mainFlow";
        }
    
        private async Task<DialogTurnResult> CardSelectionStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            StepContext = stepContext;
            //then return back a list of 2 cards
            //in the format: CardType
            List<ActiveFuelCardsOutput> activeFuelCardsOutputs = new List<ActiveFuelCardsOutput>();
            activeFuelCardsOutputs.Add(new ActiveFuelCardsOutput()
            {
                CardNo = "1234567890123456",
                CardType = "WM",
                ExpiryDate = DateTime.Now.AddMonths(8)
            });
    
            activeFuelCardsOutputs.Add(new ActiveFuelCardsOutput()
            {
                CardNo = "2345678901234657",
                CardType = "WM",
                ExpiryDate = DateTime.Now.AddMonths(6)
            });
    
            activeFuelCardsOutputs.Add(new ActiveFuelCardsOutput()
            {
                CardNo = "3456789012345678",
                CardType = "WM",
                ExpiryDate = DateTime.Now.AddMonths(12)
            });
    
            return await stepContext.PromptAsync($"{nameof(ActiveFuelCardDialog)}.cardSelection",
                new PromptOptions
                {
                    Prompt = MessageFactory.Text("Please select a card"),
                    Choices = ChoiceFactory.ToChoices(activeFuelCardsOutputs.Select(x => x.CardNo).ToArray())
                }, cancellationToken);
        }
    
        private async Task<DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            StepContext = stepContext;
            string selectedCard = ((FoundChoice)stepContext.Result).Value;
    
            //https://techcommunity.microsoft.com/t5/teams-developer/skill-dialog-enddialog-does-not-work/m-p/1476612
            await stepContext.Context.SendActivityAsync(new Activity()
            {
                Type = ActivityTypes.EndOfConversation,
                Code = EndOfConversationCodes.CompletedSuccessfully,
                Value = selectedCard
            });
    
            return await stepContext.EndDialogAsync();
        }
    }
    

    导致此功能为我工作的部分是在 FinalStepAsync 方法中

                await stepContext.Context.SendActivityAsync(new Activity()
            {
                Type = ActivityTypes.EndOfConversation,
                Code = EndOfConversationCodes.CompletedSuccessfully,
                Value = selectedCard
            });
    
            return await stepContext.EndDialogAsync();
    

    这似乎结束了对话并返回值。

    然后我可以通过将技能的“属性”设置为某个变量(例如 dialog.selectedCard)在 Bot Composer 中使用它。然后使用“${dialog.selectedCard}”之类的后期值。

    这篇文章将我引向了这个答案。 Helpful Post

    Showing Conversation calling skill & using value

    【讨论】:

      猜你喜欢
      • 2019-12-11
      • 1970-01-01
      • 1970-01-01
      • 2011-04-15
      • 2011-09-27
      • 1970-01-01
      • 2020-06-12
      • 2020-01-25
      • 1970-01-01
      相关资源
      最近更新 更多