はじめに
今年の正月に久しぶりに親戚とトランプや麻雀で遊んで楽しかったのですが、たまーにしかやらないので、やっぱりルールとか役とか得点計算方法とかを忘れていて、どうしてもグダグダになりがちでした・・・。
ということで、今回はリアル世界のカードゲームを Amazon Bedrock にきっちりとアシストしてもらおうというネタです。
このデモでは、日本でポピュラーな「ファイブカード・ドロー・ポーカー」を例に、ゲーム中にこっそり Amazon Bedrock に手札を見てもらって、次の一手のアドバイスをもらう、というのにチャレンジしています。出来上がりは以下のような Web アプリになります。
これはプレイ中の映像なのですが、Amazon Bedrock が Web カメラの映像を認識して、トランプの手札の絵を表示し、その手札に対するアドバイスをくれているのがわかりますよね。
この例では、最初にワンペアであることを認識して、次のドロー方法のアドバイスをくれています。その後、3 枚ドローすると (途中で一瞬フラッシュと間違えていますが) 最終的にはロイヤルフラッシュだと認識して、ポーカーで最強のハンドなので、このまま勝負でいいよと教えてくれていますね、すごいっす !
Web アプリのデモ
ご注意
本記事で紹介する AWS サービスを起動する際には、料金がかかります。builders.flash メールメンバー特典の、クラウドレシピ向けクレジットコードプレゼントの入手をお勧めします。
builders.flash メールメンバー登録
1. アーキテクチャ
全体のアーキテクチャは以下の図のようになります。
- Web カメラからのポーカーの映像を Amazon Kinesis Video Streams (KVS) の S3 Delivery 機能を使って定期的に画像として取得し、Amazon S3 に置きます。
- これをトリガーに AWS Lambda が起動し、Amazon Bedrock で手札の推論が動きます。
- 推論結果は AWS IoT Core を経由してリアルタイムにブラウザに MQTT over WebSocket で Publish されブラウザで確認できます。
では、作っていきましょう !
アーキテクチャ図
2. サンプルコード
はじめに、サンプルコードをダウンロード してください。
ディレクトリ構成
poker-builders-flash-v1.0.0.zip を展開すると以下のディレクトリ構成になっています。
.
├── README.md
├── cdk
│ ├── README.md
│ ├── bin
│ │ └── cdk.ts
│ ├── cdk.json
│ ├── jest.config.js
│ ├── lambda
│ │ └── lambda_function.py
│ ├── lib
│ │ └── cdk-stack.ts
│ ├── package-lock.json
│ ├── package.json
│ ├── test
│ │ └── cdk.test.ts
│ └── tsconfig.json
└── frontend
├── index.html
├── main.js
├── package-lock.json
├── package.json
└── style.css
3. クラウドリソースの作成
今回は Bedrock で使用するモデルの関係で全てのリソースを us-east-1 リージョンに作成します。
3-1. Amazon Bedrock の設定
Bedrock の初期設定として、ユーザーガイド に沿ってモデルアクセスの設定をしてください。今回使用するモデルは Anthropic の Claude 3 Sonnet です。モデルの用途を入力する部分は “bulders.flash poker demo” としてください。
3-2. AWS Cloud Deployment Kit (CDK) の実行
AWS Cloud Deployment Kit (CDK) を使うのが初めての場合は、AWS CDK 概要 (Basic #1)【AWS Black Belt】や CDK の開発者ガイド などを参考に CDK をインストールしてください。すでに CDK がインスールされていれば、以下のコマンドでセットアップできます。
セットアップコマンド
node のバージョンは v20.11.1 を使用しています。
cd poker-builders-flash-v1.0.0/cdk
npm ci
cdk bootstrap # us-east-1でcdkの使用が初めての場合
export AWS_REGION=us-east-1
cdk deploy
S3・Lambda・IoT Core・AWS IAM の設定完了
3-3. Amazon Kinesis Video Streams (KVS) リソースの作成
以下のコマンドを実行し、ストリームの作成と S3 Delivery の設定を行います。 ここで、DestinationConfig は CDK で作成した S3 bucket を指定します。また、WidthPixels と HeightPixels は「デバイス側の設定」で設定するカメラの設定値と合わせるのが望ましいです。 この設定により、Web カメラからの画像を KVS が 10 秒毎に切り出して、S3 bucket に置きます。
aws kinesisvideo create-stream --stream-name poker-stream
-----------------------------------
aws kinesisvideo update-image-generation-configuration --stream-name poker-stream --cli-input-json '{
"ImageGenerationConfiguration": {
"Status": "ENABLED",
"ImageSelectorType": "SERVER_TIMESTAMP",
"DestinationConfig": {
"Uri": "s3://cdkstack-pokerbucket3445747a-te5phsjp0uz7",
"DestinationRegion": "us-east-1"
},
"SamplingInterval": 10000,
"Format": "JPEG",
"FormatConfig": {
"JPEGQuality": "100"
},
"WidthPixels": 640,
"HeightPixels": 480
}
}'
4. デバイス側の設定
トランプを読み取るためのハードウェアは Raspberry Pi に一般的な Web カメラを繋いだものです。
KVS に動画を送るために、以下の手順で Raspberry Pi に KVS の SDK とサンプルコード をインストールします。

