生成 AI x RAG x サーバーレスで実現! AWS AppSync Events と Amazon Bedrock Knowledge Bases で作るライブチャットモデレーション
2025-09 | Author : 勝又 健登 & 櫻井 良
はじめに
ライブ配信サービスにおいて、リアルタイムなチャットは視聴者との重要な接点です。コメントによる反応や質問、スタンプでの盛り上がりは、配信の臨場感や一体感を生み出す要素として欠かせません。
従来のライブチャットシステムでは、WebSocket サーバーやメッセージキュー、監査用のサブシステムを自前で構築・運用する必要があり、リアルタイム性と拡張性を両立するには高いコストと技術的負荷が伴っていました。しかし、2024 年 10 月に発表された AWS AppSync Events と、その後リリースされたデータソース統合機能を活用することで、チャットのリアルタイム配信に加え、メッセージ内容の監査 (いわゆるコンテンツモデレーション) や分析をサーバーレスで簡単に実現できるようになりました。
この記事では、AWS AppSync Events を使ってライブ配信向けチャットサービスを構築し、同時にメッセージの記録や暴言フィルタリングなどの監査処理を AWS Lambda 統合で実装する方法を解説します。スケーラブルかつメンテナンス性の高いリアルタイム配信基盤の構築にご関心のある方は、ぜひ参考にしてみてください。
ご注意
本記事で紹介する AWS サービスを起動する際には、料金がかかります。builders.flash メールメンバー特典の、クラウドレシピ向けクレジットコードプレゼントの入手をお勧めします。
builders.flash メールメンバー登録
builders.flash メールメンバー登録で、毎月の最新アップデート情報とともに、AWS を無料でお試しいただけるクレジットコードを受け取ることができます。
1. AWS AppSync Eventsとは ?
リアルタイムチャットや通知機能など、サーバーからクライアントへの即時な情報配信は、モダンアプリケーションにおいて欠かせない要素です。しかし、こうした双方向通信を実現するためには、WebSocket サーバーの構築、接続状態の管理、スケーリング設計など、運用負荷が大きくなりがちです。
この課題を解決するのが、2024 年 10 月に登場した AWS AppSync Events です。サーバーレスでスケーラブルな WebSocket イベント配信を、最小限の設定とシンプルな API 呼び出しだけで実現できます。特徴的なのは、GraphQL のような特別なスキーマやクエリ言語を用いることなく、シンプルにリアルタイム通信を構築できる点です。これにより、開発チームは余計な学習コストをかけることなく導入・運用が可能になります。
AppSync Events は、チャネルベースの Pub/Sub モデルを採用しており、イベントは「チャネル」と呼ばれる論理的なトピックに対して送信されます。クライアントは必要なチャネルだけを購読 (Subscribe) し、該当するイベントをリアルタイムに受け取ることができます。さらに、チャネルは名前空間 (Namespace) で整理でき、チャネル名にワイルドカードを使った柔軟な購読も可能です。
そして特に注目したいのが、2025 年に追加されたデータソース統合機能です。受信したイベントをそのまま AWS Lambda や Amazon DynamoDB といったサービスに連携できるため、チャット配信にとどまらず、コンテンツモデレーション (メッセージの監査)、記録、不適切投稿の自動ブロックといった処理もサーバーレスで簡単に実装できます。
リアルタイム通信のためのインフラ構築や接続管理を意識することなく、柔軟なイベント処理と高い拡張性を両立できる AWS AppSync Events は、リアルタイム性と開発効率のバランスを重視するあらゆる現場にとって、有力な選択肢となるでしょう。
2. アーキテクチャ概要
本チャットシステムは、AWS AppSync Events をリアルタイム通信の中核とし、メッセージ内容の自動監査と保存機能を備えた拡張性の高いアーキテクチャとなっています。以下では、主な構成要素とメッセージの流れについて順を追って解説します。
フロントエンド
フロントエンドは React と Next.js により構築されており、ユーザーは Web ブラウザ上でチャットルームに参加し、メッセージを送受信します。通信には AWS Amplify の JavaScript SDK (aws-amplify/data) を使用しており、WebSocket チャネルへの接続 (connect) やサブスクライブ (subscribe)、メッセージ送信 (post) といった処理を数行のコードで簡潔に実装できます。ローコードで手軽にリアルタイム通信を取り入れたい場合には非常に有効な選択肢です。
なお、Amplify のイベント API 機能の詳細につきましては、公式ドキュメント に記載がございます。
バックエンド
バックエンドでは、AWS AppSync Events がリアルタイム配信の中核を担っています。ユーザーがチャットメッセージを送信すると、AWS AppSync はそのチャネルの Subscriber に対してメッセージを即時にブロードキャストします。
さらに、AWS AppSync のデータソース統合機能を利用することで、各メッセージは自動的に AWS Lambda に転送されます。Lambda 関数は、メッセージが利用規約に沿っているかどうかを生成 AI (Amazon Bedrock) を使って判定します。この際、Bedrock は Amazon OpenSearch Service にインデックスされた利用規約ドキュメント (Amazon S3 に保存) をナレッジソースとして参照し、チャット内容との照合を行います。
最終的な判定に応じて、正常なメッセージであればそのまま配信され、問題がある場合は警告文へ差し替えたうえで Publisher に配信されます。すべてのメッセージは Amazon DynamoDB に保存され、後からの監査やモデレーションにも活用可能です。
メッセージフロー
- ユーザーがチャットルームでメッセージを入力し、events.post() を通じて AWS AppSync Events に送信。
- AWS AppSync Events が受信したメッセージを、データソース統合により AWS Lambda に引き渡す。
- AWS Lambda 関数が Amazon Bedrock に問い合わせ、Amazon OpenSearch Service 上の利用規約を基に生成AIによるメッセージ内容の評価を実行。
- 評価結果に応じて、メッセージをそのまま使用するか警告文に差し替えるかを判定し、Amazon DynamoDB に記録。
- AWS Lambda からの応答を受けて、AWS AppSync Events がチャネルに接続しているすべてのクライアントへ (モデレーション済みの) メッセージをブロードキャスト。
このように、AWS AppSync Events を単なるメッセージ配信手段として使うのではなく、データソース統合によって高度な業務処理ロジックを連携させている点が本アーキテクチャの大きな特徴です。リアルタイム性とガバナンスを両立した柔軟なチャット基盤として、ライブ配信やコミュニティ運営における活用が期待できます。
3. 環境構築手順
本チャットシステムを構成する各 AWS サービスのセットアップ手順を順を追って説明します。
本セクションでは、バージニア北部 (us-east-1) で構築をしておりますが、Amazon Bedrock Knowledge Bases (対応リージョン)、AWS AppSync Events、AWS Lambda、Amazon DynamoDB が利用可能であれば任意のリージョンで実装可能です。サービスの対応状況につきましては AWS リージョン別サービス一覧 をご確認ください。なお、東京 (ap-northeast-1) でも本アーキテクチャは構築可能です。
また、簡略化のため AmazonDynamoDBFullAccess や AmazonBedrockFullAccess などの権限の広いポリシーを使用していますが、本番環境では最小権限の原則に従い、必要な操作のみに限定したカスタムポリシーを作成することを強く推奨します。詳しくは AWS Well-Architected セキュリティの柱 - 最小権限でアクセス許可を実装する をご参照ください。
それでは、最初に Lambda 関数を作成します。
3-1. AWS Lambda 関数の作成
AWS AppSync Events のデータソース統合では、メッセージ受信時の処理を Lambda 関数で実行できます。本構成では、 Lambda 関数よりメッセージの内容を Amazon Bedrock に送信し、コミュニティガイドラインに違反していないかを生成 AI によって判定します。その結果に応じて、Amazon DynamoDB にメッセージを記録し、必要に応じて内容を差し替えて配信します。
まずはこのロジックを担う AWS AppSync Events のバックエンドとして機能する Lambda 関数を作成します。
ステップ 1 : Lambda 関数の作成
- AWS マネジメントコンソールから「Lambda」にアクセスし、「関数の作成」を選択します。
- 以下のパラメータで関数を作成します。
- 関数名 : builders-flash-rag-function
- ランタイム : Python 3.13
- 実行ロール : 既存または新規ロールに、以下の権限を付与します:
- AmazonDynamoDBFullAccess
- AmazonBedrockFullAccess (もしくは Bedrock Agent の呼び出しに必要なポリシー)






