聊天機器人教學:使用Dialogflow (API.AI)開發 iOS Chatbot App

聊天機器人教學:使用Dialogflow (API.AI)開發 iOS Chatbot App
聊天機器人教學:使用Dialogflow (API.AI)開發 iOS Chatbot App
In:

隨著蘋果Core ML的最新版本發佈,開發人員更容易構建人工智能應用程式,除了圖像識別和文本檢測是利用AI建置APP的好例子,另一種善於展現機器學習Power的應用程式類型則是chatbots。在本教程中,我們將使用Google的Dialogflow(以前稱為API.AI)構建在iOS上運行的chatbot應用程式!

聽起來很酷吧!接下來開始進入本教程的重點。

Intents(意圖)和Entities(關鍵字)快速概覽

在開始之前,我先解釋Dialogflow和chatbots的一般基本知識。 在構建chatbots時,你必須知道兩個術語:Intents(意圖)Entities(關鍵字)

An entity represents a term or object in the user’s input that provides clarification or specific context for a particular intent.
(entity表示用戶輸入中的術語或對象,為intent提供說明或使用情境。)

An intent, on the other hand, represents something that the user wants to do. If intents represent verbs, then entities represent nouns.
(另一方面,intent代表用戶想要做的事情,如果intent代表動詞,則entities代表名詞。)

來看一個例子,在我們的專案中,可能會告訴我們的機器人以下聲明:

“Book me a room at the La Grande Hotel”(替我在La Grande Hotel訂一間房)

在這句話中,我們的intent(意圖)是”預定一個房間”,entity(關鍵字)是”La Grande Hotel”,現在,自然語言處理(NLP)算法可以計算兩種不同類型的對話內容。

  1. 基於意圖(Intent-based)的對話:這是當NLP算法使用intents和entities進行對話時,通過識別用戶聲明中的名詞和動詞,然後與它的dictionary交叉引用,讓bot可以執行有效的操作,這種類型的對話是Dialogflow使用的。

  2. 基於流程(Flow-based)的對話:基於流程的對話是智能通信的下一個級別。在這裡,我們會給予兩個人之間對話的許多不同樣本的RNN(循環神經網絡),創建的機器人將根據你訓練的ML模型進行響應。Wit.ai是在這個領域取得巨大進展的少數網站之一,不用擔心,我們不需要做到這個程度。

注意:如果想了解更多有關Intent-based和Flow-based的對話信息,可以查看這篇文章

在本教程中,我們將創建一個可幫助你預訂hotel的機器人。

One of the most important rules when developing a chatbot is that it MUST have a personna. This means that it must behave like a real person. Therefore, let’s name out bot – Chip!
(開發chatbot最重要的規則之一,就是它必須有一個personna,意味著它必須像真人一樣行事。 因此,讓我們來替bot命名 – Chip!)

接下來,就進入本文重點!

熟悉Dialogflow

進入到Dialogflow,在右上角點擊”Go to Console(前往控制台)”。

Dialogflow

系統會要求你使用Google帳戶登錄,並授權使用Dialogflow在Google雲端平台服務中查看和管理你的資訊,接受條款,你應該看到一個初始啟動頁面。

Dialogflow-console

觀看介紹影片可以讓你更快速了解Dialogflow,但如果你不想花時間看也沒關係!點擊”Create Agent”按鈕,在Dialogflow中,一個agent(代理)意味著iOS應用將使用chatbot通過無線方式進行通訊以接收回應。

填寫代理名稱(比如Chip),然後點擊Create按鈕進行下一步,Dialogflow將為你創建agent。現在,讓我們來確認一下,你應該有2個預設intents:”Default Welcome Intent”和”Default Fallback Intent”。在左側欄位中,你應該可以看到Intents和Entities的tabs(選項)。

Create Agent in Dialogflow

我們也會在下方看到其他tabs。現在,該開始創建機器人了!

添加Entities

首先,讓我們開始添加entities,如果你還記得,entities就像NLP算法可以理解的名詞,拿出一個可能經常用於我們機器人的entities名單,我已經把我整理的list放在下面,並且隨時可以添加它。

  • Hotel
  • Room
  • Payment

選擇entities選項,然後點擊”Create Entity”按鈕。並將這個entity命名為”Hotel”,並點擊第一行,輸入”Hotel”當做參考值,當用戶使用你的機器人時,他們可能會使用Hotel以外的其他名稱。 因此,應該輸入關鍵字的一些同義詞,即使用戶使用”Hotel”以外的字,機器人仍然可以理解用戶在說什麼,看下面的圖片,我使用了一些同義詞。

Dialogflow-add-entity

現在,儲存你的entity,並按照剛才建置Hotel entity的步驟創建以下的entities。

Dialogflow-entity-payment

Dialogflow-entity-room

