You need to enable JavaScript to run this app. Bot Framework 自适应对话框中如何使用partial类的自定义LUIS属性
优惠活动
大模型
产品
解决方案
定价
更多

Bot Framework 自适应对话框中如何使用partial类的自定义LUIS属性

核心报错原因

你写的表达式跑不通,本质是搞错了两套体系的边界:

  • 你在AssistantRootDialog分部类里写的PhoneUser这类自定义属性,是纯C#编译期的强类型访问封装——它本质是带兜底逻辑的快捷getter,自己没有对应的可序列化字段,根本不会被存到自适应对话框的运行时状态结构里。
  • SetProperty.Value里写的=xxx格式的内容,是自适应表达式引擎在运行时动态解析的字符串,它读的turn.recognized是序列化后的LUIS结果JSON,只能顺着已有的结构访问意图、实体这些基础字段,根本读不到你在C# partial类里自定义的编译期属性。就算你把表达式里的字段名改成完全正确的turn.recognized.PhoneUser,引擎也找不到对应的值。
两种可落地的正确实现

方案1:把封装逻辑转成表达式规则(简单场景用)

如果你的PhoneUser逻辑就是取第一个匹配的ContactName、找不到就兜底为<no user>,直接把逻辑翻译成自适应表达式语法就行,完全不需要依赖C#端的属性:

new SetProperty() {
  Property = "conversation.find.phone.userName",
  // 逻辑和C#版的PhoneUser完全等价
  Value = "=if(turn.recognized.Entities?.ContactName != null && turn.recognized.Entities.ContactName.count > 0, turn.recognized.Entities.ContactName[0], '<no user>')"
}

这种写法完全适配表达式引擎的运行时规则,不需要额外改其他代码。

方案2:复用partial类的自定义逻辑(复杂场景用)

如果你的PhoneUser里写了多步判断、格式转换这类复杂逻辑,不想在表达式里重复造轮子,就别用内置的SetProperty了,换成CodeAction在C#层直接赋值:

new OnIntent(nameof(AssistantRootDialog.Intent.LookForMobilePhone)) {
  Actions = new List<Dialog>() {
    new CodeAction(async (dc, cancellationToken) => {
      // 从对话上下文中取出已经完成转换的强类型LUIS结果
      var luisStrongResult = dc.Context.TurnState.Get<AssistantRootDialog>();
      // 直接调用partial类里写好的封装属性取值
      var phoneUserName = luisStrongResult?.PhoneUser ?? "<no user>";
      // 手动写入对话状态的目标路径
      dc.State.SetValue("conversation.find.phone.userName", phoneUserName);
      return await dc.EndActionAsync(cancellationToken);
    })
  }
}

这种方式可以完整复用你在partial类里写的所有逻辑,不需要在表达式端重复实现。

注意点

你之前写的错误表达式除了访问规则的问题,还有字段名笔误:想访问PhoneUser却写成了PhoneNumber,就算引擎支持自定义属性访问,这个字段名也匹配不上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 18:36:10