ステップ 2 : Powertools for AWS Lambda (Python) レイヤーの追加
1. Lambda 関数が作成されたら、「コード」タブを開き、「レイヤーを追加」をクリック。
2. 以下のパラメータを選択:
- レイヤーソース : AWS レイヤー
- AWS レイヤー : AWSLambdaPowertoolsPythonV3-python313-x86_64 (※最新バージョンをご選択ください)
3. 「追加」を実行。
このレイヤーは、正式名称 Powertools for AWS Lambda と呼ばれる、AWS が提供する公式のユーティリティライブラリです。
構造化ロギング、トレーシング、イベントルーティング、バリデーションなど、Lambda 関数に必要な処理を簡潔かつ標準化された形で実装できるのが大きな特徴です。
今回のチャット監査処理のように、イベント種別ごとにルーティングしたり、バリデーションやログを適切に出力したい場面では特に有効です。もちろん、こうした処理はネイティブな WebSocket 実装でも対応可能ですが、開発速度や保守性を考慮すると Powertools の採用は非常に合理的な選択と言えます。
詳しくは Powertools for AWS Lambda (Python) 公式ドキュメント をご参照ください。


ステップ 3 : 環境変数の設定
Lambda 関数の設定タブ「環境変数」で、次の 2 つの環境変数を追加します。
「Bedrock のナレッジベース ID」については後述の設定で取得いただけます。
- KNOWLEDGE_BASE_ID:Bedrock のナレッジベース ID
- TABLE_NAME:LiveChatMessages


