Chatbot實作

結合DialogFlow, Line, Firebase

last updated: 2022/06/20

前言

Chatbot聊天機器人分類

General Purpose

終極目標: 無所不知

Task-Oriented

負責特定工作

中文版 Eliza (心理醫師)

Alice Bot

(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)

 

Part 1. 建立Agent代理人

前往 Dialogflow平台

https://dialogflow.cloud.google.com/

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

建立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協定

擁有網域的網站空間

使用符合❷-ⓐ, ❷-ⓑ的雲端服務: Heroku 、 Firebase

關於網站、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