今回はAmazon LexというAWSが提供するフルマネージド型人工知能 (AI) サービスと組み合わせたチャットボットアプリを開発します。記事は全部で3回に分けており、2回目になるこの記事では、Lambdaの設定と前回設定したAmazon Lexとの統合までを紹介します。
1回目の記事では、Amazon Lexの設定を行います。
記事は下記リンクから確認ください。
■ Amazon Lexで対話型AIアプリを作ろう (Amazon Lex設定編)
https://press.monaca.io/hirose/8671
関数の作成
Lambdaサービスを利用して、Lexのチャットボットにユーザーが応答する度に呼ばれる関数を作成します。
AWSコンソールからLambdaのサービスを開きます。次のリンクからLambdaへアクセスできます。
https://ap-northeast-1.console.aws.amazon.com/lambda/home
「関数の作成」ボタンをクリックし、「一から作成」を選択します。
関数名に「MonacaPlanSuggestProcessor」などの任意の関数名を入力し、ランタイムは「Node.js 14.x」を選択。「アーキテクチャ」、「アクセス権限」、「詳細設定」は、デフォルトのままにします。
入力が完了したら、画面右下の「関数の作成」ボタンをクリックします。
コードソース
コードソースに次のコードを入力してください。
入力したら、「Deploy」ボタンをクリックします。
'use strict';
exports.handler = (event, context, callback) => {
try {
dispatch(event,
(response) => {
callback(null, response);
});
}
catch (err) {
callback(err);
}
};
function dispatch(intentRequest, callback) {
const slots = intentRequest.sessionState.intent.slots;
const IsForEnterprise = slots.IsForEnterprise?.value?.interpretedValue;
const UseEnterprisePlugins = slots.UseEnterprisePlugins?.value?.interpretedValue;
if (typeof IsForEnterprise === 'undefined') {
return callback(elicitSlot('IsForEnterprise', slots));
}
if (typeof UseEnterprisePlugins === 'undefined') {
return callback(elicitSlot('UseEnterprisePlugins', slots));
}
if (UseEnterprisePlugins === 'yes') {
return callback(close([{contentType: 'PlainText', content: 'あなたにおすすめのプランはEnterpriseプランです!'}], slots));
}
if (IsForEnterprise === 'no') {
return callback(close([{contentType: 'PlainText', content: 'あなたにおすすめのプランはProプランです!'}], slots));
}
return callback(close([{contentType: 'PlainText', content: 'あなたにおすすめのプランはBusinessプランです!'}], slots));
}
function elicitSlot(slotToElicit, slots) {
return {
sessionState: {
dialogAction: {
type: 'ElicitSlot',
slotToElicit,
},
intent: {
name: 'SuggestMonacaPlan',
slots,
state: 'InProgress'
},
},
};
}
function close(messages, slots) {
return {
sessionState: {
dialogAction: {
type: 'Close'
},
intent: {
name: 'SuggestMonacaPlan',
slots,
state: 'Fulfilled',
},
},
messages
};
}
dispatch関数
コードの解説をしていきます。
exports.handler
内で呼んでいる、dispatch関数がメイン関数です。
この関数ではまず、Lex側でユーザー入力したインテント・スロットの値は intentRequest.sessionState.intent.slots
から取得できるので、変数に設定しています。
const slots = intentRequest.sessionState.intent.slots;
const IsForEnterprise = slots.IsForEnterprise?.value?.interpretedValue;
const UseEnterprisePlugins = slots.UseEnterprisePlugins?.value?.interpretedValue;
「IsForEnterprise」と「UseEnterprisePlugins」は必須項目 としています。
そのため、未設定であれば、elicitSlot関数を呼び、戻り値をコールバック関数「callback」に渡して終了します。
elicitSlot関数の戻り値で取得されるオブジェクトがLexへのレスポンスとなります。
if (typeof IsForEnterprise === 'undefined') {
return callback(elicitSlot('IsForEnterprise', slots));
}
if (typeof UseEnterprisePlugins === 'undefined') {
return callback(elicitSlot('UseEnterprisePlugins', slots));
}
elicitSlot関数
elicitSlot関数を見てみましょう。
この関数では、第一引数に次に発動するするスロット名、第二引数に現在のスロットを渡します。この関数の戻り値では、「sessionState」をキーとするオブジェクトを返します。
function elicitSlot(slotToElicit, slots) {
return {
sessionState: {
dialogAction: {
type: 'ElicitSlot',
slotToElicit,
},
intent: {
name: 'SuggestMonacaPlan',
slots,
state: 'InProgress'
},
},
};
}
このオブジェクトの「dialogAction」には、Lexへの次の指示が含まれます。
「type」を'ElicitSlot'、slotToElicitに次に発動させるスロット名(「IsForEnterprise」または「UseEnterprisePlugins」)を指定すると、Lex側で次の質問を表示します。
会話のクローズ
ユーザーとLexの対話が進み、UseEnterprisePluginsとIsForEnterpriseに値が設定されたら、プランを決定できます。
今度はclose関数の戻り値をコールバック関数に渡します。
if (UseEnterprisePlugins === 'yes') {
return callback(close([{contentType: 'PlainText', content: 'あなたにおすすめのプランはEnterpriseプランです!'}], slots));
}
if (IsForEnterprise === 'no') {
return callback(close([{contentType: 'PlainText', content: 'あなたにおすすめのプランはProプランです!'}], slots));
}
return callback(close([{contentType: 'PlainText', content: 'あなたにおすすめのプランはBusinessプランです!'}], slots));
close関数
close関数では、今度は「dialogAction」の「type」を'Close'にします。
そして、第一引数で渡したmessegesオブジェクトをsessionStateオブジェクトに渡します。
function close(messages, slots) {
return {
sessionState: {
dialogAction: {
type: 'Close'
},
intent: {
name: 'SuggestMonacaPlan',
slots,
state: 'Fulfilled',
},
},
messages
};
}
messagesには条件に応じて3つのプランを提案するメッセージを設定します。
Lexに組み込む
それでは、作成したLambdaの関数をLexに組み込んでみます。
AWSコンソールからLexのサービスを開きます。次のリンクからアクセスできます。
https://ap-northeast-1.console.aws.amazon.com/lexv2/home
そして、前回作成した「MonacaSampleBot」をクリックします。
「ボットのバージョン」→「ドラフトバージョン」→「言語」セクションの「Japanese (Japan)」をクリックします。
次に「インテントの表示」をクリックし、「SuggestMonacaPlan」をクリックします。
一番下の「コードフック - オプション」の「初期化と検証に Lambda 関数を使用」にチェックを入れ、画面下部から「インテントの保存」と「構築」をクリックしてください。
構築が終わったら、「テスト」ボタンを押し、歯車マークをクリックします。
「Lambda 関数 - オプション」のソースは、「MonacaPlanSuggestProcessor」を選択します。他の項目はデフォルトのままにしておき、保存ボタンをクリックします。
テスト
それでは、前回同様に「こんにちは」と入力してみてください。
スロットに設定した質問の「法人でのご利用ですか?」が表示されます。この質問に回答すると、「アプリのソースコードやストレージの暗号化に興味はありますか?」という2つ目の質問が表示されます。
さらに回答すると、今度はプランの提案をするメッセージが表示されました。
以上で、LexとLambdaの連携の設定は完了です。
最終回となる次回ではMonacaでアプリに組み込む方法を紹介します。