Chatbot實作
結合DialogFlow, Line, Firebase
last updated: 2022/06/20
前言
Chatbot聊天機器人分類
General Purpose
終極目標: 無所不知
Task-Oriented
負責特定工作
中文版 Eliza (心理醫師)
(Artificial Linguistic Internet Computer Entity)
訂位、打包清單
點餐、訂單追蹤
Chatbot聊天機器人技術
Rule-based
樣式比對(pattern matching)
Corpus-based
採用大量詞庫進行訓練
詞庫來源: crowdsourcing, wikipedia
問答集
詞庫也是問答集的形式、大數據的概念
Chatbot聊天機器人架構
語音辨識
自然語言理解
狀態追蹤
自然語言產生
文字轉語音
對話策略
Line bot製作
以Dialogflow為「自然語言理解」引擎
Part 3. Line App
Part 2. Webhook
Part 1. Agent
Webhook: 為一網址(REST API,必須架設公開網站)
Line bot 以DialogFlow為引擎
Part1: 登入DialogFlow 建立 Agent(代理人)
Part 3: 在Line Developers Console設定
Part2: 建立Line與代理人的中介橋樑(webhook)
Dialogflow
Dialogflow Essentials (ES)
- 試用版、基本版
- 試用版免費:小於 每分鐘180次text requests
超過則 ➪ 每個request $0.002美元
(請參考配額與限制)
Dialogflow Customer Experience (CX)
- 進階版
- 視覺化介面(如對話流程設定)
步驟1:新建代理人(agent)
步驟2:設定預設意圖(Intent)
步驟3:自訂意圖
- 訓練片語(Training Phrases)
- 動作與參數(Actions and Parameters)
- Contexts
- Follow-up Intents
- 回應訊息(Response)
- Media Rich Response
步驟4:Line Integrations (跳至Part 3)
步驟5:Fulfillments(跳至Part 2)
以Dialogflow建立全新的代理人
步驟1: 新建代理人 Create Agent (1/2)
Create Agent
步驟1: 新建代理人 Create Agent (2/2)
輸入代理人名稱
設定預設語言別
綁定Google專案
步驟2: 預設意圖 (Default Intent) (1/4)
測試主控台
預設Intents
已產生兩個Intents: Fallback, Welcome
輸入測試語句
何時觸發Welcome? 偵測到「開始對話」的語句
何時觸發Fallback? 偵測到agent不了解的語句
Intent指的是某句子中的意圖(intention)
我要預約
明天天氣預報
你們店怎麼去?
使用者字句
可能的意圖
預約
查詢天氣
查詢地址
步驟2: 預設意圖 (Default Welcome Intent) (2/4)
客製化Welcome意圖:需符合系統目標、Bot的人設
❸存檔
❶ 刪除預設回應訊息
❷ 新增回應訊息如上
歡迎光臨!你想知道本店營業時間,還是想要預約來店?
設定回應訊息
步驟2: 預設意圖 (Default Welcome Intent) (3/4)
❶ 多加幾種不同的歡迎詞
❷ 存檔後測試
你好!我可以告訴你本店營業時間,也可以幫你預約,你需要什麼服務呢?
嗨!有什麼需要幫忙的嗎?我可以告訴你本店營業時間,也能幫你預約來店。
更多回應訊息
步驟2: 預設意圖 (Default Fallback Intent) (4/4)
當不了解使用者字句時,便觸發Fallback意圖
❸存檔
❶ 刪除預設回應訊息
❷ 新增回應訊息如上
抱歉,請問你是要詢問營業時間?還是要預約來店呢?
不好意思,請問你是想知道營業時間?還是要預約呢?
設定回應訊息
步驟3-1: 自訂意圖 (Create Intent) (1/4)
測試主控台
建立新的意圖
預設Intents
輸入測試語句
步驟3-1: 自訂意圖 (Create Intent) (2/4)
❶ 建立新的意圖
3-1. 建立「營業時間」、「預約」 ➔ 2個自訂意圖
我的Line bot應該要有哪些「自訂意圖」?
設計Chatbot就是在設計軟體系統
軟體工程的方法論都可派上用場
使用案例描述、使用者故事對照、資訊架構...
心智圖
試算表
軟體工具
以使用者故事對照為例
使用者故事對照範例:運動彩券
另一方面...Chatbot的操作跟一般軟體很不一樣
點餐
訂位
必須透過「對話」導引系統的執行
Colace, F.; et. al, (2017). BotWheels: a Petri Net based Chatbot for Recommending Tires. In Proceedings of the 6th International Conference on Data Science, Technology and Applications - pages 350-358.
透過對話改變狀態,以達最終目的
重新思考你規劃的架構
刻畫系統的整體圖像,並試著思考「例外」、「替代選項」
區分出任務後,寫出任務的步驟細節
醫療機器人
筆電推薦
步驟3-1: 自訂意圖 (Create Intent) (3/4)
❶ 輸入意圖名稱
以「營業時間」為例: 輸入訓練片語(Training phrases)
❷ 存檔
❸ 新增訓練用片語
步驟3-1: 自訂意圖 (Create Intent) (4/4)
❶ 輸入多個回應訊息
建立回應訊息
❷ 存檔
這是最單純的情況
建立更多的意圖
「預約」意圖必須能夠處理更複雜的句子:動作與參數
❶ 辨識出3 PM, today為重要資訊
❷ 回應訊息附上剛提及的日期、時間資訊
Dialogflow要能辨識重要資訊、並將之儲存
參數(parameters), 每個辨識出來的參數都有自己的實體型別(entity type)
步驟3-2: 自訂意圖的動作與參數 (action and parameter) (1/4)
建立相同類型的Entities
這些地名都是@mylocation
在training phrases使用Entities
只要一個句子,可包含所有同類型entity
新增「預約」意圖
❶ 輸入我要預約今天下午三點
❷ 系統自動偵測出兩個參數
或
手動標示兩個參數並選擇正確的entity type
❸存檔
步驟3-2: 自訂意圖的動作與參數 (action and parameter) (2/4)
新增「預約」意圖(續)
❶ 回應訊息輸入上列文字
❷存檔
收到!為你預約 $date 時間是 $time 來店賞車,期待你的光臨。
步驟3-2: 自訂意圖的動作與參數 (action and parameter) (3/4)
加入更多的訓練用片語
❶ 加入更多訓練用片語
❷存檔
我想看看最新款的單車
包含一些不含日期時間的句子
我的車壞了
步驟3-2: 自訂意圖的動作與參數 (action and parameter) (4/4)
有些「參數」為必要資訊,but...使用者沒有提供?
❶ 勾選為「必要」REQUIRED參數
我想看看最新款的單車
❷ 打開Define prompts,輸入後續提示字句
我的車壞了
例如:使用者輸入的句子經常不包含日期、時間,要如何預約?
❸存檔
步驟3-3 : 追問缺少必要參數 (slot filling) (1/3)
Answer: 追問出相關訊息
填入「參數」缺少時的提示訊息 (slot filling)
❶ 加入後續提示字句
以缺少[日期]為例,輸入後續Bot應該回應的問句
❷存檔
步驟3-3 : 追問缺少必要參數 (slot filling) (2/3)
填入「參數」缺少時的提示訊息 (slot filling)
❶ 加入後續提示字句
缺少「時間」時,後續Bot應該回應的問句
❷存檔
步驟3-3 : 追問缺少必要參數 (slot filling) (3/3)
對話脈絡(context): 段落資訊用來決定語意模糊問題
步驟3-4 : Context與Follow-Up意圖
例:這個景點好玩嗎?那家餐廳貴不貴?
Context
Follow-Up意圖經常用於決策
Part 3 在Line Developers Console設定
1. 前往LINE Developers Console建立Channel
(使用Messaging API)
2. 從Dialogflow ES控制台取得Line webhook URL
3. 完成Line webhook設定(Line 平台端)
4. 完成Dialogflow integrations端的設定
與其他平台整合以Line為例
步驟1: 建立Line Channel使用Line Messaging API
1. 前往LINE Developers Console建立Channel
你的系統(如Dialogflow)
Channel是LINE平台與你的系統之間的「溝通路徑」
(HTTP協定、採用「訂閱」機制)
建立Line Channel使用Line Messaging API
1-1. 登入LINE Developers Console
建立Line Channel使用Line Messaging API
1-2. 以開發者身份註冊(僅需設定一次)
輸入姓名、Email
建立Line Channel使用Line Messaging API
1-3. 建立新的Provider
輸入Provider名稱
建立Line Channel使用Line Messaging API
1-4. 建立Messaging API channel (2/3)
建立Line Channel使用Line Messaging API
1-4. 建立Messaging API channel (3/3)
建立Line Channel使用Line Messaging API
1-5. 確認Channel已成功建立
步驟2: 取得LINE webhook URL從Dialogflow控制台
步驟2: 取得LINE webhook URL從Dialogflow控制台
複製Webhook URL, 準備到LINE Developers Console進行設定
步驟3: 在LINE Developers Console設定Webhook URL
Webhook URL: 你的系統網址
你的系統(如Dialogflow)
所以,Webhook是什麼?
步驟3: 在LINE Developers Console設定Webhook URL
❶ 選擇3-1建立的Provider
❶ 選擇3-1建立的Provider
❷ 點選此分頁
3-1 前往LINE Developers Console 啟用Webhook
步驟3-3: 在LINE Developers Console設定Webhook URL
3-2 前往LINE Developers Console 啟用Webhook
❶ 貼上Webhook URL
❷ 打開啟用開關
步驟3: 在LINE Developers Console設定Webhook URL
3-3 關閉「自動回覆訊息」(重要!)
❶ 點選Edit, 關閉自動回覆訊息
步驟4: 將Channel ID, Channel secret, Channel access token貼至Dialogflow
回Dialogflow agent
步驟4: 將Channel ID, Channel secret, Channel access token貼至Dialogflow
❶ 準備從Line Provider處複製Channel ID, Channel secret, Channel access token貼至此處
❷ 啟動agent,作為Line平台的bot server
步驟4: 將Channel ID, Channel secret, Channel access token貼至Dialogflow
❶ Channel ID在Basic information段落的最前面
步驟4: 將Channel ID, Channel secret, Channel access token貼至Dialogflow
❸ Channel access token在Basic information段落的最後面
步驟5: 掃描QR-Code, 加入好友
打開手機,掃描QR-Code,加入好友
Part 1 Again
Media Rich Response
Dialogflow回應方式(media rich response)
Dialogflow意圖回應模式三種: 文字、語音、豐富媒體
Dialogflow回應方式(media rich response)
Dialogflow意圖回應模式三種: 文字、語音、豐富媒體
回應將送至Line integration
開啟: default回應優先
Dialogflow回應方式(media rich response)
Line專屬回應,使用豐富媒體: Image
輸入圖片網址
延伸議題:圖片管理
Dialogflow回應方式(media rich response)
Line專屬回應,使用豐富媒體: Card
圖片網址
必填
大標題
小標題
按鈕文字
Dialogflow回應方式(media rich response)
Line專屬回應,使用豐富媒體: Quick Replies
標題
說明文字, 最多20字
Dialogflow回應方式(media rich response)
Line專屬回應,使用豐富媒體: Quick Replies
packageId, stickerId參考 List of available stickers
{
"line": {
"type": "sticker",
"packageId": "446",
"stickerId": "1988"
}
}
可換
可換
Part 2. 建立Webhook
Firebase cloud function
Heroku
...
部署支援https協定的公開網站
選項1: 使用Inline Editor撰寫程式
❶ 開啟inline editor選項
fulfillments
❷ 在此處寫程式
❸ 部署
node.js/ Express框架
使用Google Cloud Function
選項2: 開啟Webhook選項
❶ 開啟Webhook選項
fulfillments
❷ 自行撰寫Web程式
❸ 貼上Webhook程式網址
ⓐ 支援https協定
ⓑ 擁有網域的網站空間
關於網站、http、ip與網域(1/3)
網站
網站要求
公開存取: 網站空間,必須配有IP,通常有網域名與主機名
HTTP
瀏覽器 與 Web伺服器 的溝通方式
租用/申請
網站
自行命名
租用
關於網站、http、ip、網域(2/3)
名稱伺服器(DNS伺服器)
❶ 主機名+網域名
負責轉換
❷ 轉為IP
❸根據IP建立連線
關於網站、http、ip、網域(1/3)
HTTP: 明碼傳送(不安全)
HTTPS: 加密連線(安全)
SSL憑證
網站空間 / 主機
IP
網域
SSL憑證
自行架站成本
建立第一個Cloud Function
步驟1: 建立Firebase專案
前往Firebase控制台 https://console.firebase.google.com/
新增專案
輸入專案名稱
或
選一個現存專案
步驟1: 建立Firebase專案(1/6)
Firebase專案也是Google Cloud專案
取消勾選
步驟1: 建立Firebase專案(2/6)
步驟1: 建立Firebase專案(3/6)
點選啟用Functions功能
步驟1: 建立Firebase專案(4/6)
必須是收費方案才能使用
步驟1: 建立Firebase專案(5/6)
Blaze收費方案: 測試用專案幾乎不可能收費
步驟1: 建立Firebase專案(6/6)
視專案需要,啟用資料庫、儲存內容、帳號認證等功能
建立第一個Cloud Function
步驟2. 安裝Node.js
LTS 或 Current版本皆可
Mac使用者,請安裝NVM (Node Version Manager)
建立第一個Cloud Function
步驟2-1. 安裝Firebase CLI工具
開啟命令提示字元,輸入下列指令
npm install -g firebase-tools
建立第一個Cloud Function
步驟3. 建立專案
在命令提示字元視窗,輸入下列指令
firebase login
❶ 登入firebase控制台
建立Cloud Function專案(1/5)
mkdir chatbot
cd chatbot
❷ 建立專案資料夾,如chatbot;隨後切換至該資料夾
建立Cloud Function專案(2/5)
❸ 執行firebase init建立專案
firebase init
ⓐ 專案功能選取:Firestore 與 Functions
建立Cloud Function專案(3/5)
ⓑ 選擇綁定的Google Cloud/ Firebase專案:Use an existing project
ⓒ 找到剛才建立的Firebase專案
建立Cloud Function專案(4/5)
ⓓ 使用預設選項
ⓔ 選擇程式語言
Inline Editor: JavaScript
建立Cloud Function專案(5/5)
ⓕ 不使用ESLint
ⓖ 選擇安裝套件
Inline Editor: JavaScript
此處選擇TypeScript
專案完成!
建立第一個Cloud Function
Cloud Function的主程式:functions/src/index.ts
index.js
建立第一個Cloud Function
// See https://github.com/dialogflow/dialogflow-fulfillment-nodejs
// for Dialogflow fulfillment library docs, samples, and to report issues
'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
function welcome(agent) {
agent.add(`Welcome to my agent!`);
}
function fallback(agent) {
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
}
// // Uncomment and edit to make your own intent handler
// // uncomment `intentMap.set('your intent name here', yourFunctionHandler);`
// // below to get this function to be run when a Dialogflow intent is matched
// function yourFunctionHandler(agent) {
// agent.add(`This message is from Dialogflow's Cloud Functions for Firebase editor!`);
// agent.add(new Card({
// title: `Title: this is a card title`,
// imageUrl: 'https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png',
// text: `This is the body text of a card. You can even use line\n breaks and emoji! 💁`,
// buttonText: 'This is a button',
// buttonUrl: 'https://assistant.google.com/'
// })
// );
// agent.add(new Suggestion(`Quick Reply`));
// agent.add(new Suggestion(`Suggestion`));
// agent.setContext({ name: 'weather', lifespan: 2, parameters: { city: 'Rome' }});
// }
// // Uncomment and edit to make your own Google Assistant intent handler
// // uncomment `intentMap.set('your intent name here', googleAssistantHandler);`
// // below to get this function to be run when a Dialogflow intent is matched
// function googleAssistantHandler(agent) {
// let conv = agent.conv(); // Get Actions on Google library conv instance
// conv.ask('Hello from the Actions on Google client library!') // Use Actions on Google library
// agent.add(conv); // Add Actions on Google library responses to your agent's response
// }
// // See https://github.com/dialogflow/fulfillment-actions-library-nodejs
// // for a complete Dialogflow fulfillment library Actions on Google client library v2 integration sample
// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
// intentMap.set('your intent name here', yourFunctionHandler);
// intentMap.set('your intent name here', googleAssistantHandler);
agent.handleRequest(intentMap);
});
摘自Inline Editor, 因函式庫已多年未維護,不宜佈署至專案
Chatbot實作
By Leuo-Hong Wang
Chatbot實作
Chatbot with DialogFlow (part 2)
- 415