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

如何用C#获取Microsoft QnA Maker多轮对话的isContextOnly标签?

解决QnA Maker isContextOnly标签在Bot Builder Dialogs中无法获取的问题

我之前也碰到过一模一样的问题——明明知识库配置了isContextOnly,但用C#的Bot Builder SDK就是拿不到这个属性。后来折腾了好一阵,总结了几个可行的方案,你可以根据自己的场景选:

方案一:自定义模型手动反序列化(最可靠)

默认的QueryResult类并没有映射isContextOnly字段,所以我们可以自己扩展这个类,然后手动处理API响应的反序列化:

  1. 定义扩展的查询结果类:
using System.Text.Json.Serialization;
using Microsoft.Bot.Builder.AI.QnA;

public class ExtendedQueryResult : QueryResult
{
    [JsonPropertyName("isContextOnly")]
    public bool IsContextOnly { get; set; }
}
  1. 绕过SDK的默认解析,直接调用QnA Maker API并反序列化到自定义类:
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;

public async Task<ExtendedQueryResult[]> GetQnAAnswersWithContextOnlyAsync(string question, string qnaEndpoint, string qnaSubscriptionKey)
{
    var client = new HttpClient();
    client.DefaultRequestHeaders.Add("Authorization", $"EndpointKey {qnaSubscriptionKey}");

    var requestBody = new
    {
        question = question,
        top = 1
    };

    var content = new StringContent(JsonSerializer.Serialize(requestBody), System.Text.Encoding.UTF8, "application/json");
    var response = await client.PostAsync($"{qnaEndpoint}/knowledgebases/your-kb-id/generateAnswer", content);
    var responseJson = await response.Content.ReadAsStringAsync();

    var qnaResponse = JsonSerializer.Deserialize<QnaResponse>(responseJson);
    return qnaResponse.Answers;
}

// 辅助类用于反序列化整体响应
public class QnaResponse
{
    [JsonPropertyName("answers")]
    public ExtendedQueryResult[] Answers { get; set; }
}

这样就能直接拿到IsContextOnly属性了。

方案二:利用Metadata字段间接传递(最灵活)

如果不想改代码调用方式,可以在QnA Maker知识库中,给需要标记isContextOnly的问答对添加元数据,比如新增键值对isContextOnly: true。然后在代码里从Metadata中读取:

var qnaResponse = await _qnaMaker.GetAnswersAsync(turnContext);
if (qnaResponse.Any())
{
    var contextOnlyMeta = qnaResponse.First().Metadata.FirstOrDefault(m => m.Name == "isContextOnly");
    bool isContextOnly = contextOnlyMeta != null && bool.Parse(contextOnlyMeta.Value);
    // 这里处理你的业务逻辑
}

这个方法不依赖SDK的内部实现,就算SDK更新也不会受影响,非常稳妥。

方案三:尝试升级SDK版本

部分旧版本的Microsoft.Bot.Builder.AI.QnA包确实没有包含isContextOnly的映射。你可以尝试把这个NuGet包升级到最新稳定版,然后检查QueryResult类是否已经有IsContextOnly属性。如果有的话,直接用response.Answers[0].IsContextOnly就能获取了。

方案四:反射临时取值(不推荐长期使用)

如果以上方案都不适用,你可以用反射临时获取这个属性,但要注意这依赖于SDK的内部实现,后续版本更新可能失效:

var firstAnswer = response.Answers[0];
var isContextOnlyProp = firstAnswer.GetType().GetProperty("isContextOnly", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (isContextOnlyProp != null)
{
    bool isContextOnly = (bool)isContextOnlyProp.GetValue(firstAnswer);
    // 处理逻辑
}

内容的提问来源于stack exchange,提问作者domac

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 08:43:12