SYS agent 的处理逻辑 - tedrepo/SimDial GitHub Wiki

system 部分使用的一个概率模型的 状态追踪类实现的, action的处理完全是基于概率的

  1. belief slot 的逻辑

计算 一个槽位上各个曹值概率分布 首先设置 阈值 EXPLICIT THRESHOLD = 0.2 显式确认的阈值 IMPLECT THRESHOLD = 0.6 隐式确认的阈值 GROUND_THRESHOLD = 0.95 基础阈值

a 初始化方法: uid vaue_map map key: slot value: prob last_update_turn : 上一次更新的轮次 b 添加一个新的观测 参数为 : value值, conf 置信概率, turn_id 轮次 将最近一次更新改为当前的turn_id

    # 更新曹值
    如果 这个值在value map中,更新置信概率: 
        prev_conf = self.value_map[value]
        self.value_map[value] = max([prev_conf, conf]) + 0.2
    如果之前没有出现过, 将其他出现的曹值的置信都减少一半
    记录当前曹值的置信为conf

c 根据 confirm_conf 和 disconfirm conf 更新槽位的置信值 参数 : confirm_conf, disconfirm_conf, turn_id, target_value=None) 更新 最后一次更新的轮次 如参数中没有目标曹值,选取置信最大的曹值为目标曹值

  使用如下公式更新:
        up_conf = confirm_conf * (1.0 - self.EXPLICIT_THRESHOLD)        # 对曹值的确认概率增益
        down_conf = disconfirm_conf * (1.0 - self.EXPLICIT_THRESHOLD)   # 对曹值的不确定概率增益
        old_conf = self.value_map[grounded_value]
        new_conf = max(0.0, min((old_conf + up_conf - down_conf), 1.5))   

d 获取最大置信的曹值 从 value map 中找到置信最大的曹值

e max_conf 从 value map 中找到做大的置信值 f clear: 将各个曹值的置信初始化为 self.IMPLICIT_THRESHOLD+self.EXPLICIT_THRESHOLD)/2.

BeliefGoal 类 goal slot 的状态追踪, 设置 阈值为 0.7

初始化:
    uid:  用户id
    conf : 置信度
    ddelivered: 是否发出了
    value : 当前的 value
    expected_value : 期望的值
 
 添加观测  参数 : 置信 conf , 期望值 exptected_value
     首先根据观测置信,更新 值的置信:  max(conf, self.conf) + 0.2
     更新 期望goal值 为 expected_value

 获取当前的置信

 发出:
   设置 delivered 为 true
 clear
   清空 置信 发出标志 期望goal值

DialogState(state): dm 的状态跟踪类 设置inform 阈值

初始化函数:
      持有的数据结构:
       history list 历史对话信息
       spk_state : 当前的对话状态
       user_beliefs : 有序字典,当前曹值的置信度列表
       sys_goals: 有序字典 当前 goal的置信列表
            初始化 默认goal 的置信为1.0
       valid_entries : 合法sample 从数据库中查询得到
       pending return :  发出 当前追踪到的所有约束曹值
       domian : 当前的domain
 
turn_id() : 返回当前的轮次

 gen_query() :  
   获取用户slot 最大置信的value 组成数据库查询语句

has_pending_reture():
   判断当前约束是否追加到return上

ready_to_inform() 判断当前是否可以输出信息了 遍历用户置信字典,判断每个槽位的最大置信是否大于基础阈值 遍历 goal slot 置信列表判断是否大于基础阈值

yield_floor: 判断系统动作是否在一下动作中 : SystemAct.REQUEST, SystemAct.EXPLICIT_CONFIRM, SystemAct.QUERY]

is_terminal(self): self.spk_state == State.exit

reset_sys_goals(): 重置 系统的goal置信列表, 将default goal 的置信设置为1.0

state_summary(): 当前状态的总结 1. 当前各个用户约束的置信最大的曹值和置信度 2. goal 的置信 发出状态 当前值 期望值 3. 当前的return 是否有追加的数据查询语句

system 的 逻辑 step 用当前的inputs 更新 state tracker 历史状态 函数循环遍历 处理用户actionlist 调用policy处理各个action 判断是否结束 返回训练信息