Web カメラの映像を KVS に取り込む
これが終わったら、ビルドされたサンプルコードを使って、Web カメラの映像を KVS に取り込んでみましょう。 コマンドの引数は、使っている Webカメラが対応している値を指定します。ここでは 640x480 の解像度でフレームレートは 30 fps です。Web カメラが対応する値がわからない場合は、 gst-device-monitor-1.0 コマンドで確認できます。 ここまでできたら、KVS コンソールで poker-stream を確認してみることで動画が再生されること、また S3 bucket にイメージが置かれていくのがわかると思います。
cd ~/amazon-kinesis-video-streams-producer-sdk-cpp/build
./kvs_gstreamer_sample poker-stream -w 640 -h 480 -f 30
5. Web フロントエンドの設定
フロントエンドは Vite と AWS Amplify を使って作っていきます。IoT デバイスからのメッセージをブラウザがリアルタイムに受け取る方法は、AWS AppSync など含めいくつか方法がありますが、ここでは私が簡単なデモを作る際によく使う Amplify PubSub を使う方法を紹介します。
IoT Core からリアルタイムなメッセージを受け取る
Amplify PubSubは、MQTT over WebSocket でメッセージを受け取る方法です。事前のスキーマ定義も必要なく、設定もシンプルで扱いやすいと思っています。例えば、以下のコードだけで IoT Core からリアルタイムなメッセージを受け取ることができます。簡単ですね。
const pubsub = new PubSub({
region: '<YOUR-IOT-REGION>',
endpoint: 'wss://<CODE>.iot.<YOUR-IOT-REGION>.amazonaws.com/mqtt'
});
pubsub.subscribe({ topics: '<MQTT_TOPIC_NAME>' }).subscribe({
next: (data) => console.log('Message received', data),
error: (error) => console.error(error),
complete: () => console.log('Done')
});
5-1. Vite と AWS Amplify のインストール
package-lock.json を使って Vite と Amplify のパッケージをインストールします。
cd poker-builders-flash-v1.0.0/frontend npm ci
5-2. AWS Amplify の設定
プロジェクト名を webui として設定していきます。
amplify init
? Enter a name for the project webui
? Initialize the project with the above configuration? Yes
? Select the authentication method you want to use: AWS profile
? Please choose the profile you want to use default
✔ Help improve Amplify CLI by sharing non-sensitive project configurations on failures (y/N) · yes
Amplify Auth を設定
Amplify Auth を設定します。 ここでは未認証のアクセスを許可するために、最初の質問を Manual Configuration でスタートしています。ここを Default configuration にすると後半の質問をスキップできますが、その場合は、Amazon Cognito のコンソールの Identity Pool で Guest access を Activate してください。Allow unauthenticated logins? は Yes を選択してください。
amplify add auth
Do you want to use the default authentication and security configuration? Manual configuration
Select the authentication/authorization services that you want to use: User Sign-Up, Sign-In, connected with AWS IAM controls (Enables per-user Storag
e features for images or other content, Analytics, and more)
Provide a friendly name for your resource that will be used to label this category in the project: webui6fe3f9ad6fe3f9ad
Enter a name for your identity pool. webui6fe3f9ad_identitypool_6fe3f9ad
Allow unauthenticated logins? (Provides scoped down permissions that you can control via AWS IAM) Yes
Do you want to enable 3rd party authentication providers in your identity pool? No
Provide a name for your user pool: webui6fe3f9ad_userpool_6fe3f9ad
Warning: you will not be able to edit these selections.
How do you want users to be able to sign in? Username
Do you want to add User Pool Groups? No
Do you want to add an admin queries API? No
Multifactor authentication (MFA) user login options: OFF
Email based user registration/forgot password: Disabled (Uses SMS/TOTP as an alternative)
Please specify an SMS verification message: Your verification code is {####}
Do you want to override the default password policy for this User Pool? No
Warning: you will not be able to edit these selections.
What attributes are required for signing up? Email
Specify the app's refresh token expiration period (in days): 30
Do you want to specify the user attributes this app can read and write? No
Do you want to enable any of the following capabilities?
Do you want to use an OAuth flow? No
Do you want to configure Lambda Triggers for Cognito? No
バックエンドをデプロイ
バックエンドをデプロイします。
amplify push
5-3. AWS IoT Core のポリシー付与
ブラウザから IoT Core にアクセスするためのポリシーを unauthRole に付与します。AWS IAM のコンソールで webui で検索して unauthRole (例えば amplify-webui-dev-205849-unauthRole) をみつけ、以下のポリシーを付与します。 これで、ブラウザは MQTT トピック poker-advice からのメッセージを受け取ることが許可されました。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:Connect"
],
"Resource": [
"arn:aws:iot:us-east-1:<ACCOUNT_ID>:client/*"
]
},
{
"Effect": "Allow",
"Action": [
"iot:Receive"
],
"Resource": [
"arn:aws:iot:us-east-1:<ACCOUNT_ID>:topic/poker-advice"
]
},
{
"Effect": "Allow",
"Action": [
"iot:Subscribe"
],
"Resource": [
"arn:aws:iot:us-east-1:<ACCOUNT_ID>:topicfilter/poker-advice"
]
}
]
}
5-4. サンプルコードのパラメータ更新
以下の二つのファイル内のパラメータを更新します。 index.html 内の <VIDEO_SOURCE_URL> は KVS が動的に生成するため、Web アプリを起動する前に生成して、設定します。この URL は以下のコマンドで取得できます。取得できない場合は、Web カメラからの映像がアップロードされている状態であることを確認して、再度実行してみてください。
STREAM=poker-stream KVS_DATA_ENDPOINT=$(\ aws kinesisvideo get-data-endpoint \ --stream-name $STREAM \ --api-name GET_HLS_STREAMING_SESSION_URL \ --query 'DataEndpoint' --output text \ ) HLSStreamingSessionURL=$(\ aws kinesis-video-archived-media \ get-hls-streaming-session-url --endpoint-url $KVS_DATA_ENDPOINT \ --stream-name $STREAM \ --playback-mode LIVE \ --expires 43200 \ --query 'HLSStreamingSessionURL' --output text \ ) echo $HLSStreamingSessionURL
エンドポイントの取得
main.js の <IOT_CORE_ENDPOINT> を変更します。エンドポイントは以下のコマンドで取得できます。
aws iot describe-endpoint --endpoint-type iot:Data-ATS --output text
5-5. Web アプリの実行
npm run dev
npm run dev
成功 !
localhost にアクセスして、このような画面が出てきたら成功です。
おめでとうございます。あとは、ポーカーをプレイしながら、ちらちらと手札をカメラに見せて、相手にバレないように ? アドバイスをもらってください。