小建議:要查找單詞的同義詞,只需Google搜尋”synonyms of [word]”。

現在我們已經創建了entities,接著來討論intents。

添加Intents

進入Intents頁面並點擊Default Welcome Intent,這個intent就是我們機器人在第一次啟動時會抓取的東西,你應該看到網頁呈現如下:

Dialogflow-intent

我們可以制定用戶應該說出哪個字去觸發intent。在本頁面的最底部,我們也可以制定回應的文本內容,由於這是一個Welcome intent,用戶可能會說”Hello!”或”How’s it going?” 因此,讓我們將這些短語(和任何類似的同義詞)添加到’User says’部分,以下是一些範例,你可以隨意地添加更多的訊息,設定你的用戶可能會對機器人說的字彙。

Dialogflow-welcome-intent

如果向下滾動,會找到* Response *部分。intent帶有一些內置的回應,我們添加一個follow up question(關聯性問題):”What can I do for you?”,我們最終Welcome intent應該是這樣的:

Dialogflow-welcome-intent-response

在我們開始創建下一個intent之前,如果你想在任何時候測試你的agent,請查看右側欄位,你可以輸入想要的任何內容,然後查看你的agent是否回應。輸入”Hello”,然後檢查agent是否回應了預期的回應。

到目前為止,agent只有一個intent,由於我們的機器人是為處理預訂hotel而設計的,因此我們必須創建另一個處理intent這些查詢,用戶可能會問:“能替我預訂一家旅館嗎?” 或類似的問句。

讓我們創建一個新的intent,並將其命名Begin Order。在User says欄位中,添加上面的表達式然後按下enter。一旦你輸入了這個表達式,將會看到agent已經在該語句中識別了一個@Hotel關鍵字。與entities類似,用戶不會只用這個問句來表達預訂酒店的需求。所以這裡添加一些變化,以agent理可以了解用戶的意思,增加的變化越多,agent也就越聰明,以下是一個範例展示。

Dialogflow Begin Order Intent

agent應該做的下一件事是搜索附近的hotel,並詢問用戶他/她需要幾間房。但是,如果我們要真正搜尋附近的酒店,則需要調用API並使用JavaScript將webhook與api.ai整合在一起,這超出了本教程的範圍,所以讓我們在Response欄位創建一些虛擬酒店,這是我創建的回應內容:

Dialogflow-begin-order-response

儲存intent並返回到主頁面,在右側欄位中測試你的agent,到目前為止,如果讀者有跟著前面的步驟,它應該按預期工作!正如你所看到的,不必提出確切的問題,Dialogflow將從你的陳述中學習並理解變化。

test-agent

現在,我們來添加一些follow-up intent,將鼠標移動在你剛創建的intent上,你應該看到一個選項”Add follow-up intent”,選擇它並點擊Custom,將產生一個新的intent,並顯示”Begin Order – custom”,讓我們編輯這個intent!

Dialogflow-add-follow-intent

請記住,我們agent對我們說的最後一件事情是”How many rooms do we want?”,用戶可能會回覆一個數字,他/她可能會說:”I would like 1 room”或簡單地回答”4″,你應該要預測用戶會說什麼,並填寫所有可能的答案,請參考以下我填寫的範例:

begin-order-followup-intent

正如你所看到的,Dialogflow有一個內置的數字entity,不管你輸入一個數字還是一個單詞,它都能夠處理它並理解它的含義。

接下來,我們要讓機器人回應確認價格總額,並詢問用戶喜歡什麼付款方式。同樣的,由於這些是hotel虛擬資料,我們可以在機器人的反應中添加虛擬的價格。

begin-order-followup-response

保存這個intent,現在給讀者一個挑戰,創建最後一個intent,即詢問用戶使用何種付款方式付款,這應該是非常簡單的,因為我們已經做了兩次!

希望讀者都能順利完成,如果沒有也沒關係,請按照下面的方式!所以我們將回到intent的主頁面,然後點擊Create Intent。

注意:我沒有創建另一個follow-up intent,因為當機器人第一次觸發時,用戶不太可能會說出付款方式的名稱,這就是為什麼我要創造一個normal intent,就像我們在剛開始時所做的。

將這個intent命名為Payment並添加用戶可能會說的內容,這是我們的Payment關鍵字(entity)使用的地方!

Dialogflow-payment-intent

最後,讓機器人回應一些確認訊息。以下是一些範例:

  • Done! You have rent the rooms!
  • Success! We received your payment.

就是這樣!請記住保存Payment意圖,Chip現在可以使用了,在我們轉到本教程的iOS端之前,你可以在右側欄位中對其進行測試。

A Couple More Things

