simdial 数据结构的分析, 以及如何融合 taskflow - tedrepo/SimDial GitHub Wiki

  1. 复杂度控制 Complexity 类

    将复杂度划分了 4 各部分, 从指定的 负载度空间配置类中加载

complexitySpec 复杂度配置类 对应的配置了 4个字典 ,用于提供概率配置 1. environment 控制asr 准确度: 使用的是正太分布 配置值是 均值和方差 2. proposition: 控制 action 选择的比例: yn_question : yes or no 问题出现概率 reject style: 槽位否认方式 1. reject 2. reject + inform multi_slots : 一次输出槽位的个数 多元分布 1: 2:[3: 4:] dont_care : 控制 槽位的值是否重要(是否为必填槽) multi_goals: 控制一个session 中需要的goal槽位的个数 多元分布 1: 2:[3: 4:] 3. interaction: 交互方式控制 (拟人化) hestiation: 是否犹豫 二元分布 self_restart: 重新开启会话 二元分布 self_correct:自我纠正 二元分布

    4.  社会化:
                 self_disclosure: none
                 ref_shared: None
                 violation_sn: None

channel 部分 为 生成的 action 列表, nlg生成的自然语句 添加扰动噪音 其中nvironmentNoise 为 各个action列表添加 置信度

领域配置信息类 multiple domain 其中各个子类继承了 DomainSpec 类 定义了对话的 ontolgy 信息 它持有的信息 1. domain name 领域名称 2. greet : 领域开启问话 3. nlg_spec: 配置了各个槽位的 nlg模板 nlg模板分为三类 1. inform 模板: 当前会话方给对方告诉当前的槽位信息 2. request 模板: 当前会话方向对方询问当前槽位的信息 3. yn_question 模板: 一般是 goal slot 才有,用户询问他知道的曹值是否是 系统的曹值

    4. 用户约束 槽位的实体信息
          包含的内容 1. 槽位名称 2. 槽位注释 3. 可选的实体内容
    5. 系统 goal slot 的实体信息
          包含的内容 1. 槽位名称 2. 槽位注释 3. 可选的实体内容
    6. db_size 当前领域 数据空中记录的条数

领域定义类 domain 领域定义类系列包含了三个 数据结构类 1. domainSpec 2. slot 3.domain

  1. domainSpec 第一个 domainSpec 的内容见上面的子类解释

  2. slot slot信息的封装类 封装了如下信息 1. slot name 2. description 槽位描述 3. vocabulary 槽位可以取值的实体字典 4. dim 槽位取值的个数 5. requests 槽位反问模板 6. inform 槽位输出模板 7. yn_question yes or no 问题模板 对外提供的功能接口函数 1. sample_request : 采样出一个request 2. sample_inform: 采样出一个inform 语句 3. sample_yn_question: 采样出一个 yes or no问题 4. sample_difference : 采样出一个不同的value值

  3. domain 类 domain 类定义了一个确定领域对话的ontolgy 信息,用于指导对话的生成

    它含有的数据字段有: 1. domain name : 领域名称 2. greet : domain 开启系统语句 3. usr_slots : 用户约束槽位信息 信息是 三元组 (slotname, slot desc, slot vocab)的列表 4. sys_slots : 系统goal槽位信息 信息是 三元组 (slotname, slot desc, slot vocab)的 5. db : 领域数据字典 初始化时,需要做的操作 使用 domain_spec 的信息填充上面的数据结构 将模板信息,实体字典 填充到 slot 数据结构中 加载数据库

    对外提供的接口函数: 1. get_usr_slot 获取指定slot name或slot index的user slot实体 2. get_sys_slot 获取指定slot name或slot index的system slot实体 3. is_usr_slot 判断给定的query name 是否是用户slot

