🙄
Amazon Lexとは?ゼロから学ぶ会話型チャットボット構築ハンズオン(Lambda連携)
Amazon Lexとは?
Amazon Lex は AWS が提供する会話型インターフェース構築サービスです。
自然言語理解(NLU)と自動音声認識(ASR)を使い、以下のようなチャットボットを簡単に作れます。
- カスタマーサポートボット
- FAQ ボット
- 音声ボット
- 入力フォームを会話で誘導するボット
- 予約・問い合わせ対応
- ChatGPT 的な Q&A インターフェース
Amazon Connect(コールセンター)とも統合できるのが強みです。
Lexでできること・特徴
✔ インテント(Intent)
ユーザーが「何をしたいか」を分類する仕組み。
例:
- 予約したい →
BookingIntent - 計算したい →
CalculateIntent
Lex はユーザーの入力から「どのインテントか」を自動で判別する。
✔ スロット(Slot)
必要な情報を抽出する項目。
例:
- FirstNumber
- OperatorType
- SecondNumber
✔ スロットタイプ(SlotType)
スロットの分類。
例:OperatorType → 足す/引く/割る など
✔ Lambda 連携
Fulfillment Code Hook を使うことで、
Lex → Lambda → Lex の応答フローが作れる。
ハンズオン
本記事では、以下のチャットボットを実際に構築します。
「1 足す 2」→「1 + 2 = 3 です!」と返す四則演算チャットボット
Amazon Lex(V2)+ AWS Lambda を使って会話で動くミニ計算機を構築します。
構成図

1. Lambdaの作成
- 「関数の作成」をクリック
- 設定を以下のようにする:
| 項目 | 設定 |
|---|---|
| 関数名 | lex-test |
| ランタイム | Python 3.12(推奨) |
| 実行ロール | 基本的な Lambda アクセス権限で新しいロールを作成 |
- Lambda のコードを以下に書き換える
import json
import re
from decimal import Decimal, InvalidOperation
def safe_number(x):
try:
return Decimal(str(x))
except InvalidOperation:
return None
def close(intent_name, session_state, message):
return {
"sessionState": {
**session_state,
"dialogAction": {"type": "Close"},
"intent": {
**session_state.get("intent", {}),
"name": intent_name,
"state": "Fulfilled"
}
},
"messages": [
{"contentType": "PlainText", "content": message}
]
}
def lambda_handler(event, context):
intent_name = event["sessionState"]["intent"]["name"]
slots = event["sessionState"]["intent"].get("slots", {})
session_state = event.get("sessionState", {})
a_raw = slots.get("FirstNumber", {}).get("value", {}).get("interpretedValue")
b_raw = slots.get("SecondNumber", {}).get("value", {}).get("interpretedValue")
op_raw = slots.get("OperatorType", {}).get("value", {}).get("interpretedValue")
# 補助:空白なし "1+2" の対応
if not (a_raw and b_raw and op_raw):
text = event.get("inputTranscript", "")
m = re.search(r"(-?\d+(?:\.\d+)?)\s*([+\-*/÷×])\s*(-?\d+(?:\.\d+)?)", text)
if m:
a_raw, op_raw, b_raw = m.groups()
a = safe_number(a_raw)
b = safe_number(b_raw)
if a is None or b is None or op_raw is None:
return close(intent_name, session_state, "うまく数字か演算子を読み取れませんでした。例: 12 + 34 のように送ってみてください。")
op_map = {
"+": "+",
"足す": "+", "たす": "+", "足して": "+", "たして": "+", "足し": "+", "加える": "+", "プラス": "+", "+": "+",
"-": "-",
"引く": "-", "ひく": "-", "引いて": "-", "ひいて": "-", "マイナス": "-", "−": "-",
"*": "*",
"×": "*", "かける": "*", "掛ける": "*", "かけて": "*", "掛けて": "*",
"/": "/",
"÷": "/", "割る": "/", "わる": "/", "割って": "/"
}
op = op_map.get(op_raw, op_raw)
try:
if op == "+":
result = a + b
elif op == "-":
result = a - b
elif op == "*":
result = a * b
elif op == "/":
if b == 0:
return close(intent_name, session_state, "0で割ることはできません。")
result = a / b
else:
return close(intent_name, session_state, f"演算子 '{op_raw}' が分かりません。")
except Exception as e:
return close(intent_name, session_state, f"計算中にエラーが出ました: {str(e)}")
if result == result.to_integral():
result_str = str(int(result))
else:
result_str = str(result.normalize())
return close(intent_name, session_state, f"{a} {op} {b} = {result_str} です!")
- 以下のjsonでテストする
{
"sessionState": {
"intent": {
"name": "CalculateIntent",
"slots": {
"FirstNumber": {
"value": {
"interpretedValue": "12"
}
},
"Operator": {
"value": {
"interpretedValue": "+"
}
},
"SecondNumber": {
"value": {
"interpretedValue": "34"
}
}
}
}
},
"inputTranscript": "12 + 34"
}
テスト結果例