ステップ 4 : ハンドラーコードの登録
こちらからハンドラーコードをダウンロード し、作成した Lambda 関数 (builders-flash-rag-function) に貼り付け、「Deploy」します。
コードの説明
このコードでは以下を実行しています:
- AWS AppSync Events から受信したメッセージを元に、生成 AI へ RAG (Retrieve and Generate) リクエストを送信
- ガイドライン違反の有無を JSON 形式で取得
- 評価結果に応じてメッセージを Amazon DynamoDB に保存し、必要に応じて本文を差し替え
- AWS AppSync に返すイベントレスポンスを生成

3-2. AWS AppSync Event API の作成
Lambda 関数の作成が完了したら、次に AWS AppSync Event API を作成し、チャットのメッセージ受信処理を Lambda に統合します。本セクションでは、AWS AppSync Event API の構築と、Lambda データソースとの接続設定について解説します。
ステップ 1 : AWS AppSync Event API の作成
- AWS マネジメントコンソールから AWS AppSync にアクセスします。
- 「Event API を作成」をクリックします。
- API 名に builders-flash-event-api と入力し、「作成」をクリックします。



ステップ 2 : データソースの作成
1. 作成した API を選択します。
2. 「データソース」タブをクリックし、「データソースを作成」を選択します。
3. 以下の内容で入力します:
a. データソース名: builders_flash_rag_function
b. データソースタイプ: AWS Lambda
c. リージョン:builders_flash_rag_functionを作成したリージョン
d. Lambda 関数 ARN: builders-flash-rag-function の ARN
e. サービスロール:Create and use a new service-linked role
4. 「作成」をクリックします。


ステップ 3 : 名前空間の作成とイベントハンドラー設定
1. 「名前空間」タブを選択し、「名前空間を作成」をクリックします。
2. 以下の設定で入力します:
a. 名前空間名: chat
b. ハンドラー: データソースを含むコード
c. データソース名: builders-flash-rag-function
d. 動作: Direct
e. 呼び出しタイプ: RequestResponse
3. 設定が完了したら「作成」をクリックします。