在開始真正的編程之前,讓我花點時間來解釋Dialogflow控制台左側欄位中的其他tabs,在Entities下,有一個名為Training的tab,如果點擊此選項,你將收到所有發送給agent的回覆訊息以及agent回覆的內容,如果你告訴你的agent一些回應文本,但它回應你不喜歡的輸出,這就非常有用,若你稍後意識到忘記了某個關鍵字的同義詞,並且用戶正在使用這個關鍵字,那麼也可能會有所幫助,可以去告訴你的代理在這種情況下應該做什麼。

在Training下方,你可以看到Integrations。在這裡,可以管理你的agent去串接不同的服務,例如Google Assistant,Twitter,Slack,Messenger,Cortana,Alexa等等。Integrations之後,還有Analytics,基本上用來顯示建議名稱,之後還有Fulfillment,如果你要調用一個API並實現一個webhook,這就是你會需要來的地方。

Dialogflow-integration

最後兩個選項功能非常簡單,但很有用。第一個是Prebuilt Agents,在這裡,你可以import一個預先存在的代理框架,有很多例子,如食物傳遞機器人,音樂機器人,甚至(抱歉,但你真的需要知道這個)hotel預訂機器人! 最後一個選項是Small Talk,如果你將代理設計為像Siri或Google Assistant這樣的每日夥伴(daily companion),這個選項非常有用,Small Talk允許你添加常見問題的答案,我們都喜歡問我們的機器人,如”你幾歲?”或”你住哪裡?”,以及更熱門的問題”你願意嫁給我嗎?”

現在你已經知道Dialogflow是什麼,並且對於如何操作有很好的觀念了,現在是時候移動到另一端,開始編寫Swift程式碼!

使用API.AI SDK連接到Dialogflow

現在我們移動到本教程Swift的部分,首先[下載初始專案](https://github.com/appcoda/ChatbotHotel/raw/master/ChatbotStarter.zip),我已經構建了基本的UI並綁定了API.AI SDK。如果你從頭構建應用程序,則可以使用CocoaPods安裝API.AI SDK(這是用於連接到Dialogflow的SDK),只需在Podfile中添加以下訊息:

pod 'ApiAI'

一旦你unzip初始專案,確保你打開了Chatbot Starter Project.xcworkspace文件。進入Main.storyboard,已經有一個UILabelUIButtonUITextField,它們的outlets也連接到ViewController.swift

demo-app-main-storyboard

先來看看AppDelegate.swift,我們需要讓APP連接到Dialogflow的servers,在import UIKit的正下方,輸入以下程式碼來導入framework:

import ApiAI

現在,需要使用client access token來初始化我們的配置,請參照下面範例更新didFinishLaunchingWithOptions方法:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    
    let configuration = AIDefaultConfiguration()
    configuration.clientAccessToken = "YOUR_CLIENT_ACCESS_TOKEN"
    
    let apiai = ApiAI.shared()
    apiai?.configuration = configuration
    
    return true
}

將字符串”YOUR_CLIENT_ACCESS_TOKEN”替換你自己的機器人的client access token,如果你不知道在哪裡可以找到,請移動到Dialogflow中的chatbot settings。 在”General”選項下,你應該在”API keys欄位下找到client access token。

Dialogflow-api-key

現在,當我們的應用程式啟動時,它將使用client access token連接到Chip bot。

讓裝置開始說話

前往ViewController.swift,並且在import UIKit之下,import ApiAI和AVFoundation框架:

import ApiAI
import AVFoundation

我們需要導入AVFoundation框架,因為我們需要bot與用戶交談,該框架附帶了能夠從文本轉為合成語音的“AVSpeechSynthesizer”類別,為了讓裝置與我們的用戶交談,在ViewController類中插入以下幾行代碼:

let speechSynthesizer = AVSpeechSynthesizer()

func speechAndText(text: String) {
    let speechUtterance = AVSpeechUtterance(string: text)
    speechSynthesizer.speak(speechUtterance)
    UIView.animate(withDuration: 1.0, delay: 0.0, options: .curveEaseInOut, animations: {
        self.chipResponse.text = text
    }, completion: nil)
}

讓我告訴你上面的程式碼做了哪些事。首先,我們定義一個常數speechSynthesizer,並初始化一個 AVSpeechSynthesizer的實例。AVSpeechSynthesizer是一個提供自文本轉換為語音的object,並允許存取控制正在進行的訪問,然後創建一個新的函式speechAndText(text: String),根據用戶輸入的內容執行更改。

在函式內部,我們創建一個AVSpeechUtterance的實例,最簡單的說,它是一個將被宣讀的文本塊。然後,我們要求裝置讀出這段文字,同時,我們想向用戶展示機器人的response,這就是為什麼我們將label的text設置為機器人的response。

我使用UIView.animate方法為label轉換為微妙的動畫,當你正在開發自己的應用程式,但不具備創建高品質的動畫知識,則這種方法可以實現這一效果。

