You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 23:01:24