如何在C#中实现自定义问答(Custom question answering)的多轮提示功能
在C#中实现Custom Question Answering的多轮提示功能
前提准备
- 确保你的Custom Question Answering知识库已经配置了多轮提示(Follow-up prompts),即针对特定问题设置了关联的后续问题选项。
核心实现步骤
1. 获取Custom QA响应并提取提示
在调用Custom QA服务的代码逻辑中,获取QnA结果后,检查返回的QnAResponse是否包含上下文提示,再将提示转为交互按钮展示给用户:
using Microsoft.Bot.Builder.AI.QnA; using Microsoft.Bot.Schema; using System.Collections.Generic; using System.Threading.Tasks; public async Task<IActivity> ProcessQnAResponseAsync(ITurnContext turnContext, QnAMaker qnaMaker) { var qnaResult = await qnaMaker.GetAnswersAsync(turnContext); if (qnaResult != null && qnaResult.Any()) { var topAnswer = qnaResult.First(); var reply = MessageFactory.Text(topAnswer.Answer); // 检查是否存在多轮提示 if (topAnswer.Context != null && topAnswer.Context.Prompts != null && topAnswer.Context.Prompts.Any()) { var promptButtons = new List<CardAction>(); foreach (var prompt in topAnswer.Context.Prompts) { promptButtons.Add(new CardAction { Type = ActionTypes.PostBack, Title = prompt.DisplayText, Value = prompt.DisplayText // 也可使用prompt.QnaId实现精准匹配 }); } // 用Hero卡片承载提示按钮 var heroCard = new HeroCard { Buttons = promptButtons }; reply.Attachments.Add(heroCard.ToAttachment()); } return reply; } return MessageFactory.Text("抱歉,我暂时无法回答这个问题。"); }
2. 处理用户选择的提示选项
当用户点击提示按钮后,将按钮对应的内容作为新查询发送给Custom QA服务,直接复用已有查询逻辑即可:
public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default) { if (turnContext.Activity.Type == ActivityTypes.Message) { var qnaMaker = _services.QnAMakerService; var response = await ProcessQnAResponseAsync(turnContext, qnaMaker); await turnContext.SendActivityAsync(response, cancellationToken); } }
3. 维护对话上下文(可选)
如果需要在多轮对话中保留历史上下文,可通过QnAMakerOptions传递上一轮的上下文信息,并使用对话状态存储:
// 从对话状态中获取上一轮的QnA上下文 var qnaOptions = new QnAMakerOptions { Context = _conversationStateAccessor.CurrentState.LastQnAContext }; var qnaResult = await qnaMaker.GetAnswersAsync(turnContext, qnaOptions); // 保存当前上下文到对话状态 if (qnaResult.Any() && qnaResult.First().Context != null) { _conversationStateAccessor.CurrentState.LastQnAContext = qnaResult.First().Context; await _conversationState.SaveChangesAsync(turnContext); }
关键说明
- 按钮类型选择:
PostBack类型不会将按钮文本显示在聊天窗口,若需要显示则使用ImBack。 - 精准匹配:若要通过QnA ID直接获取对应答案,可将
prompt.QnaId作为按钮Value,查询时设置QnAMakerOptions.QnAId参数。 - 状态管理:使用Bot Framework的
ConversationState保存上下文,避免话题切换后上下文混乱。
内容的提问来源于stack exchange,提问作者Aiswarya
相关产品推荐
相关产品推荐

