You need to enable JavaScript to run this app. Microsoft Bot Framework主机器人与技能机器人上下文共享问题咨询
优惠活动
大模型
产品
解决方案
定价
更多

Microsoft Bot Framework主机器人与技能机器人上下文共享问题咨询

无法传递状态的核心原因
  • 状态实例天然隔离:主机器人和技能机器人是独立运行的服务,各自的TurnContext是每轮请求独立初始化的上下文对象,不存在跨机器人的自动传递机制,你在主侧存入TurnContext的属性不会自动出现在技能侧的上下文里。
  • 存储默认隔离:哪怕你主侧已经调用SaveChangesAsync持久化到存储,只要技能机器人没有配置和主机器人完全相同的存储实例,技能根本访问不到主侧存储的状态数据。
  • 存储键规则不匹配:就算两边用了同一个存储,Bot Framework的UserState/ConversationState默认生成的存储键会包含当前机器人的Bot ID作为前缀,主机器人和技能机器人的Bot ID不同,生成的存储键完全不一样,自然找不到同一份数据。
  • 属性名不统一:你当前的属性名是用typeof(RootBot<T>).FullName动态生成的,技能机器人的项目中不存在RootBot<T>类,两边的属性访问器的属性名不一样,就算读到同一份状态数据也匹配不到对应的属性。
可行的解决方案

方案1:通过技能调用的活动直接传值(最简单,适合少量数据共享)

不需要依赖状态存储,主机器人调用技能之前,直接把需要共享的状态存入待发送给技能的Activity的Value或者Properties字段:

// 主侧调用技能前插入
var skillActivity = (Activity)Activity.CreateMessageActivity();
skillActivity.Value = patientResponce;
// 后续正常调用技能

技能侧直接从入参读取即可:

// 技能侧OnMessageActivityAsync中读取
var sharedContext = turnContext.Activity.Value as PatientResponce;

方案2:统一状态存储与配置(适合大量数据需要多端共享)

  • 第一步:主、技能两个项目都使用完全相同的Blob存储连接字符串初始化UserState,并将UserState实例注册为单例。
  • 第二步:把状态属性名提取为公共常量,不要绑定各自的Bot类名:
// 公共类库中定义常量,两边都引用
public static class SharedStateConstants
{
    public const string UserContextPropertyName = "Shared.UserContext.PatientResponce";
}
  • 第三步:自定义状态的键生成逻辑,去掉Bot ID前缀的影响,保证两边对同一个用户生成相同的存储键:
// 两边都注册自定义的存储键生成器
public class SharedUserStateKeyGenerator : IStorageKeyGenerator
{
    public string GetKey(ITurnContext turnContext, string propertyName)
    {
        var userId = turnContext.Activity.From.AadObjectId ?? turnContext.Activity.From.Id;
        return $"UserState.{userId}.{propertyName}";
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 06:45:03