APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

【AWS】AWS Lambda + ChatGPT でS3オブジェクトの自動タグ付けを実現する (Terraformコード付き)

はじめに

こんにちは、クラウド事業部の葛城です。

今回は、AWS Lambdaを活用してS3にオブジェクトを配置した際に、ChatGPTを活用して自動で内容を分析してタグ付けするシステムを構築しました。

AWS LambdaとAmazon S3を初めて触る方や、コードを書いて少し格好良くシステムを構築したいAWS初学者向けの内容になります。

GitHubでコードを公開しています。

github.com

こだわったポイントとしては、ChatGPTのAPIを試してみたかったので、s3のタグ生成の機能として活用しました。
また、AWSのインフラストラクチャをTerraformを使ってコード化したので、IaCにする際のTipsやAWSの IaCに興味ある方の参考になればと思います。

目次

1. AWSサービスの概要

AWS Lambda

AWS Lambdaは、サーバーレスコンピューティングサービスであり、アプリケーションコードを実行するためのサーバーのプロビジョニングや管理を不要にし、イベントに応じてスケーラブルにコードを実行できるAWSのサービスです。

aws.amazon.com

Amazon S3

Amazon S3(Simple Storage Service)は、AWSのオブジェクトストレージサービスであり、データの安全な格納と効率的な管理を提供します。
S3は高い耐久性、可用性、スケーラビリティを備え、ファイル、画像、ビデオ、バックアップなどあらゆる種類のデータをクラウドで保存およびアクセスするために使用されます。

aws.amazon.com

2. 自動タグ付けアプリケーション

自動タグ付けアプリケーション、以下の要素から構成されています。

  1. S3バケット - ファイルのアップロード用ストレージ
  2. AWS Lambda - ファイルアップロードイベントを検知し、タグ付けプロセスを実行。ここではPythonのコードを実行
  3. ChatGPT API - ファイルの内容を解析し、適切なタグの候補を生成

3. 事前にやるべきこと

terraformの values.yaml にAPI KEYなどの必要な情報を追記します。
※ Terrafomの実行には、適切なAWSのIAMユーザーとアクセスキーの発行が必要になります。
※ AWS Lambdaの中で、ChatGPTのOpenAIのAPIも利用しているのでAPI 取得する必要があります。

variable "access_key" {
  default     = "IAMで作成したアクセスキー"
}

variable "secret_key" {
  default     = "IAMで作成したシークレットキー"
}

variable "openai_api_key" {
  default     = "OPENAIのAPI KEY"
}

variable "upload_bucket" {
  default     = "アップロード用S3バケット名"
}

4. Terraform資材化

Tips

  • AWS Lambdaの処理が3秒を超えるような場合は、timeout値を設定した上で構築が必要
    • デフォルト では 3秒でタイムアウトになるので、今回のような処理はタイムアウトが発生します。
