根據尼爾森媒體( Nielsen )的調查, 12-65 歲的台灣⺠眾(這個年齡層幾乎涵蓋了所有的上網民眾),有將近 91% ,也就是將近 1,700 萬⼈都在使用 LINE 。換句話說,請人家掃描 QR Code 把你的服務加為好友,會比請人家安裝一個 App 來得容易,而且上手時間也比較短,因為操作介面是原本就熟悉的通訊軟體 LINE 。以往人們上網的第一件事,就是打開瀏覽器,用 Google 搜尋資料,未來很可能是打開通訊軟體,然後對著機器人聊天查詢資料。
想像一下,把 LINE@ 帳號背後的真人小編用機器人程式取代之後,會發生什麼事呢?可以確定的是,如果機器人能夠分擔部分工作,那麼真人將能夠把時間挪用去做更有生產力的事情。至於是哪些工作呢?一般而言,聊天機器人可以粗略分成兩類:任務型( Task-Oriented )和閒聊型( Chit-Chat )。前者有點像操作 ATM 提款機,使用者一次給予一個明確動作,逐步完成特定的任務(例如:提款),適合用於填寫訂單、查詢股價、常見問題等。後者則涉及對於人類自然語言的理解(以我們自身為例,就是中文),因為不容易處理,所以經常落入答非所問的窘境,比方說去年微軟 Twitter 聊天機器人被網友教壞變成種族歧視者的新聞。
因此,無論是何種類型的聊天機器人,開發者與其努力提供百分之百正確的答案(然而即使是真人,也有可能因為看錯問題而給錯答案),不如著重在操作流程(以聊天為例,就是一問一答的對話往返過程)的設計,正確引導使用者前往下一步,既不會迷失方向,也可以提升使用者體驗。尤其,如果可以在回應的答案裡面再增加一些趣味性和人味,勢必將可以提升整個服務的活躍率與黏著度。
今天我們想要先探討任務型的 LINE 聊天機器人。你只需要免費申請一個 LINE@ ID 當作聊天機器人的帳號,再搭配採用兩種免費平台 Google 文件和 Microsoft Azure 網站來當作聊天機器人的知識庫以及訊息接收與回應的後台,就可以組合出一個問答型的聊天機器人(就像我們會在 Google 輸入欄位裡面打「週末天氣」、「美食推薦」一樣),它將可以粹取使用者「問題」中的關鍵字,向知識庫查詢候選的「答案」,最後再將圖文並茂的結果回覆給使用者。
機器人的回覆往往不只是文字
假使曾經觀察過市面上的 LINE 聊天機器人應用(例如:餐廳訂位服務的 @eztable 、計程車叫車服務的 @taxigo 、英文學習的 @voicetube 、推薦鄉民熱門文章的 @poller.ai 等),再對照你自己與親朋好友之間的聊天視窗,可以發現到與真人對話以及與機器人對話之間,存在著幾個明顯的差異,更精確地說,應該是聊天機器人的介面酷炫多了!
機器人特有的下方主選單
下方主選單是機器人預設就有的功能, LINE@ ID 如果沒有轉換成機器人帳號,在後台的設定當中是找不到這個選項的,真人小編反而必須付費購買才有。
筆者猜測原因是為了幫助初來乍到的新使用者快速探索機器人的功能,因此允許開發者將最常用或最亮點的功能,放在下方主選單裡面。基本上,就是一張尺寸被定義好、版面佈局有固定規格的圖片,可以從 LINE@ MANAGER後台的「建立圖文影音內容」設定進去。
比方說 @eztable 是田字形 4 個選項(詳見圖 1 ),而 @voicetube 則是上半部 1 整個外加下半部 3 個選項(詳見圖 2 )。在這張圖片上面的點擊行為,可以對應到開啟網頁(全螢幕,但是並未跳離 LINE App )、輸出文字等,這兩種對應行為都還滿常見的。
機器人的對話比較豐富
大家平常 LINE 貼圖使用慣了,當然還有傳送文字、照片、影片等,這些機器人也都可以傳送與接收(沒錯,機器人也可以回覆貼圖博君一笑),但是有一種長方形的選項方塊(甚至多個方塊可以左右並列滑動),是只有機器人才有辦法產生的,讓使用者可以很輕易地從多個選擇當中挑選一個。根據開發者文件的講法,這類方塊叫做範本訊息( Template Message ),有按鈕型( Button )、確認型( Confirm )、旋轉木馬型( Carousel )共 3 類。
另外還有一種滿版大圖的回應,叫做影像地圖( Imagemap ),作用跟 HTML 的 map 標籤很像,尺寸最寬1040像素,可以不是正方形。點擊圖片上的不同區域,可以有不同的動作。
原則上,機器人這麼做就是要盡可能讓圖多於文、讓版面豐富、讓操作有趣,同時也讓使用者的互動被有效地限縮。呼應前言提到過的,目標是設計出一連串正確的操作流程,也就是用「工人」智慧(由人力參與許多前置處理作業,比方說使用者體驗的設計、選項文字的挑選等)去輔助人工智慧,讓使用者不易察覺出機器人其實沒有辦法完全理解使用者的每一個問題和請求。
比方說 @taxigo 就用這些方塊來詢問使用者要不要叫車或查看優惠卷(詳見圖 3 ),而 @poller.ai 則用來詢問使用者要不要觀看教學或設定偏好(詳見圖 4 )。
筆者建議如果從未將聊天機器人加為好友的話,不妨現在就去試試看上述提到的幾個應用,方法是打開手機裡的 LINE App ,點選左下角的好友分頁按鈕,再點選右上角的加入好友按鈕,選擇搜尋,輸入上述機器人的 LINE@ ID ,別遺漏開頭的「 @ 」特殊字元喔。對於 LINE 聊天機器人稍微有了初步的概念之後,接下來就輪到我們自己捲起袖子動手實作了。
申請 LINE@ ID 並且下載 SDK
第一步是免費申請 LINE@ ID ,請來到 LINE Business Center。電子郵件帳號是你用來登入個人 LINE 帳號的那個電子郵件,如果之前沒有登入過 LINE Business Center 或是 LINE 帳號沒有綁定電子郵件的話,這邊需要花點時間來設定一下,包括必須到手機端的 LINE App 設定裡面開通電子郵件帳號。
登入之後,依序點選「建立商用帳號」→點選「開始使用 Messaging API 」→設定圖片和名稱(就是我們平常在聊天視窗中,對方點擊了我們的大頭照時會看到的資訊)→設定業種的大分類和小分類→點選「申請」。
申請完成之後,點選「前往 LINE@ MANAGER 」。來到了 LINE@ MANAGER之後,依序點選「帳號一覽」→清單最上方應該就是剛才建立的那組 LINE@ ID →從左側選單點選「帳號設定」→點選「 Bot 設定」→點選「開始使用 API 」。
這裡會發現有一塊紅字警語,提醒一旦啟用 API 功能之後,機器人就無法恢復成真人(原本應該負責回應訊息的那位 LINE@ 小編)模式了。因為從此以後,使用者透過 LINE 所傳送的訊息,都會被轉送到開發者的後台(因此我們才會需要在下一個小節申請 Microsoft Azure 網站來作為訊息接收與回應的後台),而不會再儲存到 LINE 的主機上了。
啟用之後,「 Bot 設定」的畫面跟剛才第一眼看到時已經長得不太一樣了,與後台主機串接的設定,我們留待下一個小節再做說明。在此之前,有幾個設定建議可以先完成:
- 將「 Bot 設定」頁面的「請求設定」區域裡的「 Webhook 傳訊」設定成允許,雖然機器人程式要到下一個小節才會實作完成,不過搶先啟用倒是無妨。
-
將「 Bot 設定」頁面下方「詳細資訊」區域裡的「自動回應」取消,否則使用者每傳送一句話過來,就會收到一次機器人的罐頭回覆,相當囉唆。
-
從左側選單到「訊息」頁面去客製化問候語,當有新的使用者將機器人加為好友的時候,都會收到這段問候語,一般會寫一些操作說明,不過或許也可以寫得活潑一點,不要那麼罐頭。
話說回來, LINE 官方提供的 SDK 有好多種程式語言版本,可以從開發者網站的教學文章中找到,以 PHP 版本為例, GitHub 網址是 https://github.com/line/line-bot-sdk-php 。從資料夾結構來看,裡面除了有範例( examples )之外,還有一份精簡版的實作( line-bot-sdk-tiny ),裡頭包含了 Messaging API 的封裝( LINEBotTiny.php )以及 Echo 應聲蟲機器人範例( echo_bot.php ),其實這份精簡版的實作,就足夠我們變出許多把戲了。
申請 Microsoft Azure 網站並且實作 Echo 應聲蟲機器人
第二步是免費申請 Azure 帳號,以便建立網站作為接收與回應 LINE 訊息的後台。每次當需要自建網站的時候,筆者都會推薦去註冊微軟的 Azure 雲端服務,因為每個帳號可以免費建立 10 個網站(等級是F1,定價規則裡面有載明 ),當然主機等級會比較弱一點,但是初期測試服務雛形的時候都還夠用,如果不夠用的話,再付費加開資源即可,而且每個新帳號都有提供 30 天免費試用的額度。註冊過程會需要填寫信用卡資訊,不過如果沒有超額使用的話,並不會被索取費用。
請來到 Microsoft Azure 首頁,登入之後,依序從左側選單點選「應用程式服務」→點選「新增」→從「 Web Apps 」中選取「 Web 應用程式」→點選「建立」→輸入「應用程式名稱」(因為名稱將成為網址的一部分,所以不可以與其他人重複),其他欄位的資訊可以新建或使用現有的→點選「建立」。距離台灣最近的機房是東亞(East Asia),位於香港。
建立完成之後,點擊進入此應用程式服務,首次使用 Web 應用程式的話,需要先點選「部署憑證」來設定 FTP 帳號與密碼(請見Azure官方說明文件),以便透過 FTP 上傳的方式將聊天機器人的 PHP 程式碼放置到 Azure 網站上。
希望你還沒有關閉上一個小節裡, LINE@ MANAGER 的「 Bot 設定」頁面。在「狀態」區域裡有一個 LINE Developers 連結,點選之後即可進入開發者網站,裡頭有機器人程式所需的 2 項金鑰資訊:
- 點選「 Channel Secret 」欄位右側的 SHOW 按鈕以便看見明碼,並將這組金鑰複製起來,替換掉上一個小節的 line-bot-sdk-tiny 精簡版實作裡, echo_bot.php 程式碼第 22 行的 $channelSecret 變數的數值。
-
點選「 Channel Access Token 」欄位右側的 ISSUE 按鈕以便核發存取權杖,並將這組金鑰複製起來,替換掉上一個小節的 line-bot-sdk-tiny 精簡版實作裡, echo_bot.php 程式碼第 21 行的 $channelAccessToken 變數的數值。
修改完這 2 行程式碼並且存檔之後,將整個 line-bot-sdk-tiny 資料夾(包含 README.md 在內共有 3 個檔案)透過 FTP 上傳至 Azure 網站,就位在 /site/wwwroot 主機路徑底下,這裡就是網站的根目錄,如果覺得 line-bot-sdk-tiny 資料夾名稱太瑣碎,不妨直接縮寫成 line 。
接著繼續關注剛才的開發者網站頁面,準備點擊 EDIT 按鈕以便填寫「 Webhook URL 」欄位。這個欄位指出機器人程式的位置, LINE 會把來自使用者的訊息都往這個地方轉送過去。必須特別注意的是,網址必須是 HTTPS 開頭的,假使你本來就有網站主機,但是沒有 HTTPS 所需的 SSL 憑證,那麼可以考慮向 Let’s Encrypt 組織申請。所幸 Azure 網站本身就有支援 HTTPS ,如果剛才建立的 Web 應用程式的名稱是「 john 」,那麼這裡要填入的就會是「 https://john.azurewebsites.net/line/echo_bot.php 」。
最後請容我提醒一下,也許不是那麼明顯,不過 Echo 應聲蟲機器人已經成功上線了,不信的話,請拿起你自己的手機,掃描一下眼前這個開發者網站頁面上的 QR Code 即刻加為好友,試試看是不是你說什麼, Echo 應聲蟲就說什麼。
實務上, SDK 裡面總是喜歡用 Echo 當作範例,因為如果可以你丟它什麼、它就回應什麼,代表底層架構沒有問題,後續熟悉了 SDK 和 API 之後,只要把功能再往上疊加就可以了。
申請 Google 帳號並且使用 Google 文件建立知識庫
毋庸置疑的是,問答型聊天機器人的成敗,同時取決於問與答,因為機器人一方面必須對於「問題」有很好的理解,另一方面又要能夠提供很好的「答案」。而答案要好,就必須鎖定耕耘「領域」( Domain )的範疇,並且盡力精熟該領域。以美食指南為例,如果有使用者誤闖並詢問了汽車方面的問題,機器人固然一定回答不出來,但是對於附近有什麼好吃的餐廳、下午茶可以吃什麼之類的問題,就應該能夠毫不費力而且信心滿滿地回答。
所以第三步是免費使用 Google 文件的試算表充當簡易的資料庫,開始為機器人填充領域知識。假使沒有 Google 帳號的話,請先註冊一個,接著來到 Google 雲端硬碟,依序點選「新增」→選擇「 Google 試算表」。
想像你是一名美食部落客,或是美食指南粉絲團的小編。當有人問起的時候,你的答覆不外乎包含幾項必要資訊,照片、標題、內文。比方說「彰化爌肉飯吃哪間?」,關鍵字是「爌肉飯」,你會回覆一張竹籤串過三層肉配著蘿蔔乾鋪在白飯上的照片、標題是「某某爌肉飯,彰化人的首選」、內文就是你自己之前寫的部落格文章或是粉絲團貼文(為求圖文並茂、排版美觀,可以直接外連到部落格或粉絲團,並在 LINE 當中滿版瀏覽)。
除了照片、標題、內文這 3 個必要資訊之外,為了理解使用者的提問,需要再增加 1 個關鍵字欄位,以便達到關鍵字搜尋的效果。筆者本身就擁有一個美食粉絲團,輸入了幾筆資料之後,基於 Google 試算表的美食指南知識庫將會如下圖所示。必須留意的是, Facebook 放在 CDN 上的圖片一段時間之後就會逾期,所以要嘛不定期更新知識庫裡相關照片的網址,要嘛就將資料來源改成部落格而非粉絲團。
接著,點選 Google 試算表主選單的「檔案」→點選「發佈到網路」→點選「發佈」→點選「好」,可以獲得一串網址,其中從「 /d/ 」開始到「 /pubhtml 」結束之間的編碼,就是這份試算表的專屬編號,記下這組編號,並且替換到下列網址中,便可以把這份試算表變成一份雲端上的 JSON 文件,方便後續的機器人程式下載處理:
https://spreadsheets.google.com/feeds/list/試算表編號/od6/public/values?alt=json
舉例而言,筆者自己的 JSON 文件網址如下:
https://spreadsheets.google.com/feeds/list/1tQCaj3LUVwH0tBuPrfBY2dOJuF-qzpYEdOqGdNvJRLc/od6/public/values?alt=json
改造 Echo 成為問答機器人
最後一步,我們即將改造 Echo 應聲蟲,賦予它更多的功能,讓它變成美食指南機器人。不過在實務上,回想一下我們自己跟親朋好友的聊天視窗內容,通常不會講一句話就結束,有時候會鋪陳,或是閒話一些家常,而且每段句子都不會太長。因此機器人除了給予答案之外,也應該給予關懷,有時候開頭和結尾的閒聊,甚至會勝過中間答案的正確性。
舉例而言,當使用者問道「彰化爌肉飯吃哪間?」,而機器人只是回答「某某爌肉飯」,或者只是把所有候選的答案串成一列旋轉木馬,這樣的使用者體驗都稍嫌平淡了一些。更好也更有人味的作法,應該是先回應一句「爌肉飯是嗎?」,接著再回應第二句「為您推薦下列美食:」,然後出現一列候選答案組合而成的旋轉木馬,最後用「第一間是我個人的最愛」收尾,也許再搭配一張笑臉貼圖。第一句和最後一句都可以有好幾種版本,隨機輪流替換,甚至為了增加趣味性,可以考慮負能量版本,比方說「怎麼又吃爌肉飯!」、「那麼胖,別吃了!」,或是加強一下正常版,比方說「這些都超好吃,真心不騙!」。
在上一個小節中,我們已經把知識庫建立好了,現在該是改造 Echo 應聲蟲的時候了。可先行下載美食指南的範例專案。主要分成兩個部分,一個是關鍵字搜尋,找到候選的答案,並且串成陣列;另一個是回應的類型,由應聲蟲的純文字( Text )改成旋轉木馬( Carousel )。為了與 Echo 應聲蟲區別,我們可以將改造後的版本重新命名為 bot.php 。
無論是何種類型的回應,務必留意 LINE 開發者文件上的說明,所有必填( Required )的欄位只要沒填,回應就會出不來。比方說旋轉木馬的每則內容都有所謂的標題( Title )和文字( Text ),標題可以不填,但是文字如果沒填,回應絕對出不來,使用者會誤以為機器人已讀不回。
先看第一部分的關鍵字搜尋實作,我們會用知識庫中每筆資料自行定義的關鍵字(當關鍵字有好多個時,以逗號分隔),去比對使用者的提問,一旦匹配,就將該筆資料加入 $result 陣列當中,作為候選答案。每個答案會有一顆顯示為「查看詳情」的按鈕,點擊之後會開啟網頁連結至臉書粉絲團的原文。
$json = file_get_contents('https://spreadsheets.google.com/feeds/list/1tQCaj3LUVwH0tBuPrfBY2dOJuF-qzpYEdOqGdNvJRLc/od6/public/values?alt=json');
$data = json_decode($json, true);
$result = array();
foreach ($data['feed']['entry'] as $item) {
$keywords = explode(',', $item['gsx$keyword']['$t']);
foreach ($keywords as $keyword) {
if (mb_strpos($message['text'], $keyword) !== false) {
$candidate = array(
'thumbnailImageUrl' => $item['gsx$photourl']['$t'],
'title' => $item['gsx$title']['$t'],
'text' => $item['gsx$title']['$t'],
'actions' => array(
array(
'type' => 'uri',
'label' => '查看詳情',
'uri' => $item['gsx$url']['$t'],
),
),
);
array_push($result, $candidate);
}
}
}
接著看第二部分的旋轉木馬回應實作, messages 訊息會有 3 個段落,先一句話開頭,再來是提供候選答案的旋轉木馬,最後再用一句話收尾。
$client->replyMessage(array(
'replyToken' => $event['replyToken'],
'messages' => array(
array(
'type' => 'text',
'text' => $message['text'].'讓我想想喔…',
),
array(
'type' => 'template',
'altText' => '為您推薦下列美食:',
'template' => array(
'type' => 'carousel',
'columns' => $result,
),
),
array(
'type' => 'text',
'text' => '這些都超好吃,真心不騙!',
),
),
));
如果想要將 messages 陣列的回應文字改成貼圖,可以把 type 從 text 改成 sticker 試試看,而套件 ID 和貼圖 ID 則可以參考開發者文件上提到的貼圖清冊,示範如下:
array(
'type' => 'sticker',
'packageId' => '1',
'stickerId' => '2',
),
好了,到這邊為止,我們的美食指南機器人便大功告成了。喔,最後別忘了最重要的一件事,就是趕緊散佈機器人的 LINE@ ID (本文範例的 ID 是 @ujn2132k ,功能會不定期升級喔)或 QR Code (詳見下圖),如果已經加過好友了,也可以直接在聊天視窗中點擊機器人的大頭照,然後點選「推薦」,逕自邀請通訊錄裡面的親朋好友將機器人加為好友。
結語
本文實作的問答型( Question and Answer ,簡稱 Q&A 或 QA )聊天機器人有兩個顯著的缺點,其一是無法留存記錄以便進行後續的大數據分析(比方說得知最多人感興趣的餐廳、每天最常被詢問的問題等),這點可以透過引入資料庫來補強;其二是對於問題語句的理解有時不太盡如人意,這點可以透過引入自然語言理解技術(比方說 Microsoft 的 LUIS 、 Google 的 API.AI 、 Facebook 的 Wit.ai 等)來補強。
至於如何提高留存率,也就是聊天機器人被加為好友之後,不會被刪除或冷落,根本上仰賴的還是知識庫的多元性,一旦答案很貧乏,那麼流程再友善、介面再有趣,都很難讓人有想要再試一次的動機。
最後,關於本文實作的美食指南機器人的程式碼,可至筆者的 GitHub 下載。如你喜歡此文章,請你按左邊的按鈕給一個讚或分享給同樣有興趣學習 Chatbot 開發的朋友,謝謝!