核心结构 涉及到的类有 1. agent 的抽象类 2. Action 的封装类 3. state 状态管理器的抽象类 4. 系统动作的枚举类, 5. 用户动作的枚举类 6. BaseSysSlot 的枚举类 7. BaseUserSlot 的美家居类

  1. agent 的抽象类 定义了 用户agent 和系统agent 需要持有的基本数据结构 和 对外功能 持有的数据结构: 1. domain : 领域的onotlgy 信息 2. complexity: 复杂度控制信息 对外的交互接口 1. step 接收另一个代理的动作,作出应答返回一个action 列表

  2. Action(dict): Action 的基类 描述agent的最小动作单元 持有act 类型 和act 参数列表[(slot_name=slot_val),] 持有的数据结构: 1. act 类型 2. act 的参数列表 是(slotname , slotvalue) 的一个元组列表, 元组还可以添加附加信息 对外的接口 add_parameter(type, value) : 想参数列表中添加 slotname 和 slotvalue

  3. State 状态管理器的基类, 用于状态追踪

  4. sysmAct 的枚举类, 可用的act 有 IMPLICIT_CONFIRM = "implicit_confirm" # 含蓄的确认 EXPLICIT_CONFIRM = "explicit_confirm" # 明确的确认 INFORM = "inform" # REQUEST = "request" GREET = "greet" GOODBYE = "goodbye" CLARIFY = "clarify" ASK_REPHRASE = "ask_rephrase" ASK_REPEAT = "ask_repeat" QUERY = "query"

  5. UserAct 用户动作的枚举类 GREET = "greet" INFORM = "inform" REQUEST = "request" YN_QUESTION = "yn_question" CONFIRM = "confirm" DISCONFIRM = "disconfirm" GOODBYE = "goodbye" NEW_SEARCH = "new_search" CHAT = "chat" SATISFY = "satisfy" MORE_REQUEST = "more_request" KB_RETURN = "kb_return"

  6. 基本基本槽位的枚举类 PURPOSE = "#purpose" DEFAULT = "#default"

7 基本用户槽位的枚举类 NEED = "#need" HAPPY = "#happy" AGAIN = "#again" SELF_CORRECT = "#self_correct"

