Bedrockで規約違反の投稿を自動でチェックしてみる

スポンサーリンク
ハンズオン
スポンサーリンク

はじめに

ブログや掲示板、フォーラムを運営していると、炎上につながるコメントや荒らし行為に頭を悩ませることはありませんか?
建設的なコミュニケーションを目的とした場であるはずなのに、荒らされてしまうと評価や信頼に悪影響がでてしまいますよね。
とはいえ、すべてのコメントを手作業でチェックするのは時間も手間もかかり、24時間・365日人の目でチェックをするのは現実的ではありません。

そこで本記事では、AWSを活用したコメント自動チェック機能をご紹介します。
具体的には、Amazon Bedrockを使ってコメント内容を規約に沿ってチェックし、判定結果を出力するAPIを作成します。
このAPIを利用することで、コメント投稿時に自動で規約違反をチェックする仕組みを簡単に導入できます。

記事内では、実際の画面を使って手順をわかりやすく解説していますので、
AWSに慣れていない方でも安心して取り組めます。
ぜひ参考にしてみてください!

環境構成

以下の構成で自動チェック機能を構築していきます。

本記事ではLambdaにシステムプロンプト(前提の命令)を埋め込んでますが、S3から取得するといった方法を利用すると前提条件を変えて実行が可能です。

前提作業

以下実施してください。

  • AWSアカウントの作成
  • Bedrockの基盤モデル(Anthoropic社のClaude 3.5 Sonet)を有効にする(以下の記事が参考になります)
    Amazon Bedrockの基盤モデルを有効化して使ってみる
    ※基盤モデルの有効化はリージョンごとで設定が必要です。API GatewayやLambdaと同じリージョンでモデルを有効化してください。
  • 投稿規約の作成
    以下Claude 3.5 Sonetで生成したサンプルです。
    システムプロンプトには、こちらの黄色部分の禁止行為の部分を埋め込んでみます。

    【掲示板投稿規約】
    当掲示板をご利用いただく際は、以下の規約に同意したものとみなします。

    1. 一般規則
      • 法律、条例等の法令に違反する投稿を禁止します。
      • 他人の権利を侵害する投稿を禁止します。
      • 公序良俗に反する投稿を禁止します。
    2. 禁止行為 以下の行為を禁止します:
      • 差別的な発言や人種、民族、性別、宗教等に関する攻撃的な投稿
      • わいせつな内容や過激な性的表現を含む投稿
      • 他人への誹謗中傷、脅迫、プライバシーの侵害
      • スパム行為、広告目的の投稿
      • 著作権や商標権等の知的財産権を侵害する投稿
      • 個人情報の掲載
      • 同じ内容の連続投稿や不必要に多数の投稿を行う行為
      • 荒らし行為、議論を妨害する行為
      • その他、管理者が不適切と判断する投稿
    3. 投稿内容の責任
      • 投稿内容に関する責任は、投稿者本人が負うものとします。
      • 管理者は、問題のある投稿を予告なく削除する権利を有します。
    4. アカウントの停止・削除
      • 規約違反が繰り返される場合、アカウントの一時停止または削除を行う場合があります。
    5. 免責事項
      • 当掲示板での投稿内容や他のユーザーとのやり取りによって生じたいかなる損害についても、管理者は責任を負いません。
    6. 規約の変更
      • 本規約は予告なく変更される場合があります。定期的にご確認ください。

    以上の規約を遵守し、互いに尊重しあう心を持って、楽しく有意義な議論の場としてご利用ください。

設定手順

設定の流れ

以下の流れで設定作業をします。

  1. システムプロンプトの定義
  2. Lambda関数の設定
  3. Lambda関数のIAMロールの設定
  4. API Gatewayの設定

1. システムプロンプトの定義

システムプロンプトの構成は以下です。

  1. 役割を定義
  2. 具体的な指示を定義
  3. 出力フォーマットを定義

上記の構成に従って、システムプロンプトを以下で定義します。
<role></role>の内容は使っている投稿規約に設定してください。

あなたは文章をチェックするオペレータです。
入力された文章が以下の規約に沿った内容かチェックしてください。
<role>
禁止行為 以下の行為を禁止します:
・差別的な発言や人種、民族、性別、宗教等に関する攻撃的な投稿
・わいせつな内容や過激な性的表現を含む投稿
・他人への誹謗中傷、脅迫、プライバシーの侵害
・スパム行為、広告目的の投稿
・著作権や商標権等の知的財産権を侵害する投稿
・個人情報の掲載
・同じ内容の連続投稿や不必要に多数の投稿を行う行為
・荒らし行為、議論を妨害する行為
・その他、管理者が不適切と判断する投稿
</role>
判定結果に沿って、以下のjsonフォーマットで結果を復帰してください。
その他の出力は不要です。
◆規約違反ではない内容の場合
{ “result”: true, “message”: “” }
◆規約違反の内容の場合
{ “result”: true, “message”: “【具体的な規約違反内容を出力】” }
このシステムプロンプトをLambda関数に埋め込んでいきます。

2. Lambda関数の作成

Lambda関数を作成します。