發送請求

我們只剩下最後一部分,當用戶點擊按鈕時,應發送request給我們的代理,讓我們看看我們該怎麼做!在sendMessage操作方法中插入以下幾行程式碼:

let request = ApiAI.shared().textRequest()

if let text = self.messageField.text, text != "" {
    request?.query = text
} else {
    return
}

這段code是相當基本的,但是可能部分讀者不太理解這段代碼,還是讓我解釋一下。基本上,我們以用戶提供的query條件來準備API.AI文本請求,從messageField中檢索文本並執行基本驗證,確保文本字段不是空白,一旦我們得到了這段text,就將它丟給request的query屬性。

好的,文本request已經準備好了,下一步是發起請求並發送給機器人。當然,我們需要處理API.AI代理回應的任何內容,有兩種可能性:successfailure,如果代理程序返回成功訊息,那麼我們希望應用程式說出回應並將其顯示在螢幕上,如果出現失敗訊息,那麼應用程式只是打印錯誤到控制台,我們可以通過使用下面的程式碼來實現:

request?.setMappedCompletionBlockSuccess({ (request, response) in
    let response = response as! AIResponse
    if let textResponse = response.result.fulfillment.speech {
        self.speechAndText(text: textResponse)
    }
}, failure: { (request, error) in
    print(error!)
})

request執行完成後,應用程式需要做什麼,你可以調用setMappedCompletionBlockSuccess方法並在閉包中指定動作,一旦請求完成,完成處理程序將被調用,並將回應作為參數傳遞,在閉包中,我們調用前面創建的speechAndText(text: )方法來說出並顯示回應內容,如果response顯示失敗,我們只需將其打印到logs即可。

剩下最後一件事,我們還沒有發起對API.AI的request,為此,我們調用enqueue函式並放入指定request,這可以通過使用下面的程式碼來完成:

ApiAI.shared().enqueue(request)
messageField.text = ""

我們將請求發送到API.AI並清除textfield中的文字,你的整個sendMessage方法應該如下所示

@IBAction func sendMessage(_ sender: Any) {
    let request = ApiAI.shared().textRequest()
    
    if let text = self.messageField.text, text != "" {
        request?.query = text
    } else {
        return
    }
    
    request?.setMappedCompletionBlockSuccess({ (request, response) in
        let response = response as! AIResponse
        if let textResponse = response.result.fulfillment.speech {
            self.speechAndText(text: textResponse)
        }
    }, failure: { (request, error) in
        print(error!)
    })
    
    ApiAI.shared().enqueue(request)
    messageField.text = ""
}

是時候了!現在運行應用程式(在iPhone X上),一切都應該按預期工作!

chatbot-demo-hotel-booking

What’s Next

本教程包含很多的資訊,希望對讀者會是非常有益的,那麼,接下來你應該做什麼?我會建議你繼續擴展這個機器人,甚至創建你自己的機器人,期待你分享如何創建自己的機器人,歡迎發表在下面的評論!

以供參考,你可以在Github下載完成的專案

關於Dialogflow的更多資訊,你你可以參考他們的documentation

勇敢大膽的嘗試吧!你可以在Dialogflow上創建自己的聊天機器人,並把它放在Google Assistant上。如果你想嘗試一下,請查看這個影片,可以打開Google Assistant並透過”Talk to Max the Programmer”來測試我用Dialogflow製作的聊天機器人!鼓勵大家繼續研究Dialogflow,因為你可以在Google Assistant,Alexa,Twitter,Cortana,Facebook Messenger,Telegram等平台部署聊天機器人!

譯者簡介:陳奕先-過去為平面財經記者,專跑產業新聞,2015年起跨進軟體開發世界,希望在不同領域中培養新的視野,於新創學校ALPHA Camp畢業後,積極投入iOS程式開發,目前任職於國內電商公司。聯絡方式:電郵[email protected]

FB : https://www.facebook.com/yishen.chen.54
Twitter : https://twitter.com/YeEeEsS

原文Building a Chatbot App for iOS with Dialogflow (API.AI) and Text-to-Speech

作者
Sai Kambampati
Sai Kambampati 是程式開發員,生活於美國加州薩克拉門托,於2017獲得Apple's WWDC獎學金。精於 Swift及Python語言,渴望自家開發人工智能產品。閒時喜歡觀看Netflix、做健身或是遛漣圖書館中。請到推特追蹤 @Sai_K1065 。
評論
很好! 你已成功註冊。
歡迎回來! 你已成功登入。
你已成功訂閱 AppCoda 中文版 電子報。
你的連結已失效。
成功! 請檢查你的電子郵件以獲取用於登入的連結。
好! 你的付費資料已更新。
你的付費方式並未更新。