policy 中的具体内容: 1. 首轮判断 返回问候动作 和对 NEED 槽位的request 2. 终止判断 获取最近一次的用户动作列表 查看是否有GOODBYE 动作

   3. 判断是否有 pending 的查询结果
       如果有就返回 
        actions.append(Action(SystemAct.INFORM, [dict(query), goals]))
        actions.append(Action(SystemAct.REQUEST, (BaseUsrSlot.HAPPY, None)))
   4. 判断当前是否准备好输出了
         生成查询语句  (usr slot 约束 和goal 列表)
         返回动作 actions.append(Action(SystemAct.QUERY, [query, goals]))
   5. 其他状况
        填充3个list
             隐式确认列表  implicit_confirms = []
             显式确认列表   exp_confirm = []
             请求列表     requests = []

        遍历各个 约束槽位的置信字典:
            如果 当前槽位 的最大置信 小于 显式确认
                生成 一个Action(SystemAct.REQUEST, (slot.uid, None))) 添加到 显式确认列表中
            否则 小于 隐式确认
                生成一个  Action(SystemAct.EXPLICIT_CONFIRM, (slot.uid, slot.get_maxconf_value()))) 添加到request列表中
            否则 小于 基础阈值:
                生出一个 ction(SystemAct.IMPLICIT_CONFIRM, (slot.uid, slot.get_maxconf_value()))) 添加到  隐式确认列表中
       遍历各个 goal 的置信字典:
            如果 当前goal的置信 大于0 小于基础阈值
                 那么将 Action(SystemAct.REQUEST, (BaseUsrSlot.NEED, None)) 添加到request列表中
       总结上面三个列表:
           如果 exp_confirm 列表不为空
                  将 expconfirm的第一个 加上 implicit_confirm 列表输出
           否则如果request 列表不为空
                  将 request 的第一个 加上 implicit_confirm 列表输出
           否则
                 只输出 implict_confirm

装填更新逻辑 state_update() 参数 usraction 置信conf 如果usraction 内容为空 直接返回

 更新 state 的 历史信息
 更新 state 的 对话状态

 遍历 用户动作:
     1. act 为 confirm:
         取出 对应的slot 更新其状态追踪
               self.state.usr_beliefs[slot].add_grounding(conf, 1.0 - conf, self.state.turn_id())
     2. act 为 disconfirm
         取出对应的 slot 更新其状态追踪
               self.state.usr_beliefs[slot].add_grounding(1.0 - conf, conf, self.state.turn_id())
     3. act 为 INFORM:
         取出 参数中的slot 和slotvalue
             为这个值初始化置信
              self.state.usr_beliefs[slot].add_new_observation(value, conf, self.state.turn_id())
     4. act 为 REQUEST:
          取出参数中的slot
          更新goal的观测置信
          self.state.sys_goals[slot].add_observation(conf, None)
     5. act 为 new search:
          重置状态追踪中的 slot 置信列表
          重置状态追踪中的goal置信列表

     6. 当前用户的动作是yes or no 问题
         取出当前参数中的slot 和 对应的 slot value
         更新goal 的置信
         self.state.sys_goals[slot].add_observation(conf, value)
     7. 如果用户满意 sys goal的值,或者要求更多的goal时, 标注 该goal值是被用户接受的, 已经发出
           for para, _ in action.parameters:
                self.state.sys_goals[para].deliver()
     8.  如果 用户的动作是 kb——return , 那么根据 query 携带的goal值更新 goal的置信
            query = action.parameters[0]
            results = action.parameters[1]
            self.state.pending_return = query
            for slot_name, goal in self.state.sys_goals.items():
                if slot_name in results.keys():
                    goal.value = results[slot_name]

update_grounding(sys_actions): 根据已经选择的 sys action 更新基础置信 遍历 每一个选中的系统动作 如果当前系统动作是 IMPLICIT CONFORM 取出 slot 和其值 更新状态跟踪中的置信 self.state.usr_beliefs[slot].add_grounding(1.0, 0.0, self.state.turn_id())