🎃

Bedrock Guardrails コンテンツフィルターのアプリ組み込み

に公開

導入

背景・目的

  • 2025年3月のアップデートにより、Bedrock Guardrailsのコンテンツフィルターのマルチモーダル対応がGAになりました。
  • まずは、AWSコンソール上でGuardrailを作成し、テストを行うことで、マルチモーダル対応がGAとなったことを確認します。
  • その後、AWS上で稼働する画像分析アプリケーションにコンテンツフィルターを組み込む方法について、簡易的なサンプルアプリを実装しながら解説します。

対象読者

  • 本記事は、AWS 認定ソリューションアーキテクト - アソシエイトレベルの知識を持つ読者を想定しており、AWSサービスの基本的な解説は省略します。

AWSコンソール上でのGuardrail作成・テスト

Guardrail作成

AWSコンソール画面からGuardrailの設定画面にアクセスして、Guardrailを作成します。
今回はコンテンツフィルターのみを有効化します。以前は Image の部分に付いていた「Preview」マークが削除されたことが確認できます。


すべてのフィルターを有効化したうえで、Guardrailを作成します。

Guardrailテスト

作成したGuardrailのコンテンツフィルターが想定通りに機能するかどうか、Guardrailの詳細画面からテストしてみましょう。
Claude 3.5 Sonnet にボクシングの画像をアップロードし、その説明を求めたところ、想定通りGuardrailによってブロックされました。

カスタムアプリへの組み込み

環境概要

コンテンツフィルターが想定通りに機能することをテストできたため、実際にカスタムアプリへコンテンツフィルターを組み込んでみます。
S3にアップロードされた画像ファイルについて、Lambda経由でBedrockを呼び出して、画像の説明文章を生成します。

Guardrailバージョンの作成

アプリケーションに組み込むための事前準備として、Guardrailのバージョンを作成します。
Guardrailの詳細画面からバージョンを作成することができます。

カスタムアプリの作成

Lambda上で稼働するカスタムアプリをPythonで実装します。
s3:ObjectCreated:*イベントからの起動を想定し、boto3を用いてS3から画像ファイルを取得したうえで、Bedrockの基盤モデルを呼び出しています。

import json
import boto3
import base64
import os
from urllib.parse import unquote_plus

s3_client = boto3.client('s3')
bedrock_client = boto3.client('bedrock-runtime')

MODEL_ID = "apac.anthropic.claude-3-5-sonnet-20241022-v2:0"
GUARDRAIL_ID = os.environ.get("GUARDRAIL_ID")
GUARDRAIL_VERSION = os.environ.get("GUARDRAIL_VERSION")


def lambda_handler(event, context):
    try:
        for record in event['Records']:
            try:
                # Get Object Info
                bucket_name = record['s3']['bucket']['name']
                object_key = unquote_plus(record['s3']['object']['key'])
            except KeyError as e:
                print(f"Error extracting S3 event details: {e}")
                return {'statusCode': 400, 'body': json.dumps({'error': 'Invalid S3 event format'})}

            try:
                # Get Image from S3
                image_obj = s3_client.get_object(
                    Bucket=bucket_name, Key=object_key)
                image_data = image_obj['Body'].read()
            except Exception as e:
                print(f"Error retrieving image from S3: {e}")
                return {'statusCode': 500, 'body': json.dumps({'error': 'Failed to retrieve image from S3'})}

            try:
                # Invoke Model
                b64_image = base64.b64encode(
                    image_data).decode('utf-8')
                body = json.dumps(
                    {
                        "anthropic_version": "bedrock-2023-05-31",
                        "max_tokens": 100,
                        "messages": [{"role": "user", "content": [
                            {"type": "image", "source": {"type": "base64",
                                                         "media_type": "image/jpeg", "data": b64_image}},
                            {"type": "text", "text": "この画像について説明してください。"}
                        ]}],
                    }
                )
                response = bedrock_client.invoke_model(
                    modelId=MODEL_ID,
                    body=body,
                    guardrailIdentifier=GUARDRAIL_ID,
                    guardrailVersion=GUARDRAIL_VERSION,
                )
                response_body = json.loads(
                    response['body'].read().decode('utf-8'))
            except Exception as e:
                print(f"Error invoking model: {e}")
                return {'statusCode': 500, 'body': json.dumps({'error': 'Model invocation failed'})}

            print(response_body)
            return {
                'statusCode': 200,
                'body': json.dumps(response_body)
            }
    except Exception as e:
        print(f"Unexpected error: {e}")
        return {'statusCode': 500, 'body': json.dumps({'error': 'Internal server error'})}