AWS管理コンソールのサービス検索欄で「Lambda」と入力しLambdaのサービスを開きます。

Lambda関数を作成していきます。
まだLambda関数を作成したことがない場合は以下の画面が表示されます。
関数の作成ボタンを選択してください。Lambda関数の作成画面に遷移します。

すでに作成済みの方は以下の画面が表示されます。
同じく関数の作成ボタンを選択してください。

Lambda関数の作成画面が表示されます。
基本的にはデフォルトの設定で関数を作成していきます。
関数名は任意の名前、ランタイムはNode.js 22.x を選択してください。
入力が終わったら、「関数の作成」を選択してください。

しばらくすると関数の設定画面に遷移します。

タイムアウト時間を変更するため、「設定」タブを選択し、左メニューから「一般設定」を選択し、「編集」ボタンを選択します。

タイムアウトの時間を25秒に変更します。API Gatewayのタイムアウト値が29秒なので、それより短い25秒に設定しています。一度の実行で10秒程度かかるときもあるので余裕をもった時間にしています
変更ができたら「保存」を選択してください。

次に環境変数を設定します。設定値は以下です。入力が終わったら「保存」を選択してください。

キー 説明
REGION ap-northeast-1 Bedrockのモデルを有効化したリージョンを指定してください。
MODELID anthropic.claude-3-5-sonnet-20240620-v1:0 投稿時点での最新モデルを指定しています。
VERSION bedrock-2023-05-31 anthropicのバージョン。公式ドキュメントを見ると「bedrock-2023-05-31」を指定する旨が記載されています。

Lambda関数の呼び出しファイルの拡張子を変更します。
「コード」タブを選択し、「コードソース」の左メニューの「index.mjs」を「index.js」に変更してください。

続けて、ソースを書き換えていきます。
以下のソースに書き換えてください。

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.handler = void 0;
const client_bedrock_runtime_1 = require("@aws-sdk/client-bedrock-runtime");
// 環境変数の取得
const REGION = process.env.REGION;
const MODELID = process.env.MODELID;
const VERSION = process.env.VERSION;
// 変数定義
const basePrompt = () => {
    return `
        あなたは文章をチェックするオペレータです。 
        入力された文章が以下の規約に沿った内容かチェックしてください。 
         
        禁止行為 以下の行為を禁止します:
        ・差別的な発言や人種、民族、性別、宗教等に関する攻撃的な投稿
        ・わいせつな内容や過激な性的表現を含む投稿
        ・他人への誹謗中傷、脅迫、プライバシーの侵害
        ・スパム行為、広告目的の投稿
        ・著作権や商標権等の知的財産権を侵害する投稿
        ・個人情報の掲載
        ・同じ内容の連続投稿や不必要に多数の投稿を行う行為
        ・荒らし行為、議論を妨害する行為
        ・その他、管理者が不適切と判断する投稿
        
        判定結果に沿って、以下のjsonフォーマットで結果を復帰してください。
        その他の出力は不要です。

        ◆規約違反ではない内容の場合 
        { "result": true, "message": "" } 
 
        ◆規約違反の内容の場合
        { "result": true, "message": "【具体的な規約違反内容を出力】" }
        `;
};
// Bedrock Clientの初期化
const bedrockRuntimeClient = new client_bedrock_runtime_1.BedrockRuntimeClient({ region: REGION });
// handler関数の定義
const handler = async (event) => {
    try {
        // インプットチェック
        console.log("----- インプットチェック -----");
        const body = event.body ? JSON.parse(event.body) : {};
        const { input } = body;
        if (!input) {
            return {
                statusCode: 400,
                body: JSON.stringify({ message: "Missing 'input' in request body." }),
            };
        }
        console.log("input: " + input);
        console.log("----------");
        // 実行パラメタの定義
        console.log("----- 実行パラメタの定義 -----");
        const payload = {
            anthropic_version: VERSION,
            max_tokens: 1000,
            system: basePrompt(),
            messages: [
                {
                    role: "user",
                    content: [
                        { type: "text", text: input }
                    ],
                }
            ],
        };
        console.log("payload:");
        console.log(payload);
        console.log("----------");
        // Claudeで実行
        console.log("----- Claudeで実行 -----");
        const command = new client_bedrock_runtime_1.InvokeModelCommand({
            contentType: "application/json",
            body: JSON.stringify(payload),
            accept: "application/json",
            modelId: MODELID,
        });
        console.log("command:");
        console.log(command);
        const response = await bedrockRuntimeClient.send(command);
        console.log("----------");
        // 復帰処理
        console.log("----- 復帰処理 -----");
        const decodedResponseBody = new TextDecoder().decode(response.body);
        const responseBody = JSON.parse(decodedResponseBody);
        console.log("responseBody: ");
        console.log(responseBody);
        console.log("----------");
        return {
            statusCode: 200,
            body: responseBody.content[0].text
        };
    }
    catch (error) {
        console.error("Error invoking Bedrock model:", error);
        return {
            statusCode: 500,
            body: JSON.stringify({
                message: "Internal Server Error",
                error: error.message,
            }),
        };
    }
};
exports.handler = handler;

