【Rasa-Core源碼閱讀】Tracker

最近在做dialog policy相關(guān)的研究昧穿,實(shí)現(xiàn)就用了rasa的輪子,看源碼順便寫篇文章首尼。水平有限,還請指正言秸。

先吹一波

rasa core的代碼質(zhì)量非常高非常高非常高软能!我知道有許多中國工程師參與了開發(fā),牛逼举畸!

整體思路

我們先從執(zhí)行的角度來分析tracker的源碼

  • 是什么查排?如何初始化
  • 輸入是什么
  • 跟蹤了什么內(nèi)容
  • 如何更新狀態(tài)
  • 狀態(tài)如何表達(dá)

如何初始化 —— init

下面是init的全部代碼,非常簡單抄沮,我做了一些注釋方便理解雹嗦,其實(shí)源碼里面的注釋很多,原來的注釋大家就直接看源碼吧合是。多說一句,rasa的源碼寫得太漂亮了锭环,注釋詳細(xì)聪全,格式規(guī)范,讀起來就是享受辅辩。

    def __init__(self, sender_id, slots,
                 max_event_history=None):
        """Initialize the tracker.

        A set of events can be stored externally, and we will run through all
        of them to get the current state. The tracker will represent all the
        information we captured while processing messages of the dialogue."""

        # 可以跟蹤的最長歷史难礼,tracker記錄狀態(tài)是以event為單位的
        self._max_event_history = max_event_history
        # 歷史事件列表
        self.events = self._create_events([])
        # 這個(gè)id和rasa的chenel特性有關(guān)系
        self.sender_id = sender_id
        # slot列表
        self.slots = {slot.name: copy.deepcopy(slot) for slot in slots}

        ###
        # current state of the tracker - MUST be re-creatable by processing
        # all the events. This only defines the attributes, values are set in
        # `reset()`
        ###
        # 暫停標(biāo)志
        self._paused = None
        # 一些action記錄
        self.followup_action = ACTION_LISTEN_NAME
        self.latest_action_name = None
        self.latest_message = None
        # bot的上一個(gè)返回內(nèi)容
        self.latest_bot_utterance = None
        self._reset()

從init函數(shù)中我們可以知道些什么呢?

  • tracker是記錄一個(gè)用戶對話狀態(tài)的對象
  • tracker基于Event對象跟蹤對話狀態(tài)

Event

既然tracker是基于Event的玫锋,我們就來看看Event是啥

簡單來說蛾茉,Event就是對bot一切行為的抽象,每一個(gè)具體的事件類都繼承自Event基類

class Event(object):
    """Events describe everything that occurs in
    a conversation and tell the :class:`DialogueStateTracker`
    how to update its state."""

    type_name = "event"

    def __init__(self, timestamp=None):
        self.timestamp = timestamp if timestamp else time.time()

這種設(shè)計(jì)很優(yōu)秀撩鹿,使得tracker可以跟蹤系統(tǒng)預(yù)定義以外的事件谦炬,只要你自己實(shí)現(xiàn)一個(gè)Event的子類就行。說起來這是應(yīng)該是面向?qū)ο蟮幕驹O(shè)計(jì)思維,但是真正編碼的時(shí)候很難考慮周全键思。

rasa-core內(nèi)部實(shí)現(xiàn)了以下Event


Event子類

名字一看就知道大概什么意思了

下面我們看一下Event核心的方法apply_to()

class UserUttered(Event):
        def apply_to(self, tracker):
            # type: (DialogueStateTracker) -> None

            tracker.latest_message = self
            tracker.clear_followup_action()

看一個(gè)就行础爬,這是在干嘛呢?就是給tracker改屬性吼鳞,把一些和自己有關(guān)的內(nèi)容更新了看蚜。