AWS基盤の作成

CDKを用いて、画像ファイルをアップロードするためのS3や、カスタムアプリの実行基盤となるLambda関連資源を作成します。
Lambda関数向けにbedrock:ApplyGuardrail 権限の付与を忘れないように留意ください。

    // ---- S3
    const myBucket = new s3.Bucket(this, 'MyS3Bucket', {
      removalPolicy: cdk.RemovalPolicy.DESTROY, // 開発用のためDESTROY設定
      autoDeleteObjects: true,
      enforceSSL: true,
    });

    // ---- Lambda
    // Create Lambda Function
    const myFunction = new lambda.Function(this, "MyFunction", {
      runtime: lambda.Runtime.PYTHON_3_12,
      code: lambda.Code.fromAsset('lambda/python/genai'),
      handler: 'lambda_function.lambda_handler',
      memorySize: 256,
      timeout: cdk.Duration.seconds(25),
      tracing: lambda.Tracing.ACTIVE,
      insightsVersion: lambda.LambdaInsightsVersion.VERSION_1_0_98_0,
      environment: {
        GUARDRAIL_ID: props.guardrailId,
        GUARDRAIL_VERSION: props.guardrailVersion,
      }
    })
    // Grant Access
    myBucket.grantRead(myFunction);
    myFunction.addToRolePolicy(new iam.PolicyStatement({
      actions: ['bedrock:InvokeModel', 'bedrock:ApplyGuardrail'],
      resources: ['*'], // 開発用のため広めに権限付与
    }));
    myBucket.addEventNotification(s3.EventType.OBJECT_CREATED, new s3n.LambdaDestination(myFunction));

動作確認

カスタムアプリやAWS基盤を作成したので、動作確認してみましょう。
先程のテスト時に利用したボクシングの画像ファイルをS3にアップロードしてみます。
アップロード後にLambdaが起動して、Guardrailにてブロックされていることが確認できます。

'content': [{'type': 'text', 'text': '申し訳ありませんが、モデルはこの質問に回答できません。'}],
'amazon-bedrock-guardrailAction': 'INTERVENED'

次に、ブロックされないパターンも確認してみましょう。猫の画像をS3にアップロードしてみます。アップロード後にLambdaが起動して、無事画像の説明が生成されていることが確認できます。

'content': [{'type': 'text',
'text': 'この画像には、床の上で横たわっているかわいいキジトラ猫が写っています。
猫は大きな表情豊かな目をしており、カメラの方をじっと見つめています。
体を横にして寛いでいるような姿勢で、典型的な猫のリラックスした様子が捉えられています。'}],
'amazon-bedrock-guardrailAction': 'NONE'

考察

生成AIのさらなる利活用を推進するにあたり、責任あるAIの運用を通じて、公平性・透明性・安全性を確保することが不可欠です。
基盤モデルが備える保護機能に加え、BedrockのGuardrails を活用することで、より強固なコンテンツフィルタリングを実現できます。
安全なAI活用の実現に向けて、ユースケースやシステム要件に応じて適切な設定を検討するのが良いでしょう。

参考

https://aws.amazon.com/jp/about-aws/whats-new/2025/03/amazon-bedrock-guardrails-general-availability-image-content-filters/

https://aws.amazon.com/jp/blogs/machine-learning/amazon-bedrock-guardrails-image-content-filters-provide-industry-leading-safeguards-helping-customer-block-up-to-88-of-harmful-multimodal-content-generally-available-today/

https://aws.amazon.com/jp/blogs/news/amazon-bedrock-guardrails-now-supports-multimodal-toxicity-detection-with-image-support/

https://docs.aws.amazon.com/ja_jp/bedrock/latest/userguide/guardrails-supported.html

https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-37.html#model-parameters-anthropic-claude-37-request-response

注意事項

  • 本記事は万全を期して作成していますが、お気づきの点がありましたら、ご連絡よろしくお願いします。
  • なお、本記事の内容を利用した結果及び影響について、筆者は一切の責任を負いませんので、予めご了承ください。
Accenture Japan (有志)

Discussion