0
0

LambdaからLex インテントのサンプル発話を更新しビルドする

Posted at

はじめに

本記事では、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.pylambda_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つともフルーツ名に更新されている事が確認できました。

image.png

  • 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"}
・・・

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0