メインコンテンツに移動
日常で楽しむクラウドテクノロジー

Amazon Bedrock はリアルなカードゲームでも強い味方だった ?! (ポーカー編)

2024-05-01 | Author : 井上 昌幸

はじめに

今年の正月に久しぶりに親戚とトランプや麻雀で遊んで楽しかったのですが、たまーにしかやらないので、やっぱりルールとか役とか得点計算方法とかを忘れていて、どうしてもグダグダになりがちでした・・・。

ということで、今回はリアル世界のカードゲームを Amazon Bedrock にきっちりとアシストしてもらおうというネタです。

このデモでは、日本でポピュラーな「ファイブカード・ドロー・ポーカー」を例に、ゲーム中にこっそり Amazon Bedrock に手札を見てもらって、次の一手のアドバイスをもらう、というのにチャレンジしています。出来上がりは以下のような Web アプリになります。

これはプレイ中の映像なのですが、Amazon Bedrock が Web カメラの映像を認識して、トランプの手札の絵を表示し、その手札に対するアドバイスをくれているのがわかりますよね。

この例では、最初にワンペアであることを認識して、次のドロー方法のアドバイスをくれています。その後、3 枚ドローすると (途中で一瞬フラッシュと間違えていますが) 最終的にはロイヤルフラッシュだと認識して、ポーカーで最強のハンドなので、このまま勝負でいいよと教えてくれていますね、すごいっす !


X ポスト » | Facebook シェア » | はてブ »

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 を展開すると以下のディレクトリ構成になっています。

bash
.
├── 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 を使用しています。

bash
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 の設定完了

これにより S3・Lambda・IoT Core・AWS IAM の設定が完了します。 cdk deploy 実行時に作成された S3 bucket 名が表示されます (例 : CdkStack.BucketNameOutput = cdkstack-pokerbucket3445747a-te5phsjp0uz7) ので控えておいてください。S3 bucket 名は AWS CloudFormation コンソール のスタックの Outputs でも確認することもできます。

3-3. Amazon Kinesis Video Streams (KVS) リソースの作成

以下のコマンドを実行し、ストリームの作成と S3 Delivery の設定を行います。 ここで、DestinationConfig は CDK で作成した S3 bucket を指定します。また、WidthPixels と HeightPixels は「デバイス側の設定」で設定するカメラの設定値と合わせるのが望ましいです。 この設定により、Web カメラからの画像を KVS が 10 秒毎に切り出して、S3 bucket に置きます。

bash
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 とサンプルコード をインストールします。

A Raspberry Pi device connected to an Anker camera with a USB cable, both resting on a wooden table.

Web カメラの映像を KVS に取り込む

これが終わったら、ビルドされたサンプルコードを使って、Web カメラの映像を KVS に取り込んでみましょう。 コマンドの引数は、使っている Webカメラが対応している値を指定します。ここでは 640x480 の解像度でフレームレートは 30 fps です。Web カメラが対応する値がわからない場合は、 gst-device-monitor-1.0 コマンドで確認できます。 ここまでできたら、KVS コンソールで poker-stream を確認してみることで動画が再生されること、また S3 bucket にイメージが置かれていくのがわかると思います。

bash
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 からリアルタイムなメッセージを受け取ることができます。簡単ですね。

javascript
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 のパッケージをインストールします。

bash
cd poker-builders-flash-v1.0.0/frontend npm ci

5-2. AWS Amplify の設定

プロジェクト名を webui として設定していきます。

bash
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 を選択してください。

bash
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

バックエンドをデプロイ

バックエンドをデプロイします。

bash
amplify push

5-3. AWS IoT Core のポリシー付与

ブラウザから IoT Core にアクセスするためのポリシーを unauthRole に付与します。AWS IAM のコンソールで webui で検索して unauthRole (例えば amplify-webui-dev-205849-unauthRole) をみつけ、以下のポリシーを付与します。  これで、ブラウザは MQTT トピック poker-advice からのメッセージを受け取ることが許可されました。

json
{
    "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 カメラからの映像がアップロードされている状態であることを確認して、再度実行してみてください。

bash
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> を変更します。エンドポイントは以下のコマンドで取得できます。

bash
aws iot describe-endpoint --endpoint-type iot:Data-ATS --output text

5-5. Web アプリの実行

npm run dev

bash
npm run dev

成功 !

localhost にアクセスして、このような画面が出てきたら成功です。

おめでとうございます。あとは、ポーカーをプレイしながら、ちらちらと手札をカメラに見せて、相手にバレないように ? アドバイスをもらってください。

Screenshot of the Poker Hand Advisor web app interface showing Japanese instructions, a video playback element, and five facedown playing cards. The instruction text in Japanese reads: 'ハンドを見せてください!' (Please show your hand!).

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 と一緒にカタチにしましょう。

A portrait photo of a smiling person with glasses, taken indoors with wooden interior elements visible in the background.