6. まとめ
今回は AWS の IoT と AI のマネージドサービスを活用して、リアル世界のポーカーとクラウド上の生成 AI をリアルタイムに繋いでみました。
便利に使おうとするとメガネにつけるくらいの小型カメラが必要かもしれませんが、手札の推論と次の一手のアドバイスについては、今回の単純な Prompt でも、Amazon Bedrock / Claude 3 がそこそこいい仕事をしてくれていると思います。
実は Amazon Bedrock を使う前に Amazon Rekognition でカスタムモデルの作成と推論をあれこれ試したのですが、それと比べてかなり短時間で高精度なものができました。またトランプ以外にも UNO や麻雀も試してみたところ、UNO のカードはそこそこ認識できる、麻雀牌はちょっと厳しいかな、という感じでした。RAG やファインチューニングなどを組み合わせれば、今回のアーキテクチャで他のゲームも楽しめるのではないかと思います。興味のある方はチャレンジしてみてください !
筆者紹介
井上 昌幸
アマゾン ウェブ サービス ジャパン合同会社
IoT Specialist Solutions Architect
Internet of Things と Robotics 界隈で面白い事を探しながら、今日もこつこつリアルな世界とクラウドを繋いでいます。あなたのとっておきのアイデアを AWS と一緒にカタチにしましょう。