2. Amazon Lex ボットを作成
- Amazon Lex → Bots
- 「Create bot」
- 設定を以下のようにする:
| 項目 | 設定 |
|---|---|
| 作成方法 | 空のボットを作成します。 |
| ボット名 | CalcBot |
| IAM アクセス許可 | 基本的な Amazon Lex 権限を持つロールを作成します。 |
| エラーログ | 無効 |
| COPPA | いいえ |
| セッションタイムアウト | 5分 |
| 言語 | Japanese (ja_JP) |
3. インテントを作成
- Intents → Add intent → Empty intent
- 名前:CalculateIntent
- サンプル発話に以下を設定
{FirstNumber} {OperatorType} {SecondNumber}
※サンプル発話とはユーザーがそのインテントで話しそうな言い方の例。
- インテントを保存
4. スロットタイプ(OperatorType)を作成
- スロットタイプ→スロットタイプを追加→空のスロットタイプを追加
- 設定を以下のようにする:
| 項目 | 設定 |
|---|---|
| スロットタイプ名 | OperatorType |
| スロット値の解決 | スロット値に制限 |
| スロットタイプ値 | 足す、たす、足して... |
5. Lambda を Lex に紐付け
- デプロイ→エイリアス
- 「TestBotAlias」を選択
- 言語:Japanese (Japan) をクリック
- Lambda function に
lex-testを選択 - 保存
6. スロットを作成
- インテント→
CalculateIntentを選択→スロット - 以下のように
FirstNumber、OperatorType、SecondNumberを設定する


7. フルフィルメントのCode Hook設定
- インテント→
CalculateIntentを選択→フルフィルメント -
フルフィルメントに Lambda 関数を使用にチェック
8. テスト
-
画面右上より
構築をクリック

-
右上から
テストをクリック

-
実際にテストしてみると正しく機能してることがわかります!

まとめ
本記事では Amazon Lex の基礎である
- インテント
- スロット
- スロットタイプ
- フルフィルメント(Lambda 連携)
- エイリアス運用
を、実際の四則演算チャットボット構築を通して学びました。
Amazon Lex は「会話から必要な情報を構造化して取り出す」ことが得意で、
ユーザー入力を “機械が扱える形” に変換するフロントエンド として非常に優れています。
これから
近年は Amazon Bedrock や Claude、Llama、Titan など
高性能な生成AIモデルと組み合わせることで、Lex で作るボットはさらに進化します。
Lex が:
- インテントを判定し
- スロットで情報を集め
- 必要事項を整理して Lambda に渡す
そのうえで Lambda 側で Bedrock を使うと、たとえば:
- 自然言語の質問に高精度で回答できる FAQ ボット
- 社内ドキュメントを検索して回答する RAG(検索拡張生成)ボット
- ブッキングや問い合わせの意図を AI が柔軟に判断して処理するボット
- 感情や文脈を理解した応答生成
といった、柔軟で“賢い”チャットボットが簡単に実現できます!
Discussion