6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【作業時間3時間】全ブロガーに捧ぐ!Rekognition×Bedrockで、S3に画像を置くだけの全自動altタグ生成パイプライン

Last updated at Posted at 2025-07-14

こんにちは。SCSK株式会社の佐藤優音です!

この記事は「2025 Japan AWS Jr. Chanpions 夏のQiitaリレー」の記念すべき10日目の記事です!

過去の投稿(リンク集)はこちらからご覧ください!
https://qiita.com/natsumi_a/items/80539843482fed4cd648?utm_campaign=post_article&utm_medium=twitter&utm_source=twitter_share

この記事はこんな方におすすめ!

  • 1分でも早くブログを書き終えて寝たい方(私も深夜に執筆しておりますが…)
  • AWSの複数サービスを掛け合わせてシステムを作ってみたい初心者の方
  • コーディングは最小限で、AIを使った自動化を体験したい方

所要時間: 2〜3時間で完成します!
難易度: AWS初心者〜中級者
前提知識: 基本的なAWSの知識があると良いですが、コピペでもOK

🔥 この記事のGOAL

S3に画像をドラッグ&ドロップするだけで、以下が全自動で完了します!

# 投稿した画像: hachioji-ramen.jpg
# ↓ 1分後、AIが自動生成 ↓

ImageName: hachioji-ramen.jpg
AltText: 熱々のスープに浮かぶ中華麺と、チャーシュー、ネギが盛り付けられた美味しそうな八王子ラーメン
DetectedLabels: Food, Noodle, Ramen, Bowl, Soup, Dish

これを使えば、今までやっていたように画像1枚1枚にキャプションを付ける必要はなくなります!

💡 なぜ作ったのか:3つの理由

1. とにかく面倒だった(切実)

やっぱりブログの価値はコンテンツ!なのに、altタグをつけるような「作業」に時間を奪われるのってストレスですよね…?
1つのブログに対して10枚画像を付けたなら、その分altタグを付けなければいけないなんて面倒ですよね…?

2. SEOとアクセシビリティをサボりたくなかった

せっかく書いたブログを多くの人に見てほしい!でもSEO対策アクセシビリティ対応をする時間がないという方も少なくないのでは…?

3. 初心者の方でも簡単に構築できるシステムを作ってみたかった

AIサービスを触ってみたいという方も多いと思いますが、システムに組み込むのは少々ハードルが高いもの…。
「目で見るAI(画像認識)」と「脳で考えるAI
(文章生成)」の最強コンビを、簡単なセットアップでつくってみたくなりました!

🏗️ システム構成

今回構築するシステムは、面倒なサーバー管理が一切不要なサーバーレス構成です。
ざっくりとした構成図は以下のようになっています。
本システムの構成図

今回は初心者の方でも短い時間で簡単にサービスどうしの連携を理解してもらいたいという狙いから、データが格納されたDynamoDBを直接参照するような形にしています。

もちろんフロントエンドを開発することでアップロードから結果の取得まで同一画面で行うことができるので利便性は上がりますね!

サービス 役割
Amazon S3 画像アップロード先
AWS Lambda 処理実行
Amazon Rekognition 画像認識
Amazon Bedrock 文章生成
Amazon DynamoDB データ保存

重要: 東京リージョン (ap-northeast-1) での構築を前提としています

🚀 システムを構築してみよう

Step 1: DynamoDBテーブルの作成

まずは出力結果を格納するDynamoDBをテーブルを作成していきます。
手順は以下の通りですが、CLIからも作成することが可能です!

  1. DynamoDBコンソールを開く
  2. 「テーブルを作成」をクリック
  3. 以下を設定:
    • テーブル名: ImageAltTags
    • パーティションキー: ImageName (文字列)
  4. 「テーブルを作成」

AWS CLIでの作成例:

aws dynamodb create-table \
    --table-name ImageAltTags \
    --attribute-definitions AttributeName=ImageName,AttributeType=S \
    --key-schema AttributeName=ImageName,KeyType=HASH \
    --billing-mode PAY_PER_REQUEST

Step 2: IAMロールの作成

セキュリティ重要: 最小権限の原則に従い、必要な権限のみを付与しましょう!

続いてIAMロールを作成していきます。計5ロール付与できていればOKです。

必要な管理ポリシー:

  • AWSLambdaBasicExecutionRole(Lambdaを実行を許可するロール)
  • AmazonRekognitionReadOnlyAccess(Rekognitionの読み取りのみを許可するロール)
  • AmazonDynamoDBFullAccess_v2(DynamoDBへのアクセスを許可するロール)
  • AmazonS3ReadOnlyAccess(S3の読み取りのみを許可するロール)

加えて、Bedrock実行用にインラインポリシーも追加しておきましょう。

Bedrock用のインラインポリシー:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "bedrock:InvokeModel",
      "Resource": "*"
    }
  ]
}

Step 3: Lambda関数の作成

続いて本システムの司令塔ともいえるLambda関数を作成していきます。

  • 関数名: GenerateAltTagFunction
  • ランタイム: Python 3.13
  • 実行ロール: 上記で作成したロール
  • タイムアウト: 1分に延長(重要!)

ソースコード:

import json
import boto3
import urllib.parse

# boto3クライアントの初期化
s3_client = boto3.client('s3')
rekognition_client = boto3.client('rekognition')
bedrock_runtime_client = boto3.client('bedrock-runtime', region_name='ap-northeast-1')
dynamodb_resource = boto3.resource('dynamodb')
table = dynamodb_resource.Table('ImageAltTags')