書き換えた後に「Deploy」を選択してLambda関数を更新します。

Lambda関数の作成のステップはこれで完了です。

3. Lambda関数のIAMロールの設定

Lambdaに紐づいているIAMロールにBedrockのモデルの実行権限を付与します。

先ほどのLambda関数の設定画面から「設定」タブを開き、「一般設定」を選択し、「編集」を選択してください。

画面の下にLambda関数に紐づいているロールのリンクが表示されています。リンクを選択してください。

IAMロールの設定画面が表示されます。
「許可を追加」を選択し、「インラインポリシーを作成」を選択してください。

ポリシーの設定画面が表示されます。「JSON」を選択してJSONエディタを開きます。

エディタを編集していきます。

以下を入力してください。
arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0
の部分は利用するリージョンやモデルIDに合わせて変更してください。
入力後、画面下の「次へ」を選択してください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "bedrock:InvokeModel",
            "Resource": [
                "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-3-5-sonnet-20240620-v1:0"
            ]
        }
    ]
}

ポリシー名を入力して「ポリシーの作成」を選択します。

ポリシーが追加されました。

これでLambda関数のIAMロール設定は完了です。

4. API Gatewayの設定

APIとして公開するための設定をします。

AWS管理コンソールのサービス検索欄で「API Gateway」と入力しAPI Gatewayのサービスを開きます。

APIの作成画面に遷移します。「REST API」の「構築」ボタンを選択します。

REST APIの作成画面に遷移します。
以下の入力項目を入力し、「APIを作成」を選択します。

項目 設定値 説明
APIの詳細 新しいAPI 新規でAPIを作成するため、新しいAPIを選択
API名 【任意の名前】 任意の値を入力
説明 【任意の説明】 任意で説明を入力
APIエンドポイントタイプ リージョン インターネット向けに公開するため、
「リージョン」を選択
特定VPCからの接続を許可する場合は
「プライベート」を選択
※プライベートの場合のVPC設定については本記事で解説しておりません。

APIのリソース画面が表示されます。
APIのメソッドを作成するため、「メソッドを作成」を選択します。

メソッドの設定をします。
以下の入力項目を入力し、「メソッドを作成」を選択します。

項目 設定値 説明
メソッドタイプ POST メソッドのタイプを指定
結合タイプ Lambda関数 作成したLambda関数を使うため
Lambdaプロキシ統合 ON プロキシ統合するためON
Lambda関数 【リージョン】、【作成したLambda関数のARN】 作成したLambda関数のリージョンとARNを入力
結合のタイムアウト 29000 デフォルト値を使用

メソッドを作成した後、「APIをデプロイ」を選択してください。

新しいステージを作成します。
ステージを「*新しいステージ*」を選択し、任意のステージ名を入力してください。

新しいステージが作成されます。
作成したステージ用のAPIのURLが表示されます。動作確認で使用するのでメモに控えておいてください。

動作確認

作成したAPIを実行していきます。APIクライアントなどで以下を実行してください。

POST 【APIのURL】
{
    "input": "【チェックしたいコメント】"
}

レスポンスは以下となります。

・規約上問題ないコメントの場合

{
    "result": true,
    "message": ""
}

・規約違反のコメントの場合

{
    "result": false,
    "message": "【規約違反となる理由】"
}

NG例 個人情報を含む場合

リクエスト

POST 【APIのURL】
{
    "input": "私の名前は山田太郎です。東京都千代田区千代田1−1に住んでいます。"
}

レスポンス

{
    "result": false,
    "message": "個人情報の掲載が含まれています。具体的な氏名と住所が記載されており、プライバシーの侵害に当たる可能性があります。"
}

NG例 荒らし行為(意味のない文章)

リクエスト

POST 【APIのURL】
{
    "input": "あああああああああああああああああああああああああああああああああああああああ"
}

レスポンス

{
    "result": false,
    "message": "同じ内容の連続投稿や不必要に多数の投稿を行う行為に該当します。意味のない文字の連続は、有意義な議論や情報交換を妨げる可能性があります。"
}

OK例

リクエスト

POST 【APIのURL】
{
    "input": "私はゲームをするのが好きです。一緒に遊んでくれるゲーム友達を探しています。"
}

レスポンス

{
    "result": true,
    "message": ""
}

いい感じに振り分けできていそうですね!

まとめ

本記事では、Amazon Bedrockを使って、投稿されたコメントが規約に沿ったものか判定するAPIを作成してみました。

文章のチェックなど単純なプログラムではチェックができないものでも生成AIを使うことで簡単に判定することができます

今回はわかりやすくAPIの実行をトリガーとしてコメントの内容のチェックを行っていますが、AWSの他のサービスを使うことで以下のような使い方が可能です。

  • キューイング(SQS)を使うことで、コメント投稿アクションの後にチェックする
  • ファイルアップロード(S3)をトリガーとし、ファイルの内容をチェックする

またシステムプロンプトに定義した指示文を変更することで文章の要約・生成なども可能です。

ぜひ実際に使って試してみてください!

生成AIについて詳しく知りたい方は以下の書籍がおすすめです。

 

 

タイトルとURLをコピーしました