gpt4 book ai didi

C# Microsoft Bot Framework 与 luis 结果指向 QNA Maker 和图形 api

转载 作者:太空狗 更新时间:2023-10-29 21:52:46 24 4
gpt4 key购买 nike

我使用 Microsoft 机器人框架制作了一个机器人,并使用 Luis 来匹配意图。一些意图将其指向 QNA,而另一些意图将其指向图形 api。

我的问题是确定是应该去 qna 搜索 qna 中的相关意图还是应该去 graph api 获取结果的最佳方法是什么。

到目前为止,我使用多个 Luis Intents 来匹配正确的意图,然后根据所需的意图功能将其重定向(无论是将其定向到 qna 对话框还是 graph api 对话框)。

`[LuisModel("模型 ID", "键")]

[Serializable]
public class RootDialog : DispatchDialog
{

//this intent directs to graph api dialog
[LuisIntent(DialogMatches.GraphApiIntent)]
public async Task RunGraphapiIntent(IDialogContext context, IActivity activity)
{
UserMessage = (activity as IMessageActivity).Text;
await context.Forward(new GraphApiDailog(), EndDialog, context.Activity, CancellationToken.None);
}

//This intent directs to qna dialog
[LuisIntent(DialogMatches.BlogMatch)]
public async Task RunBlogDialogQna(IDialogContext context, LuisResult result)
{
var userQuestion = (context.Activity as Activity).Text;
(context.Activity as Activity).Text = DialogMatches.BlogMatch;
await context.Forward(new BasicQnAMakerDialog(), this.EndDialog, context.Activity, CancellationToken.None);
}
`

但是这种方法要求我使用 [LuisIntent("intentstring")] 来匹配每个意图。因为我可以有 50 或 100 个意图,所以为 50 个函数编写 50 个函数是不切实际的意图。

我在 Quickstart: Analyze text using C# 中找到了一种调用 api 以从话语中获取意图的方法

它利用“https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/df67dcdb-c37d-46af-88e1-8b97951ca1c2?subscription-key= &q=turn on the bedroom light”用于获取意图的 API。

同样,我的问题是我如何知道我是否应该将它重定向到 QnaDialog 或 Graph Api Dialog 以使用我得到的意图结果获取数据?

提前致谢

最佳答案

如果您希望事情能够扩展,您最好编写自己的 Nlp 服务来调用 Luis API 来检测意图。我认为按意图处理对话重定向的最佳方法是制作类似于 IntentDetectorDialog 的东西,它的唯一工作是分析用户话语并转发到与检测到的意图相对应的对话。

这是我已经使用了一段时间的巧妙方法:

public abstract class BaseDialog : IDialog<BaseResult>
{
public bool DialogForwarded { get; protected set; }

public async Task StartAsync(IDialogContext context)
{
context.Wait(OnMessageReceivedAsync);
}

public async Task OnMessageReceivedAsync(
IDialogContext context,
IAwaitable<IMessageActivity> result)
{
var message = await result;

var dialogFinished = await HandleMessageAsync(context, message);

if (DialogForwarded) return;

if (!dialogFinished)
{
context.Wait(OnMessageReceivedAsync);
}
else
{
context.Done(new DefaultDialogResult());
}
}

protected abstract Task<bool> HandleMessageAsync(IDialogContext context, IMessageActivity message);

protected async Task ForwardToDialog(IDialogContext context,
IMessageActivity message, BaseDialog dialog)
{
DialogForwarded = true;
await context.Forward(dialog, (dialogContext, result) =>
{
// Dialog resume callback
// this method gets called when the child dialog calls context.Done()
DialogForwarded = false;
return Task.CompletedTask;
}, message);
}
}

基础对话框,所有其他对话框的父级,将处理对话框的一般流程。如果对话尚未完成,它将通过调用 context.Wait 通知机器人框架,否则它将以 context.Done 结束对话。它还将强制所有子对话框实现 HandleMessageAsync 方法,该方法返回一个 bool 指示对话框是否已完成。并且还公开了一个可重用的方法 ForwardToDialog,我们的 IntentDetectorDialog 将使用该方法来处理意图重定向。

public class IntentDetectorDialog : BaseDialog
{
private readonly INlpService _nlpService;

public IntentDetectorDialog(INlpService nlpService)
{
_nlpService = nlpService;
}

protected override async Task<bool> HandleMessageAsync(IDialogContext context, IMessageActivity message)
{
var intentName = await _nlpService.AnalyzeAsync(message.Text);

switch (intentName)
{
case "GoToQnaDialog":
await ForwardToDialog(context, message, new QnaDialog());
break;
case "GoToGraphDialog":
await ForwardToDialog(context, message, new GraphDialog());
break;
}

return false;
}
}

那是 IntentRedetectorDialog:BaseDialog 的儿子,它唯一的工作是检测意图并转发到相应的对话框。为了使事情更具可扩展性,您可以实现 IntentDialogFactory,它可以根据检测到的意图构建对话框。

public class QnaDialog : BaseDialog
{
protected override async Task<bool> HandleMessageAsync(IDialogContext context, IMessageActivity message)
{
if (message.Text == "My name is Javier")
{
await context.PostAsync("What a cool name!");

// question was answered -> end the dialog
return true;
}
else
{
await context.PostAsync("What is your name?");

// wait for the user response
return false;
}
}
}

最后我们有了我们的 QnaDialog:它也是 BaseDialog 的儿子,它唯一的工作就是询问用户的名字并等待响应。

编辑

根据您的评论,在您的 NlpService 中您可以:

public class NlpServiceDispatcher : INlpService
{
public async Task<NlpResult> AnalyzeAsync(string utterance)
{
var qnaResult = await _qnaMakerService.AnalyzeAsync(utterance);

var luisResult = await _luisService.AnalyzeAsync(utterance);

if (qnaResult.ConfidenceThreshold > luisResult.ConfidenceThreshold)
{
return qnaResult;
}
else
{
return luisResult;
}
}
}

然后将 IntentDetectorDialog 更改为:

public class UtteranceAnalyzerDialog : BaseDialog
{
private readonly INlpService _nlpService;

public UtteranceAnalyzerDialog(INlpService nlpService)
{
_nlpService = nlpService;
}

protected override async Task<bool> HandleMessageAsync(IDialogContext context, IMessageActivity message)
{
var nlpResult = await _nlpService.AnalyzeAsync(message.Text);

switch (nlpResult)
{
case QnaMakerResult qnaResult:
await context.PostAsync(qnaResult.Answer);
return true;

case LuisResult luisResult:
var dialog = _dialogFactory.BuildDialogByIntentName(luisResult.IntentName);
await ForwardToDialog(context, message, dialog);
break;
}

return false;
}
}

就是这样!您无需在 Luis 和 QnaMaker 中重复话语,您可以同时使用两者并根据更有把握的结果设置策略!

关于C# Microsoft Bot Framework 与 luis 结果指向 QNA Maker 和图形 api,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52337163/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com