def lambda_handler(event, context):
    # S3イベントからバケット名とファイル名を取得
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')

    try:
        # 1. Amazon Rekognitionで画像からラベルを検出
        rek_response = rekognition_client.detect_labels(
            Image={'S3Object': {'Bucket': bucket, 'Name': key}},
            MaxLabels=10,
            MinConfidence=80
        )
        labels = [label['Name'] for label in rek_response['Labels']]
        labels_string = ", ".join(labels)

        # 2. Amazon Bedrockでaltタグを生成
        model_id = 'anthropic.claude-3-5-sonnet-20240620-v1:0'

        prompt = f"""
        あなたはプロのWebコンテンツライターです。SEOとアクセシビリティの重要性を深く理解しています。
        画像の内容を表す以下のキーワード群を元に、その画像に最適なalt属性用の説明文を1つだけ生成してください。
        説明文は、具体的で、画像に示されているものが読者にはっきり伝わるように、かつ簡潔に記述してください。

        キーワード: {labels_string}

        alt説明文:
        """

        bedrock_request_body = {
            "anthropic_version": "bedrock-2023-05-31",
            "max_tokens": 200,
            "messages": [
                {
                    "role": "user",
                    "content": [{"type": "text", "text": prompt}]
                }
            ]
        }

        bedrock_response = bedrock_runtime_client.invoke_model(
            body=json.dumps(bedrock_request_body), modelId=model_id
        )

        response_body = json.loads(bedrock_response.get('body').read())
        alt_text = response_body.get('content')[0].get('text').strip()

        # 3. 結果をDynamoDBに保存
        table.put_item(
            Item={
                'ImageName': key,
                'AltText': alt_text,
                'DetectedLabels': labels_string
            }
        )

        return {'statusCode': 200, 'body': json.dumps('Successfully generated alt tag.')}

    except Exception as e:
        print(f"Error processing file {key} from bucket {bucket}. Error: {e}")
        raise e

プロンプトエンジニアリングのポイント:
あなたはプロのWebコンテンツライターです。と役割を与えることで、AIの性能が向上します。
ここを書き換えることで、自分だけのAIにカスタマイズ可能!

Step 4: S3バケットとイベント通知の設定

最後に、画像を格納するS3バケットの設定をLambdaへの通知を設定していきましょう。

  1. S3バケットを作成(例: my-alt-tag-generator-20250715
  2. バケットの「プロパティ」タブを開く
  3. 「イベント通知」→「イベント通知を作成」
  4. 以下を設定:
    • イベントタイプ: 「すべてのオブジェクト作成イベント」
    • 送信先: 「Lambda関数」
    • Lambda関数: GenerateAltTagFunction

🎉 これで完成!早速画像をアップロードして試してみましょう!

🐛 トラブルシューティング:よくあるエラー集

開発時によくあるエラーをおさらいしておきましょう。
迷った時にはとにかくCloudWatchを確認すること!
そこにエラーが吐き出されていなければLambda自体が正しく呼び出されていない可能性が…。
エラーがなかったとしてもトラブルシューティングの対象を絞り込めるという点では、CloudWatchを確認する価値がありそうです。

エラー1: InvalidS3ObjectException

原因: LambdaがS3オブジェクトを読み取る権限がない
解決: IAMロールに AmazonS3ReadOnlyAccess を追加

エラー2: ValidationException (Bedrock)

原因: 指定したモデルが利用できない、またはリージョンが間違っている
解決: 東京リージョンで利用可能なモデルに変更

エラー3: ResourceNotFoundException (DynamoDB)

原因: テーブル名が間違っている、またはテーブルが存在しない
解決: DynamoDBコンソールでテーブルの存在を確認

デバッグのコツ: CloudWatch Logsで詳細なエラーログをチェックしよう

今後の展望

このシステムをベースにして、次のような拡張も可能です!

🔄 WordPress連携

  • WordPress REST APIを使って記事に自動でaltタグを設定
  • 既存記事の画像にも一括でaltタグを適用

🌐 多言語対応

  • 英語、中国語、韓国語でのaltタグ生成
  • 国際的なWebサイトでの活用

📱 SNS連携

  • 生成完了をSlack/Teamsに通知
  • 生成されたaltタグをTwitterで共有

🎨 画像解析の高度化

  • 感情分析を追加(「楽しそうな」「落ち着いた」など)
  • ブランドカラーの検出と説明への反映

コスト試算→月1000枚処理しても激安!

月1000枚の画像処理をするケースで金額を概算してみました。
ブログに写真を多く使用される方にはかなりお勧めできます!

サービス 使用量 単価 月額コスト
S3 1GB保存 $0.025/GB $0.025
Lambda 1000回実行 $0.0000002/回 $0.0002
Rekognition 1000枚解析 $0.001/枚 $1.00
Bedrock 1000回呼び出し $0.003/1K token $3.00
DynamoDB 1000回書き込み $0.00000125/回 $0.00125

月額合計: 約$4.03(約600円)

🎯 まとめ:面倒ごとはテクノロジーに任せちゃおう

このシステムにより実現できること:

生産性向上: altタグ作成時間をゼロに短縮
品質向上: AIが生成する自然で読みやすい説明文
SEO効果: 検索エンジンが理解しやすい適切なalt属性
アクセシビリティ: 視覚障害者の方への情報提供
運用コスト: 月数百円程度の低コスト運用

NEXT STEP:
まずは小さな画像から試してみて、徐々に本格運用に移行することをおすすめします!
写真はうまく反応できますが、システム構成図やグラフなどはまだ読み込むことが難しい状態です。
スクリーンショットなどを多く貼るような記事では改善の余地があるかもしれません。
慣れてきたら、上記の発展アイデアにもチャレンジしてみてください!

この記事が、あなたのブログ運営効率化の参考になれば幸いです!
ぜひ皆さんも試してみてください!

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?