NLG 类部分 nlg 部分包含的类有: 1. AbstractNlg nlg的抽象类 2. Syscommon Nlg 系统common类, 保存了sys nlg 的模板 3. SysNlg 根据 系统动作 匹配模板 4. UserNlg 根据用户 action 列表使用你人化的方式拼接各个action对应的模板

  1. AbstractNlg nlg 的抽象类 nlg 持有的 数据类型为: 1. domain 对话领域的ontology 信息 2. complexity 复杂度控制信息

    对外的函数接口: 1. generate_sent() 自然语句生成函数,根据 action 列表 ,生成 一句query 2. sample() 在一些example中随机的选择一个样本

  2. SysCommonNlg 系统nlg 的模板类 定义了一个 action 组合到 对话模板的一个字典 ,这些action 一般是不带有槽位的,和没有曹值的

  3. SysNlg: 系统 agent 的sysnlg 类 使用 ongology 和 template 来生成自然语言 对外的接口函数 gnerate_sent(action, domain, templates) 遍历 每一个action 如果当前的action是 SystemAct.GREET 如果定义了domain 则追加上领域问候 否则 从 系统 common 模板中采样出一个 语句 如果 系统动作是 SystemAct.QUERY: 从 动作列表中取出 1. 所有的用户约束槽位值 2. 系统目标槽位 从中收集信息生成查询语句 以json的格式dump成字符串 如果当前的动作是 INFORM 遍历从action 参数中取出 (槽位类型 槽位追踪值 槽位期望值)的列表 如果期望槽位值存在 查询出的槽位值和期望槽位值相同, 那么添加前缀 是的, 否则添加前缀 不是 将前缀与槽位采样出来的request 进行拼接 将 action的参数该为 gaol的追踪值的字典 将拼接结果添加到 nlg 回复列表中 如果当前的系统动作是 SystemAct.REQUEST 从参数列表中取出 slot type 如果 槽位类型为 core.BaseUsrSlot.NEED, core.BaseUsrSlot.HAPPY 则从common 模板中采样话术 否则从domain中取出对应的slot类实体, 在它的request列表中采样 request 话术 追加到自然语言回复列表中 如果当前的动作为 SystemAct.EXPLICIT_CONFIRM: 从action 参数中取出 slot type 和 slot val 如果slot value 为空: 认为 该slot为dont care 将 action的参数 的slotval改为 dontcare 否则 询问用户是否是当前追踪的曹值 Do you mean %s?" % slot.vocabulary[slot_val] 将参数改为当前追踪的曹值 如果当前的动作为 SystemAct.IMPLICIT_CONFIRM: 取出 slot_type slot_val 如果追踪的slot val 为空 处理方法同上 否则: 告诉用户 自己相信当前询问到的曹值是 当前追踪到的曹值 "我相信你说的是 %s." % slot.vocabulary[slot_val] 将 action 的参数中的 slot value从value idx 改为对应的曹值: a_copy.parameters[0] = (slot_type, slot.vocabulary[slot_val]) 如果不是上面的所有 action: 从 common 中 采样出对应的无槽 模板句子 将更新后的action 添加到lexicalized_actions

    返回 str_action, 和 lexicalized_actions
    
  4. UserNlg: 遍历生成的user action列表 如果当前的act 为 UserAct.KB_RETURN: 从action 参数中取出 sys_goals 为 每个sys goal 将 slot value 的idx 换成 数据库存储的 slot value 将 goal slots 字典以 json的形式返回

       如果当前的用户动作是 UserAct.GREET
             就从候选的问候模板中采样出问候语句
    
       如果当前 用户动作是 UserAct.GOODBYE:
             就从告别模板中采样一个告别语句
    
       如果当前的用户动作是 UserAct.REQUEST:
             从action的参数中提取出slot type
             从domain中采样出当前对应的系统 goal slot对象
             从goal slot 对应的模板中采样出一个request 语句
       如果当前用用户动作是 UserAct.INFORM:
             首先取出用户动作的最后一个参数, 判断当前的动作是否带有 self correct
             从参数中取出 slot type, slot val
             从ontology 中取出对应的 slot 对象
             
             定义一个 根据slot value 生成utt的函数
                   如果 slot value 是None
                         就采样一个可忽略的回复
                   否则
                        从slot 对象中采样一个 inform query 将值填充进去
    
             如果action 带有用户自身纠正的参数
                   就从target value 中采样出一个错误的value
                   使用上面定义的函数返回一个错误值的用户slot语句
                   使用上面定义的函数返回一个正确值的用户slot语句
                   从自纠正连接话术模板中采样一个连接语句, 将上面两个语句进行拼装
             否则
                使用上面定义的函数返回一个正确值的用户slot语句,填到 返回话术list中
       如果 用户的动作是  UserAct.CHAT 
             采样一个闲聊话术填充到 返回话术list中
       如果 用户的动作是  UserAct.YN_QUESTION:
             从 动作参数中取出 slot_type, 和 期望的goal value的index
             从domain中取出 对应的target slot 对象
             从target slot 对象的字典中采样出期望value
             从 target slot 对象的yn query 并将期望值填充进去
    
       如果用户的动作是 UserAct.CONFIRM:
             就从确认话术中采样一个确认话术
    
       如果用户的动作是 UserAct.DISCONFIRM:
             就从否认话术中采样一个否认话术
    
       如果用户的动作是 UserAct.SATISFY:
             从 满意话术中采样一个 满意话术
      
       如果用户的动作是  UserAct.MORE_REQUEST:
             从 更多问题话术中采样一个 更多问题话术
    
       如果用户的动作是 NEW_SEARCH:
             从 再查询话术中采样一个 再查询话术
    
       否则返回