所以他们在EchoBot示例中有一个很好的例子来演示链
public static readonly IDialog<string> dialog = Chain.Posttochain() .Select(msg => msg.Text) .Switch( new Case<string,IDialog<string>>(text => { var regex = new Regex("^reset"); return regex.Match(text).Success; },(context,txt) => { return Chain.From(() => new PromptDialog.PromptConfirm("Are you sure you want to reset the count?","Didn't get that!",3)).ContinueWith<bool,string>(async (ctx,res) => { string reply; if (await res) { ctx.UserData.SetValue("count",0); reply = "Reset count."; } else { reply = "Did not reset count."; } return Chain.Return(reply); }); }),new RegexCase<IDialog<string>>(new Regex("^help",RegexOptions.IgnoreCase),txt) => { return Chain.Return("I am a simple echo dialog with a counter! Reset my counter by typing \"reset\"!"); }),new DefaultCase<string,IDialog<string>>((context,txt) => { int count; context.UserData.TryGetValue("count",out count); context.UserData.SetValue("count",++count); string reply = string.Format("{0}: You said {1}",count,txt); return Chain.Return(reply); })) .Unwrap() .PostToUser(); }
但是,我宁愿使用LUIS Intent而不是使用REGEX来确定我的会话路径.我正在使用这段漂亮的代码来提取LUIS Intent.
public static async Task<LUISQuery> ParseUserInput(string strInput) { string strRet = string.Empty; string strEscaped = Uri.EscapeDataString(strInput); using (var client = new HttpClient()) { string uri = Constants.Keys.LUISQueryUrl + strEscaped; HttpResponseMessage msg = await client.GetAsync(uri); if (msg.IsSuccessstatusCode) { var jsonResponse = await msg.Content.ReadAsstringAsync(); var _Data = JsonConvert.DeserializeObject<LUISQuery>(jsonResponse); return _Data; } } return null; }
现在不幸的是,因为这是异步的,所以LINQ查询不能很好地运行case语句.任何人都可以为我提供一些代码,允许我根据LUIS Intents在我的链中包含一个case语句吗?
解决方法
Omg在他的评论中是正确的.
请记住,IDialogs有一个TYPE,意思是,IDialog可以返回一个你自己指定的类型的对象:
public class TodoItemDialog : IDialog<TodoItem> { // Somewhere,you'll call this to end the dialog public async Task FinishAsync(IDialogContext context,IMessageActivity activity) { var todoItem = _itemRepository.GetItemByTitle(activity.Text); context.Done(todoItem); } }
对context.Done()的调用返回您的Dialog要返回的对象.当你在阅读任何类型的IDialog的类声明时
public class TodoItemDialog : LuisDialog<TodoItem>
它有助于将其读作:
“TodoItemDialog是一个Dialog类,它在完成后返回一个TodoItem”
您可以使用context.Forward()而不是链接,它基本上将相同的messageActivity转发到另一个对话框类.
context.Forward()和context.Call()之间的区别主要在于context.Forward()允许你转发一个messageActivity,它由被调用的对话框立即处理,而context.Call()只是启动一个新的对话框,没有移交任何东西.
在“根”对话框中,如果需要使用LUIS来确定意图并返回特定对象,则只需使用Forward将messageActivity转发给它,然后在指定的回调中处理结果:
await context.Forward(new TodoItemDialog(),AfterTodoItemDialogAsync,messageActivity,CancellationToken.None); private async Task AfterTodoItemDialogAsync(IDialogContext context,IAwaitable<TodoItem> result) { var receivedTodoItem = await result; // Continue conversation }
最后,您的LuisDialog类看起来像这样:
[Serializable,LuisModel("[ModelID]","[SubscriptionKey]")] public class TodoItemDialog : LuisDialog<TodoItem> { [LuisIntent("GetTodoItem")] public async Task GetTodoItem(IDialogContext context,LuisResult result) { await context.PostAsync("Working on it,give me a moment..."); result.TryFindEntity("TodoItemText",out EntityRecommendation entity); if(entity.score > 0.9) { var todoItem = _todoItemRepository.GetByText(entity.Entity); context.Done(todoItem); } } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。