resource "aws_lambda_function" "content_generator" {
  function_name    = "content_generator"
  filename         = "lambda_function_payload.zip"
  source_code_hash = filebase64sha256("lambda_function_payload.zip")
  role             = aws_iam_role.lambda_role.arn
  handler          = "lambda_function.lambda_handler"
  runtime          = "python3.10"
  timeout          = 60 # タイムアウト値を設定


  • AWS Lambdaで利用する関数コードのzipファイルは、terraformのarchive_fileを設定すると便利
    • アーカイブする資材(pythonのコードなど)を編集して再度ZIP化する手間が省けます。
# Pythonモジュールとスクリプトを格納したディレクトリをzipファイル化
data "archive_file" "lambda_function_payload" {
  type        = "zip"
  source_dir  = "python"
  output_path = "lambda_function_payload.zip"
}

Terraformを実行する際に、ZIPファイルとアーカイブフォルダの内容を比較し、差分がある場合にはZIPファイルを更新してくれます。

導入手順

Terraformで IaC化しているため、構築は簡単です。
Githubからコードを取得して、terraformコマンドを実行します

# 初期化
terraform init
# 構築内容確認
terraform plan
# 構築
terraform apply

環境削除の場合は、S3バケット内のオブジェクトをすべて削除後、以下で一括削除できます

terraform destroy

5. ChatGPTでタグ生成

ここではPythonで ChatGPTのAPIを実行しています。

ChatGPTで、ファイルの内容を解析して、適切なタグを生成してます。
解析可能なファイルの種類は、テキストベースの html, markdown, pdf, txt のみです。

openaiモジュールをインポートして、api_keyを設定。

import openai

# OpenAIのAPIキーを設定
openai.api_key = os.getenv("OPENAI_API_KEY")

promptに実行してもらいたい内容を定義して、OpenAIのAPIを実行できます。
タグ生成なので、以下の様なプロンプトを実行してます。

# プロンプト文: 出力は'[#tag1, #tag2]'の形式で返却してください。また、タグの値は英数字のみ(日本語は英語に直すこと)。以下の文章のタグをいくつか生成してください。: (ChatGPTの命令文については、考慮の余地あり。)
prompt = "Output should be returned in the format '[#tag1, #tag2]'. However, only alphanumeric characters should be used (Japanese tags should be translated into English). Please generate several tags for the following sentence. :\n" + file_content[:5000]
# CahtGPTでプロンプト文を実行
response = openai.Completion.create(engine="text-davinci-003", prompt=prompt, temperature=0.2, max_tokens=200)

6. S3 自動タグ付け 実行例

S3にオブジェクトのアップロードイベントを検知して、AWS Lambdaが実行されます。

aws cliで、sample.mdをs3にアップロードしてみます。

$ aws s3 cp sample.md s3://${UPLOAD_BUKET}/test/sample.md
upload: .\sample.md to s3://${UPLOAD_BUKET}/test/sample.md

aws cliでタグが付与されているか確認します。
(付与されたタグはAWS マネジメントコンソールの画面からでも確認可能です)

$  aws s3api get-object-tagging --bucket ${UPLOAD_BUKET} --key test/sample.md
{
    "TagSet": [
        {
            "Key": "key1",
            "Value": "AWSLambda"
        },
        {
            "Key": "key2",
            "Value": "AmazonS3"
        },
        {
            "Key": "key5",
            "Value": "ServerlessComputing"
        },
        {
            "Key": "key3",
            "Value": "Terraform"
        },
        {
            "Key": "key4",
            "Value": "ChatGPT"
        }
    ]
}

これでアップロードしたオブジェクトにS3のタグが付与されていることが確認できました。

7. AWS Lambda のデバッグについて

AWS マネジメントコンソールでAWS Lambdaのコードのデバッグが可能ですが、最初はやり方分からず苦戦してました。

上記理由もあり、Pythonを環境があればローカルでも動作確認できるようにしています。

ローカルで実行できると嬉しい側面も多々あります。
- (実行の容易さや実行速度、軽い修正などいちいちlamdba再作成せずすぐに実行できるなど)

AWS Lamdbaのデバッグの説明

AWSマネジメントコンソールからLambdaを開き、content_generatorという名前の関数を選択します。
この画面のテストタブからコードのテストを行うことができます。


コードのデバックには、S3がuploadされたイベントをLambdaに受け取らせないといけないので 以下のテストイベントの画面から、「テンプレート - オプション」の検索窓でs3を調べ s3-putのテンプレートを表示させます。


テスト実行前に、実際にバケットにオブジェクトが登録されている必要があります。

以下のように、イベントJSONを編集して、上の「テスト」ボタンをクリックしてコードのテスト実行ができます。

      "s3": {
        "s3SchemaVersion": "1.0",
        "configurationId": "testConfigRule",
        "bucket": {
          "name": "[yourbucket]]", # 作成したバケット名
          "ownerIdentity": {
            "principalId": "EXAMPLE"
          },
          "arn": "arn:aws:s3:::example-bucket"
        },
        "object": {
          "key": "test%2Fsample.md", # バケットのオブジェクトのkey(パス)
          "size": 1024,

コードの実行に成功していれば、以下のような画面で出力が表示されて確認することができます。


コードや受けっているイベントに問題がある場合は、以下のような画面になるのでエラー出力を参考にコードのデバッグができます。

ローカル実行の説明

LOCAL_DEBUGを有効にすることで、ローカルでもコードの確認ができるようにしてます。

# ローカルデバック用変数 Tureの場合、ローカルのファイルを読み込む
LOCAL_DEBUG = os.getenv("LOCAL_DEBUG", "False") == "True"

ローカルで実行する場合は、事前に変数を定義した上で実行してください。

export OPENAI_API_KEY="<ChatGPTで使用するOpenAPIのApiKey>"
export UPLOAD_BUKET="<S3の保存先のバケット名>"
export LOCAL_DEBUG="True"

感想

今回は、実際にAWS Lamdbaを活用したS3オブジェクトの自動ダグ付けシステムを構築してみました。

Terraform で作成しているので、AWS Lambdaの実行内容(コード)部分を編集することで、比較的手軽に他の自動化システムも構築できるかと思います。

ChatGPTは技術的な疑問やコードの添削・エラー解決などで普段から活用してましたが、今回のようにシステムに組み込むなど様々な可能性を感じました。
タグの提案以外にも面白そうな使い方があると思いますので、思いついたら試していきたいと考えてます。

おわりに

APC は AWS セレクトティアサービスパートナー認定を受けております。

その中で私達クラウド事業部は AWS などのクラウド技術を活用した SI/SES のご支援をしております。

https://www.ap-com.co.jp/service/utilize-aws/

また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。

www.ap-com.co.jp

本記事の投稿者: 葛城
AWSを活用したインフラ系のご支援を担当しています。