為什么要有這個(gè)方法呢?因?yàn)槊總€(gè)Event需要修改的屬性不一樣赔桌,把這部分邏輯放到子類自己實(shí)現(xiàn)供炎,調(diào)用邏輯在tracker實(shí)現(xiàn),最大化復(fù)用代碼疾党。這同樣應(yīng)該屬于基礎(chǔ)思維音诫,那么自己做到了么(逃

狀態(tài)更新 —— update

    def update(self, event):
        # type: (Event) -> None
        """Modify the state of the tracker according to an ``Event``. """

        if not isinstance(event, Event):  # pragma: no cover
            raise ValueError("event to log must be an instance "
                             "of a subclass of Event.")

        self.events.append(event)
        event.apply_to(self)

就是這么簡單

輸出

上面說的內(nèi)容就是tracker的核心部分了,抽象非常優(yōu)美仿贬。題外話纽竣,推薦大家讀一讀Flask的源碼,我讀了一部分茧泪,說賞心悅目不為過蜓氨,那種架構(gòu)設(shè)計(jì)的嚴(yán)謹(jǐn)優(yōu)雅看著是真tm舒服。

tracker記錄了整個(gè)交流的過程队伟,提供了生成Story的接口和生成Dialog的接口

    def export_stories(self):
        # type: () -> Text
        """Dump the tracker as a story in the Rasa Core story format.

        Returns the dumped tracker as a string."""
        from dqn_policy.training.structures import Story

        story = Story.from_events(self.applied_events())
        return story.as_story_string(flat=True)

     def as_dialogue(self):
        # type: () -> Dialogue
        """Return a ``Dialogue`` object containing all of the turns.

        This can be serialised and later used to recover the state
        of this tracker exactly."""

        return Dialogue(self.sender_id, list(self.events))

其他接口

tracker還實(shí)現(xiàn)了很多接口穴吹,涉及到了rasa的各個(gè)部分,就不一一細(xì)說了嗜侮。里面很多是用來featurize的輔助接口港令,我也還沒把這部分研究透,后面會再寫一篇聊featurize锈颗,這是rasa core的核心組件

總結(jié)一哈

tracker是rasa core中承上啟下的一環(huán)顷霹,它記錄來自前端輸入的數(shù)據(jù),又為模型訓(xùn)練的featurize提供基礎(chǔ)击吱。從tracker出發(fā)基本能摸清楚整個(gè)rasa core的框架結(jié)構(gòu)淋淀。rasa core抽象做得非常好,代碼質(zhì)量賊高覆醇,必須吹一波朵纷。這部分源碼相對比較簡單,注釋非常詳細(xì)永脓,讀起來很舒服袍辞,推薦大家都讀一讀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末常摧,一起剝皮案震驚了整個(gè)濱河市搅吁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖似芝,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件那婉,死亡現(xiàn)場離奇詭異,居然都是意外死亡党瓮,警方通過查閱死者的電腦和手機(jī)详炬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寞奸,“玉大人呛谜,你說我怎么就攤上這事∏固眩” “怎么了隐岛?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長瓷翻。 經(jīng)常有香客問我聚凹,道長,這世上最難降的妖魔是什么齐帚? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任妒牙,我火速辦了婚禮,結(jié)果婚禮上对妄,老公的妹妹穿的比我還像新娘湘今。我一直安慰自己,他們只是感情好剪菱,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布摩瞎。 她就那樣靜靜地躺著,像睡著了一般孝常。 火紅的嫁衣襯著肌膚如雪旗们。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天构灸,我揣著相機(jī)與錄音蚪拦,去河邊找鬼。 笑死冻押,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的盛嘿。 我是一名探鬼主播洛巢,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼次兆!你這毒婦竟也來了稿茉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎漓库,沒想到半個(gè)月后恃慧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡渺蒿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年痢士,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片茂装。...
    茶點(diǎn)故事閱讀 38,566評論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡怠蹂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出少态,到底是詐尸還是另有隱情城侧,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布彼妻,位于F島的核電站嫌佑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏侨歉。R本人自食惡果不足惜屋摇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望为肮。 院中可真熱鬧摊册,春花似錦、人聲如沸颊艳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽棋枕。三九已至白修,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間重斑,已是汗流浹背兵睛。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留窥浪,地道東北人祖很。 一個(gè)月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像漾脂,于是被迫代替她去往敵國和親假颇。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 概念: FastDFS是余慶(前阿里巴巴架構(gòu)師骨稿,現(xiàn)易到用車架構(gòu)師)開發(fā)的一個(gè)開源的輕量級分布式文件系統(tǒng)笨鸡,對于小文件...
    yingyingguigui閱讀 5,737評論 0 2
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,090評論 1 32
  • core package 概要:Core是所有其他包的基礎(chǔ)包.它提供了大部分功能包括metadata姜钳,templa...
    LOVE小狼閱讀 2,559評論 0 3
  • 本文章是 Vert.x 藍(lán)圖系列 的第二篇教程。全系列: Vert.x Blueprint 系列教程(一) | 待...
    sczyh30閱讀 2,021評論 0 10
  • 和發(fā)小約了一場旅行形耗,兩個(gè)女人哥桥,各自帶著一個(gè)剛滿4歲的兒子,相約千里之外的南方城市激涤,因?yàn)槌霭l(fā)地不同拟糕,所以選擇...
    卷卷的圓寶閱讀 444評論 2 2