3-3. DynamoDB テーブルの作成
AWS AppSync Events から連携された Lambda 関数は、すべてのチャットメッセージ (および審査結果) を Amazon DynamoDB に記録します。この処理に対応するため、以下の手順でテーブルを作成します。
ステップ 1 : DynamoDB コンソールにアクセス
- DynamoDB コンソール にアクセスします。
- 左メニューから「テーブル」を選択し、「テーブルを作成」をクリックします。
ステップ 2 : テーブル定義の入力
以下の情報を入力します:
- テーブル名: LiveChatMessages
- パーティションキー: liveId(文字列型)
- ソートキー: messageId(文字列型)
この設計により、1つのライブ配信 (liveId) ごとに複数のメッセージ (messageId) が時系列順に格納されます。
なお、messageId には UTC 時刻の ISO 文字列と UUID を組み合わせた文字列 を使用しています。これにより、以下のことを実現しています
- ソートキーとして自然に時系列順の並びが確保できる
- 各メッセージが一意に識別できる (UUID) という二つのメリットを同時に実現できます。
ステップ 3 : テーブルの作成
「テーブルを作成」をクリックして完了します。


保存されるデータの例
このテーブルには、次のようなデータが Lambda 関数から保存されます:
{
"liveId": "abc123",
"messageId": "2025-06-26T18:38:44.428147Z#076941a6-7c23-4475-82be-705162bcff21",
"username": "user1",
"message": "こんにちは!",
"isRejected": false,
"violationReason": ""
}
3-4. Amazon Bedrock ナレッジベースの作成
このセクションでは、チャットのモデレーション (荒らし・暴言・不適切発言の検出) に活用する Amazon Bedrock ナレッジベース を構築します。生成 AI による審査に一貫性と基準を持たせるために、事前に定義した「コミュニティガイドライン」をナレッジとして取り込む構成です。
ステップ 1 : ガイドラインファイルの準備
S3 バケットを作成し以下のファイルをアップロードしてください:
- バケット名: 任意の名前
- ファイル名: community_guideline.txt
- community_guideline.txt の内容は下記の「コミュニティガイドライン (デモ用)」よりコピー & ペーストしてください
このファイルには、チャットで禁止されている表現や行為を詳細に記述しており、ナレッジベースが RAG (Retrieve and Generate) を通じて参照するベース情報となります。
保存されているガイドライン
アップロードされた community_guideline.txt (デモ用) の内容は以下のような構成です:
- 攻撃的な発言、差別的な表現、性的内容、スパム行為、個人情報の開示などを明確に禁止
- 建設的な会話やリスペクトを推奨
- 評価結果を自動化するための基準として活用
# コミュニティガイドライン(デモ用)
- 他者を罵倒・侮辱・挑発する言動
- 誹謗中傷、ハラスメント
- 人種、性別、国籍、宗教、障がい等に基づく差別発言
- わいせつな言葉・描写
- 性的なニュアンスを含む冗談や誘導
- 同一内容の連投
- 商品・サービス・リンクの宣伝
- 意味のない言葉の羅列や、単語・表現の過剰な繰り返し
- 汚い言葉・暴言・ネットスラング
- 他者が不快に感じる表現全般
- 実名、電話番号、住所などの投稿
- 建設的な意見交換
- 楽しさと安全の共有
ステップ2: ナレッジベースの詳細を指定
- Amazon Bedrock コンソール にアクセスし、「ナレッジベース」を選択。
- 「作成」をクリック。
- 「ベクトルストアを含むナレッジベース」をクリック。
以下の情報を入力します:
- ナレッジベース名 : LiveChatGuidelineKB
- IAM 許可 : 新しいサービスロールを作成して使用
- データソースを選択 : Amazon S3
- 「次へ」を選択


ステップ3 : データソースを設定
- データソースの場所 : この AWS アカウント
- S3 : 作成した S3 バケット
- 解析戦略 : Amazon Bedrock デフォルトパーサー
- チャンキング戦略 : デフォルトチャンキング
- 「次へ」を選択

ステップ3: データストレージと処理を設定
- 埋め込みモデル : Titan Text Embeddings V2
- ベクトルストアの作成方法 : 新しいベクトルストアをクイック作成
- ベクトルストア : Amazon OpenSearch Serverless
- 「次へ」を選択
- 確認画面が出るので「ナレッジベースを作成」をクリック

ナレッジベース ID
※ナレッジベースが作成されると、詳細ページに ナレッジベース ID が表示されます。これをコピーし、Lambda 関数 (builders-flash-rag-function) の環境変数 KNOWLEDGE_BASE_ID に設定します。

