はじめに
本記事では、AWS Lambda のスクリプトからLex Bot のサンプル発話を更新し、DRAFTバージョンをビルドする処理を実装していきます。
環境
- Python:3.12
- Lex:v2
ゴール
Lambda関数から下記の2点を実行する
- Lex Botのサンプル発話の内容を更新する
- Lex BotのDRAFTバージョンをビルドする
LambdaからLexのビルドについては下記の記事に実装しています。
Lex
本記事では下記のように6つのインテントのあるLex Botを想定しています。
インテント(初期)
・intent0001(サンプル発話:あああ)
・intent0002(サンプル発話:いいい)
・intent0003(サンプル発話:ううう)
・intent0004(サンプル発話:えええ)
・intent0005(サンプル発話:おおお)
・FallbackIntent
これらLex インテント 6つのうち、4つ(intent0001~intent0004)をLambdaで更新しビルドします。
インテント(Lambdaで更新後)
・intent0001(サンプル発話:リンゴ)
・intent0002(サンプル発話:バナナ)
・intent0003(サンプル発話:ぶどう)
・intent0004(サンプル発話:えええ)
・intent0005(サンプル発話:もも)
・FallbackIntent
Lambdaの作成
本記事では、lex_operations.py
と lambda_function.py
の2つのスクリプトを作成します。
-
lambda_function.py
環境変数からインテント名を取得し、各インテントに登録されてるサンプル発話の文言をfruit_utterances
の内容に更新します。
その後Botのビルドを開始し、使用可能な状態("Built")になるまで待機します。
lambda_function.py
import boto3
import json
import os
from lex_operations import update_intents, build_bot, get_draft_status, wait_for_build_completion
def lambda_handler(event, context):
lex_client = boto3.client('lexv2-models')
bot_id = os.environ['BOT_ID']
bot_version = 'DRAFT'
locale_id = os.environ['LOCALE_ID']
intent_names = [
os.environ['INTENT_NAME_1'],
os.environ['INTENT_NAME_2'],
os.environ['INTENT_NAME_3'],
os.environ['INTENT_NAME_4']
]
# サンプル発話の内容
fruit_utterances = ["リンゴ", "バナナ", "ぶどう", "もも"]
# ビルド前の DRAFT ステータスを取得
pre_build_status = get_draft_status(lex_client, bot_id, locale_id)
print(f"ビルド前の DRAFT ステータス: {json.dumps(pre_build_status)}")
# インテントの更新
update_intents(lex_client, bot_id, bot_version, locale_id, intent_names, fruit_utterances)
# DRAFT バージョンをビルド
build_bot(lex_client, bot_id, bot_version, locale_id)
# ビルドの完了を待機
wait_for_build_completion(lex_client, bot_id, bot_version, locale_id)
# ビルド後の DRAFT ステータスを取得
post_build_status = get_draft_status(lex_client, bot_id, locale_id)
print(f"ビルド後の DRAFT ステータス: {json.dumps(post_build_status)}")
return {
'statusCode': 200,
'body': json.dumps({
'message': 'インテントが更新され、ボットのビルドが完了しました',
'preBuildStatus': pre_build_status,
'postBuildStatus': post_build_status,
'buildSuccess': post_build_status['buildStatus']
}, ensure_ascii=False)
}
-
lex_operations.py
lambda_function.py
から呼び出す関数をそれぞれ作成しています。
関数の詳細はコメントアウトの通りです。
lex_operationspy
import time
# サンプル発話を更新
def update_intent_utterances(client, bot_id, bot_version, locale_id, intent_id, intent_name, new_utterance):
client.update_intent(
botId=bot_id,
botVersion=bot_version,
localeId=locale_id,
intentId=intent_id,
intentName=intent_name,
sampleUtterances=[{'utterance': new_utterance}]
)
# インテントを更新
def update_intents(client, bot_id, bot_version, locale_id, intent_names, utterances):
intents = client.list_intents(
botId=bot_id,
botVersion=bot_version,
localeId=locale_id
)
intent_summaries = intents['intentSummaries']
for intent_name, utterance in zip(intent_names, utterances):
intent_id = None
for intent in intent_summaries:
if intent['intentName'] == intent_name:
intent_id = intent['intentId']
break
update_intent_utterances(client, bot_id, bot_version, locale_id, intent_id, intent_name, utterance)
# DRAFT ステータスを取得
def get_draft_status(client, bot_id, locale_id):
response = client.describe_bot_locale(
botId=bot_id,
botVersion='DRAFT',
localeId=locale_id
)
return {
'buildStatus': response['botLocaleStatus'],
'lastBuildDateTime': str(response.get('lastBuildSubmittedDateTime'))
}
# ビルドが完了するまで待機
def wait_for_build_completion(client, bot_id, bot_version, locale_id):
while True:
response = client.describe_bot_locale(
botId=bot_id,
botVersion=bot_version,
localeId=locale_id
)
print(f"現在のビルドステータス: {response['botLocaleStatus']}")
if response['botLocaleStatus'] in ['Built', 'Failed']:
break
time.sleep(5)
# Botをビルド
def build_bot(client, bot_id, bot_version, locale_id):
client.build_bot_locale(
botId=bot_id,
botVersion=bot_version,
localeId=locale_id
)
動作確認
Lambdaをテスト実行すると、200のステータスコードでレスポンスが返ってきました。
Lex Botを確認するとインテント(intent0001~intent0004)の中のサンプル発話が 4つともフルーツ名に更新されている事が確認できました。
- CloudWatch
Lambdaの実行ログをCloudWatchで確認してみると、BotのビルドステータスがBuilding⇒ReadyExpressTesting⇒Builtとなっている事を確認できます。
ビルドが完了し使用可能な状態(Built)になっている事を確認できました。
CWログ
・・・
ビルド前の DRAFT ステータス: {"buildStatus": "Built", "lastBuildDateTime": "2024-09-28 11:27:20.595000+00:00"}
現在のビルドステータス: Building
現在のビルドステータス: Building
現在のビルドステータス: Building
現在のビルドステータス: ReadyExpressTesting
現在のビルドステータス: ReadyExpressTesting
現在のビルドステータス: ReadyExpressTesting
現在のビルドステータス: ReadyExpressTesting
現在のビルドステータス: Built
ビルド後の DRAFT ステータス: {"buildStatus": "Built", "lastBuildDateTime": "2024-09-28 11:30:59.952000+00:00"}
・・・