[Golang][LineBot][2018 更新部分] 透過微軟的語言學習服務 LUIS 架設具有 AI 對話的聊天機器人

前言:

這篇文章其實講解了兩年前為了去 COSCUP 弄的專案(https://github.com/kkdai/LineBotBabyLuis) ,因為當初其實也沒有花太多時間講解開發的內容. 並且也沒有講解如何實現.

如果有興趣當初演講內容的話,可以查看以下兩份投影片:

這篇文章主要講解最近一週,為了讓這個機器人復原所做的一些修改的部分.並且補充了 LineBotLUIS 的執行循序圖,希望讓有興趣的人能夠更清楚的了解.

關於 LineBotLUIS 的簡單介紹:

LineBotLUIS (https://github.com/kkdai/LineBotBabyLuis) 主要是兩年前開發的實驗性質產品.那時候想要結合 NLP 學習的 AI 引擎 (MSFT LUIS) 並且透過 LineBot 的交互式對談的方式,能夠讓這個機器人做到自我學習.

整個機器人就是模擬一個小孩子啞啞學語機器人,大致上流程如下.細節可以再看(循序圖):

  • 輸入小孩子講的話語 (e.g. shi shi, mi~ mi~, ㄋㄞ ㄋ ㄞ ..)
  • 如果她已經學會了,他會告訴你以往的意圖.如果不會它會問你說這句話的意圖是什麼
  • 你可以從 抱抱,牛奶,奶嘴或是玩具之中選擇一個小孩子可能的意圖.(可能就是你了解你小孩子想什麼之後)
  • 然後透過 LUIS 就會學習到,並且之後打出類似的話語就會辨識出來小孩子的意圖.

聽起來很神奇?其實並不難…

架構與近期修改的部分:

這個部分除了 LineBot Webhook (https://github.com/kkdai/LineBotBabyLuis) 的相關處理外,另外還有一個要處理 LUIS API 的 LUIS SDK .這邊是透過我兩年前開發的套件 (https://github.com/kkdai/luis) ,並且也於日前將 API 升級到了 2.0 .

其實本來也沒有太大問題,不過主要是因為微軟日前已經將 LUIS 1.0 API deprecated 掉了.導致我必須將相關的 API 服務都改成 2.0 的服務.

最後, LineBot SDK 也有一些改動.兩年前的 Token 傳遞方式也有變動,造成我必須更新 LineBot Go SDK 的版本之外,其實他們對於 PostAction 的反應也有修改.這邊也會稍微提一下.

關於 LUIS v2.0 修改的部分:

講到 LUIS,就是微軟開發的語意學習引擎 (luis.ai),他將每一句會區分為 Intent(意圖)Entity (物件) .而學習出來的機器模型會根據你輸入的 utterance(話語) 來 Predict(預測) 你的意圖.

先來提提 LUIS 改變到 v2.0 API 的相關修改:

  • Training 跟 Publish 分開來,Training 後必須要 Publish 才能讓你的 Prediction 拿到最新的資料.
  • Prediction 的 API 網址有變動.這邊比較奇怪的是,他不像是一般的 API 從 1.0 換到 2.0 而是整個網址換掉.並且跟其他的 API entrypoint 都不一樣.
  • 其他還有就是要加入 Intent 變得更加的麻煩,不過還好 LineBotLUIS 本身並沒有提供新增 Intent 的方式.

關於 LineBot SDK 的更新:

那回過頭來談談,這一年多來其實 LineBot Go SDK (https://github.com/line/line-bot-sdk-go) 也有一些修改.加上 Line Bot Webhook 的 calling sequence 也有一些些修改如下.

  • Token 的存放位置有變,這邊並不需要改 code ,你只需要更新 Line-Bot-SDK-Go 套件就可以了.
  • 對於 PostAction 的回覆,之前只會傳回一個 Message Event 為 EventTypePostback .更改過後,會傳兩個進來.一個為原有的 EventTypePostback ,又多傳一個 TextMessage. 根據官方部落格文章 開發LINE聊天機器人不可不知的十件事 ,可以了解官方建議你如果要設定 PostAction 的文字,就必須要設定一個無法再 TextMessage 裡面產生作用的特殊字元組合. (e.g. [我要喝牛奶mileQQ~~~]) 類似..

LineBotLUIS 的學習循序圖 (Sequence Diagram):

以上是如何讓 LUIS LineBOT 學習的循序圖,幾個重點可以跟大家分享一下.

  • 使用者輸入任意的文字
  • 如果是 LUIS model 不認識的,或是無法找到最高分的意圖(intent)
  • 這時候就會透過 LineBot Webhook 傳回 Post Action 也就是會顯示目前系統本來就有的意圖(intent)來讓使用者選擇
  • 這時候使用者選擇相對應的意圖後,馬上就會加入該話語到意圖中.並且啟動訓練(training),這就是故意要造成 Streaming Learning 的狀態.
  • 除了要 Training 之外,還要馬上將訓練好的模型發布(publish)出來.讓下一次輸入類似的話語就會找到相對應的意圖.

找得到的循序圖就相對應的簡單,只要找到相對應的意圖馬上就回覆給使用者.

待續

LineBotLUIS 透過呼叫微軟的 LUIS 人工智慧學習引擎,企圖製造出一個會學習的簡單機器人.並且透過 LUIS 似乎也可以打造出一個雖然沒有任何資料庫,但是也不會因為 Heroku 而會重新開始的學習機器人.

[Golang] 在 Kubernetes 上面透過 Go 開發 GRPC service 可能遇到的問題

前言:

之前為了幫公司的產品加上一個中間層的服務處理,需要把許多原先預設的 GRPC 服務參數都改掉,或是新增不少功能.在這裡整理一下,分享給大家.

本文會提供一個簡單的 repo 裡面有提到會使用到的一些功能,並且附上一個 Kubernetes 部署的 yaml 檔.

Show Me The Code

不囉唆,先看 REPO https://github.com/kkdai/grpc-example

原先的 GRPC 服務開始擴展:

一開始,我們先以 Hello World 為範例,並且省略相關的部分. 一開始 SayHello 的範例建置好之後. 這個範例(hello world) 相當簡單,就是一個 SayHello 然後傳回一個回覆. 我們可能會開始收到其他的需求…

以下的需求最後將整合到一個範例 repo https://github.com/kkdai/grpc-example

1: 能不能一次送多個指令 (streaming request)

你可能收到需求,需要在原先的服務上面新增一個接口可以處理連續性的請求 (streaming request) .或是在處理資料的時候不要一次都處理完才回復,而是處理完其中一個部分請求就先回傳 (streaming response).

這是一個相當範例,可以看到 SayStreamHello 並沒有增加新的資料欄位.而是沿用舊的資料欄位

rpc SayHelloStreamServer (HelloRequest) returns (stream HelloReply) {}

在 proto buffer 裡面其實要改得很少,但是處理方式就不太依樣.以下開始放相關的處理代碼.

首先看 Streaming Server 的 server 端的部分

這邊稍微解釋一下,由於你將回傳的資料改成了 streaming 的結果.所以你必須要將資料一筆一筆的傳回去. 這段範例中,我加上了兩秒的 sleep 讓 streaming 更有感覺.

再來看 Streaming Server 的 client 端的部分

由於資料都是由 stream.Recv() 取出來,所以你需要做檢查是否資料傳完了沒.這裡是透過 err == io.EOF 來檢查.

Streaming client 的部分,由於差不多請直接看程式碼 SayHelloStreamClient

2. 如何控制 GRPC service 的連線時間?

接下來能夠連續傳送資料之後,再來就是你會希望能夠讓你的 GRPC call 能夠更久一點.那麼你就會需要去修改你的連線方式.

這段程式碼裡面,可以看到 20*time.Second 就是我們連線的時間限制.你可以延長這個時間來達到增加呼叫時間,當然你也可以換個方式透過這個方式來控制你的時間限制.

3. 能不能大量的資料?

既然你的 GRPC 服務已經可以傳送大量的資料,那麼接下來就會有另外的需求: 能不能傳送相當大量的資料呢? 這裡定義的大量資料可能是超過 5MB 以上,因為 GRPC 預設的大小限制為 4 MB (source code)

	defaultServerMaxReceiveMessageSize = 1024 * 1024 * 4

那如果要修改的話,就依照以下的方式來修改.

這一段是要改成 server 將傳送的大小限制從 4MB 改到 8MB ,因為傳送資料是在 client –> server 這邊做第一次的控管,所以是由 server 來決定最多能傳送多大的資料.當然如果你希望 server 回傳資料可以傳大量的資料,就反過來要改在 client

當然,如果你想改 python 的 grpc server ,可以參考一下方式:

另外一方面.. C++ 的 GRPC server 可以參考:

[更新 20180819] 4. 關於部署到 Kubernetes 可能發生的問題

要部署到 Kubernetes 上,需要兩部分的 yaml 設定.而這裡可能會有一些問題發生. 首先讓我們來看 Deployment 的部署 yaml

Kubernetes Deployment yaml file

這邊的部署方面沒有太多問題,當初在 Dockerfile 設定也是將 clientserver 的檔案包在同一個 docker iamge . 然後透過不同的 entrypoint 來修改.

Kubernetes Service yaml file

這邊設定還算簡單,但是可能有個雷在這裡要小心.

關於 Kubernetes 服務 (service) 部署的小雷

這邊主要要注意到 service 的 selector 設定,要注意好

  selector:
    name: grpc-example 

如果設定不正確,將會導致 client 再透過 grpc-example.default 的連線方式如法正確找到 service .除錯的方式如下

除錯方式:

第一個先透過 kuberctl get endpoints 來確認每個服務(service) 都有相對應的 endpoint ,如果設定不正確可能會出現 endpoint 是空的狀態.

這時候建議回來檢查 service selector 確認是否能夠跟原本的 deployment 對應再一起,這裡建議的 selector 方式使用 name 來找是最簡單的.

總結:

這篇文章整理了幾個容易在撰寫 GRPC 服務的時候卡關的問題,希望能幫助到大家.所有的相關範例程式碼在: https://github.com/kkdai/grpc-example

參考

  • https://stackoverflow.com/questions/42629047/how-to-increase-message-size-in-grpc-using-python
  • https://nanxiao.me/en/message-length-setting-in-grpc/

[好書分享] 創意電力公司:我如何打造皮克斯動畫

前言:

很久沒有看實體的雜書(非程式設計相關的書籍),這一本很早之前就放在我的購物車裡面. 不過因為最近有朋友推薦了另外一本書,就一併買了下來.

但是開始看就欲罷不能,想不到一個週末就把它看完了. 內容讓我相當喜歡,決定想把自己一些心得拿來跟大家分享一下.

內容簡介:

作者 Ed Catmull 是皮克斯動畫工作室的創辦人之一.這本書就是敘述他如何創辦這間公司,並且公司被盧卡斯工作室賣給賈伯斯之後.進而發光發熱製作出許多膾炙人口的動畫影片 “玩具總動員” ,”海底總動員”, “蟲蟲危機” .近幾年更是被迪士尼所收購,成為夢想工廠重要的一員,進而製造出史上動畫最知名的”冰雪奇緣” .

整本書的內容圍繞在如何打造出一個具有創意的團隊.

從第一部的開端,如何創造皮克斯開始.這部分主要是傳達皮克斯建立的環境之外,還有他如何招募進來核心的員工,主要招募的準則就是找進來比他自己還聰明的人. 到了遇到了賈伯斯,離開盧卡斯之後.皮克斯也不是一凡風順的,一開始皮克斯是在賣圖像電腦(也就是影音剪輯電腦,搭配著賈伯斯當時買下的 NeXT 電腦.面臨著只賣出三百台的慘淡業績,讓他們好好思考要從事他們的熱情所在”電腦動畫”,於是乎他們跟剛好需要創新題材的迪士尼合作,簽下來發行三部動畫電影的合約.接下來,就是孕育出令人驚奇的”玩具總動員”.

這邊有個書上提到有趣的小插曲,就是賈伯斯看完”玩具總動員”的內容之後.就加緊找了 Ed Catmull 說 : “ 這部電影一定會讓皮克斯大紅特紅,我們要準備好各種條件.讓迪士尼接下來跟我們簽約的時候給予最好的報價”. 於是在玩具總動員上市的前一個月,他們不是忙著宣傳.而是不斷地尋找上市的相關準備,力圖在玩具總動員開演後一週上市. 當然接下來的故事就為人熟知,玩具總動員上映後打破了影史上相關的紀錄.不論是影評還是票房都是佳評如潮. 皮克斯也如願上市,並且之後跟迪士尼簽訂了更多的合作影片合約.

第一次重大的公司危機就發生在玩具總動員大成功之後.團隊所有人都忙著在做”蟲蟲危機”,而玩具總動員第二集由於被定義成續集,於是公司是透過另外一組人馬來製作. 這時候就發生了第二集的故事劇情令人不滿意,於是乎皮克斯把原本的劇情完全推翻.並且把公司全部人馬又找回來傾全力製作第二集.經過了這次的事件,皮克斯也更深信他們的核心思想 - “有趣而打動人心的故事”.

到第二部的實際運作創意團隊需要的重要條件,舉凡保護新點子,誠實與坦率的智囊團會議是一個很有趣的點子.我們都以為創意是靈光一現,但是他們告訴你創意就像是你的程式碼一樣,需要不斷檢查,運行後進行討論修改.任何我們熟知的熱門電影一開始都是完全不一樣的故事.因為一開始故事的發想是透過編劇與導演來討論出來,這時候會經過皮克斯內部的”智囊團”,是由一群專門”說故事”的人來討論故事的內容.但是皮克斯的智囊團制度有個很有趣的地方是,權力還是在導演的身上.也就是導演可以完全不聽信智囊團的建議. 但是由於智囊團的討論方式相當的正面,於事整個故事的打磨可以在非常順暢的狀況下進行.

恐懼與失敗的章節裡面更形容出創意人有趣的部分.我們都會以為創意人是具有強烈個人意見的,不容易聽信別人的建議. 並且很害怕失敗的發生. 但是在皮克斯裡面,第一個守則是 “一定會發生失敗”. 因為創意不是一次就能到位的東西,是需要不斷修改才能誕生的.這邊舉了一個例子是 “怪獸電力公司”.原本的點子是一個三十歲的會計師與他的故事書的插曲,由於故事書裡面的怪物跑出來後來變成他的朋友. 大家都知道後來的怪獸電力公司是完全不一樣的故事,這也是告訴我們就算一開始的構想是不夠完美的,但是透過團隊不斷的討論後來就能發展出打動人心的好故事.

第三個章節敘述了建立與維持,一個好的創意團隊需要不斷的自主學習與充電.由於皮克斯是充滿創意的公司,於是更需要大家有不斷的”養分”灌溉. 於是有了”皮克斯大學” .公司內部的類似讀書會的組織,並且定期找專業講師來上課.比如說很多電腦動畫師其實並不是美術相關科系出身,於是公司找了專業的美術老師來教導繪畫,讓每個工程師能夠更了解美術人員看東西的角度.

最後一個部分討論到了新挑戰,也就是後來皮克斯被迪士尼併購之後的故事.雖然皮克斯是被併購的公司,但是動畫的相關部門全部都由 Ed Catmull 統一來管理.這時候兩家部門的合併引發了不少直得討論部分. 首先幾個創辦人花了很多時間在兩個部門跑來跑去,並且導入皮克斯的智囊團到迪士尼的內部.讓他們許多傳統動畫的製作部分有了更多的故事琢磨的空間.

最後一個附錄討論了賈伯斯,由於賈伯斯才能造就皮克斯在最艱困的時候能夠堅持做自己想做的電腦動畫.所以最後一部分的附錄就討論了關於賈伯斯的部分,這部分我想有看過傳記可能會知道,就不多提了.

心得:

創意團隊的建立比起我想像中的更難,不僅僅因為創意團隊需要很多的討論.所以人與人之間的交流變得更加的重要,不像是程式碼的世界一樣,一個動人的故事需要注入許多人的經驗與歷練分享,才能討論出令人驚豔的故事.而創意的產生過程會經歷許多的撞牆期,這時候絕對不能害怕失敗.要大膽的失敗才會有創意被激發出來.

許多人也在說軟體工程師也是一個創意的產業,但是我認為軟體工程師比較像是建築工人,不斷地吸收養分進來讓我們能了解如何蓋房子才能又快又好.但是一個好的房子還是會需要不斷的進步,並且測試與改進.

建立一個以專業的團隊相當的困難,創意的團隊更難.需要更大量的人員討論空間,更要有能夠容忍失敗的空間.這些部分都是很值得好好學習的部分.

[投影片分享] Introducing Go channel and pipeline

鏈結

投影片

前言

前幾天在公司的內訓投影片,簡單介紹如何應用 Buffered Channel 跟 Unbuffered Channel 並且導入在 data pipeline 的應用

結果公司內部激發 Go 核心討論.. 讚讚

內容簡介

主要是講解 Go channel 跟 pipeline 的運用. 其中內容會帶到 buffered channel 與 unbuffered 的運用場景. 並且解釋 fan-in 與 fan-out .最後會帶到 pipeline 寫法與介紹 go-kit 裡面 endpoint 的用法.

補充

這個投影片是透過 Present 所製作的,這個算是官方常在 GopherCon 使用的投影片工具.主要有幾個特點:

  • 簡潔
  • 可以顯示程式碼
  • 還可以線上修改與執行

幾個點需要補充一下:

  • 線上修改 Present 的程式碼需要使用 “shift + enter” 來做換行.不然會有問題.

  • 除了顯示程式碼,也可以顯示圖片,但是常常需要調整顯示大小

[Podcast 分享] Kubernetes Origin, with Joe Beda

鏈結

前言

聽 Podcast 是我通勤時候最常做的事情,也是讓我可以練習聽力(但是沒練到說?) 的好機會. 這篇是我今天聽到覺得很有趣的事情,本來只想貼到臉書講個幾句,但是想到大家都不想很忙,所以決定幫大家把重點全部摘錄出來.順便介紹一些重要的角色.

聽完這篇才知道 Heptio 真是個很強大的公司,難怪 Dave Cheney 要離開 Atlassian 去那邊

來賓 - Joe Beda

Joe Beda, Craig McLuckieBrendan Burns 是 Kubernetes 當初的三位發起者. 而 Joe Beda 原本更是在 Google 工作過. 曾在微軟 IE 工程師出身的他,後來到了 Google 後就在 Google Talk 與 GCE 的部門開發相關服務. 後來在 Google 期間推動了 Kubernetes 的開源活動.之後離開了 Google 跟 Craig McLuckie 一起創立了 Heptio 一間專門幫忙企業來建置 Kubernetes 服務並且開源了許多有用的 Kubernetes 工具的公司.

話說 Kubernetes 三個發起者到頭來都不是 Google 的人.

  • Joe Beda 原本是 GCE 工程師,後來離開變成 Heptio CTO
  • Craig McLuckie 原本是 Google Group PM 後來變成 Heptio CEO
  • Brendan Burns 很久之前就離開 Google 並且在微軟成為傑出工程師

關於 Heptio 的開源工具

  • ksonnet: 一個方便部署 Kubernetes 服務的工具
  • Heptio Ark: 幫助你備份 Kubernetes 與做災難復原的工具
  • sonobuoy: 一個幫助你檢定你安裝的 Kubernetes 網路設定與基礎設定是否符合基本標準. (後來被 Kubernetes Conformance 大量採用)
  • contour: 一個 Kubernetes ingress controller 用在 Lyft’s Envoy proxy. 這是我們大家熟悉的 Dave Cheney 的主要工作
  • gimbal: gimbal 是 ingress load balancing platform 可以在多個 Kubernetes 或是 openstack 上面使用

演講內文

這裡我會挑出幾個有趣的問題,將他解釋清楚一點.

為何請到 Joe Beda

Kubernetes 在近期剛好歡慶四週年,他們就想找當初的發起人來談談到底為何會有 Kubernetes 這個產品.

Kubernetes 的起源

當時 Joe BedaCraig McLuckie 都主要在推廣 GCE 的服務,剛好有新的老闆來於是他們很興奮地展示 GCE 當時的功能. 當時 GCE 最為人津津樂道的就是他們開 機器(VM) 的速度超快,從設定好到機器安裝 OS 到開機只要數十秒鐘. 讓 GCE 團隊的人都很自豪,但是給他們新的老闆展示的時候就沒那麼有興趣了.

那時候他們才發覺到 GCP 要做的服務不僅僅是開機器快而已, 而是機器開好之後如何讓人能夠有效地使用它們. 所以這時候有兩種方向:

  • 第一種就是讓 Googler 放棄他們原先在使用 Container (註: Google container 並不是 docker container 而是 Google 自己特製的),轉而一起來開發 VM 上面的應用.
  • 不然就是讓 Google 內部的 container orchestration 工具 Borg 來給大家使用.

所以後來的聲浪就是後者,也就是想要打造之後稱為的 GKE (Google Kubernetes Engine) 一個給大眾使用的在 GCP 上面的集群管理系統.但是考量到 Borg 是由 C++ 打造而成,裡面充斥著太多 Google 內部的管理機密.加上當時的 Golang 與 Docker正在興起.於是他們參考了 BorgOmega 的概念,並且透過 Golang 來打造,底層一開始先使用 docker container 所建置而成.

談談 Kubernetes 開源這件事

大家或許會認為 Google 很樂意將許多產品開源,從 Android 到 Chromium.但是其實要將 Kubernetes 開源在 Google 內卻有許多的討論,Google 之前曾經發表過 Map Reduce Paper 後來被其他公司的工程師看懂後開發出 Hadoop 或是 Big Table Paper 也被開發成 HDFS 的系統. 但是 Google 都沒有公佈任何原始碼 . 所以再決定要開源 Kubernetes 的立場上, Google 也決定要更認真的經營社群.

許多新的功能被要求加進去 Kubernetes

就像是 Serverless 或是 Machine Learning 的相關運用,都是近幾年 Kubernetes 相當熱門的衍生應用. Joe Beda 說他被太多人問說有想要加上的特殊功能.但是他建議這樣的功能應該寫在系統之外,讓 Kubernetes 專注在精簡的功能.

Joe Beda 也表示,他希望四年可以期待看到 Kubernetes 維持目前 Boring (指的是單純,沒有太多額外功能)而看到越來越多人發展 Kubernetes 相關的應用.

Reference Link:

[TIL] 關於 Omnigraffle 一些相關資源

要做投影片的時候,需要有一個方便畫流程圖的軟體,於是買了 Omnigraffle .希望可以找到許多的已經畫好的框架幫助自己在做投影片的時候有所幫助. 找到一些資料列出如下:

Omnigraffle Stencils

StencilTown 是一個使用者預先準備好的圖形樣板,可以直接下載後套入使用

Google Cloud Official Icons

參考這個網站,提供各種格式的 Google Cloud Platform Icons (PPT, Google Slide, Draw.io 甚至是 PNG)