4. フロントエンドの構築
このセクションでは、ユーザーがライブチャットに参加し、リアルタイムでメッセージを送受信できる React ベースのフロントエンドアプリケーションを構築します。使用するフロントエンドのプロジェクトは こちらよりダウンロード できます。
本アプリケーションは Next.js を使用しており、AWS Amplify SDK を活用することで AWS AppSync Events との接続やメッセージ送受信を非常に簡潔に実装しています。
使用技術と特徴
- Next.js (React フレームワーク)
- AWS Amplify SDK v6+
- AppSync Events との WebSocket 通信をローコードで実現
- API キー認証による簡易接続
- Tailwind CSS によるスタイリング
- イベントチャンネル名:/chat/{liveId} に動的接続
構成概要
チャットページの構成は以下のようになっています:
- ユーザー名とライブ配信 ID (username / liveId) をローカルストレージから取得
- AppSync Events に対して connect() を呼び出し、/chat/{liveId} チャンネルにサブスクライブ
- メッセージが届くたびに画面に即時反映 (subscribe() )
- 送信時は events.post() で publish
実装ファイル例:app/chat/page.tsx
以下は実際のコードの構成と役割の簡単な解説です。
Amplify.configure(AMPLIFY_CONFIG);
AppSync Event API のエンドポイントや API キーを設定
特定のライブ ID に基づいてチャンネル接続します。ここでは WebSocket 接続がバックグラウンドで確立されます
const connectionPromise = events.connect(`/chat/${liveId}`);
チャンネルへのサブスクライブ
メッセージ受信処理を登録します。
channel.subscribe({ next: handleIncomingMessage }
メッセージの publish
メッセージを publish します。
await events.post(`/chat/${liveId}`, messageData);
特筆すべき点:Amplify SDK によるローコード構成
- WebSocket のハンドリングやトークン処理を SDK 側で吸収してくれるため、手動での接続管理や Ping 処理が一切不要
- 公式 Amplify SDK は、AppSync Events の「動的チャネル」や「Publish / Subscribe」モデルを抽象化して提供しており、Next.js との親和性も高い
- 今回の構成では、フロントエンド側でチャットの状態管理・UI 描画に専念でき、ネットワーク処理は SDK が代行してくれるため、非常に生産性の高い開発が可能です。
UI 構成 (概要)
- MessageBubble コンポーネント : 受信済みメッセージを吹き出し形式で表示
- MessageInput コンポーネント : ユーザーがメッセージを入力・送信
- scrollToBottom() 関数 : 最新メッセージへ自動スクロール
- モデレーション結果 (isRejected) が true の場合、表示文面を差し替え
5. 動作確認
セットアップ
依存関係をインストールします。
npm install
.env.local に環境変数を設定
コマンド
NEXT_PUBLIC_APPSYNC_ENDPOINT=あなたのappsyncエンドポイント
NEXT_PUBLIC_AWS_REGION=あなたのawsリージョン
NEXT_PUBLIC_AUTH_MODE=apiKey
NEXT_PUBLIC_API_KEY=あなたのapiキー
開発サーバーを起動
使用方法
- 最初のページでユーザー名とライブ ID を入力します。
- 「視聴する」をクリックしてチャットルームに入室します。
- 入力フィールドにメッセージを入力し、「送信」をクリックするか Enter キーを押します。
- メッセージはすべての接続ユーザーにリアルタイムで表示されます。

チャット画面の確認
2 つの異なるユーザー (例: Alice と Bob) が同じ Live ID (f64f2f85 など) に参加した場合、以下のような画面が表示されます。
主な確認ポイント
- 送信されたメッセージが即座にすべてのクライアントに反映される (Pub/Sub)
- 不適切と判定されたメッセージは、全クライアント上で「表示できません」メッセージに置き換えられる
例:「このコメントはコミュニティガイドラインに違反しているため表示できません」
- メッセージの投稿者・タイムスタンプが表示されている
不適切な内容の自動フィルタリング
- Bob が攻撃的、またはガイドライン違反とされるコメントを送信します。
- Lambda 関数が Amazon Bedrock に問い合わせます。
- 返ってきた判定結果が isRejected: true の場合、Amazon DynamoDB に保存はされつつも、画面上には「非表示」メッセージとして出力されます。
- 全クライアント共通で、同じ検閲済みのメッセージが反映されます。
6. リソースの削除
以上でサンプルチャットアプリの動作確認は完了です。
不要なコスト発生を防ぐため、使用したリソースを忘れずに削除しましょう。
AWS AppSync Event API
- サービス名: builders-flash-event-api
- 削除手順:
a. AWS マネジメントコンソールで「AWS AppSync」にアクセス
b.「API」一覧から builders-flash-event-api を選択
c. 右上の「削除」ボタンをクリックし、確認のうえ削除
AWS Lambda 関数
- 関数名: builders-flash-rag-function
- 削除手順:
a.「AWS Lambda」コンソールを開く
b. builders-flash-rag-function を選択
c. 右上の「アクション」メニュー →「関数の削除」を選択
d. 削除確認ダイアログに従って削除
DynamoDB テーブル
- テーブル名: LiveChatMessages
- 削除手順:
a.「Amazon DynamoDB」コンソールを開く
b. LiveChatMessages テーブルを選択
c. 右上の「削除」ボタンをクリックし、確認のうえ削除
※ チャットログがすべて削除されます。
必要であれば事前にエクスポートしてください。
S3 バケット(ナレッジベース用)
- バケット名: builders-flash-bedrock-knowledge-base
- 削除手順:
a. 「Amazon S3」コンソールを開く
b. builders-flash-bedrock-knowledge-base を選択
c. 中にある community_guideline.txt を削除
d. バケット自体を削除 (バケットは空である必要があります)
Bedrock ナレッジベース
- 削除手順:
a. 「Amazon Bedrock」コンソールを開く
b. 左側メニュー「ナレッジベース」を選択
c. 作成したナレッジベース(S3 バケットと連携しているもの)を選択
d. 右上の「削除」をクリックし、確認して削除
※ OpenSearch を使っている場合は関連インデックスも忘れず削除してください
CloudWatch ロググループ(任意)
- 削除手順:
a. 「Amazon CloudWatch」コンソールを開く
b. 左メニューから「ロググループ」を選択
c. 以下のロググループが存在する場合、それぞれチェックして「ロググループの削除」を実行
/aws/lambda/builders-flash-rag-function
6. まとめ
本記事では、AWS AppSync Events のデータソース統合機能を活用し、リアルタイムかつチャットモデレーション機能付きのチャットアプリを構築する方法を紹介しました。
特に注目すべきポイントは以下のとおりです。
- GraphQL の学習不要で、ローコードかつシンプルにリアルタイム通信が実現できる
- AppSync Events のチャネルベースPub/Subにより、スケーラブルで安定した WebSocket インフラを手間なく構築
- データソース統合機能により、バックエンド処理 (保存・検閲)を柔軟かつ簡単に実現可能
- Amazon Bedrock + ナレッジベース (RAG)により、AI を使ったチャットモデレーションもサーバレスで簡単に実現
- Amplify SDK を活用することで、フロントエンド側の通信処理も極めてシンプル
筆者プロフィール

勝又 健登 (Kent Katsumata)
アマゾン ウェブ サービス ジャパン合同会社
クラウドアプリケーションアーキテクト
2023 年にサポート部門のクラウドサポートエンジニアとして新卒入社。主にフロントエンド・サーバーレスサービスの技術支援を担当させていただきました。2024 年 8 月からはパブリックセクタープロフェッショナルサービス部門のクラウドアプリケーションアーキテクトとして、主に公共機関のお客様中心にフロントエンド・サーバーレスアーキテクチャを用いたシステムの設計・構築に取り組んでいます。
スキーが趣味で冬はほぼ毎週末友人と雪山にいます。

櫻井 良 (Ryo Sakurai)
アマゾン ウェブ サービス ジャパン合同会社
ソリューションアーキテクト
2023 年にサポート部門のクラウドサポートエンジニアとして新卒入社。主にサーバーレス・IoT サービスの技術支援を担当させていただきました。2024 年 8 月からはソリューションアーキテクトとして、主に小売・流通・消費財業界のお客様に対して基幹システムの AWS 移行や AI ソリューションの導入支援に取り組んでいます。
趣味は温泉巡りで、週末は何処かの温泉に出没しています。