Techfirm Cloud Architect Blog

テックファーム株式会社クラウドインフラグループのブログ

【初心者向け】AWS LambdaとOpenAI APIを使って文章の要約機能を作成する方法

はじめに

本記事では、AWS LambdaとOpenAI APIを組み合わせて簡単な文章要約ツールを作る方法をご紹介します。
Lambda関数をテスト実行すると文章の入力が求められ、それをOpenAI API経由で要約するという、仕組みとしては非常にシンプルなものです。

Architecture

準備するもの(前提条件)

本記事では以下が準備されていることを前提としています。

  • AWSアカウント

    AWS Lambdaを動作させるアカウントが必要になりますので、はじめての方はAWSアカウント作成の流れにしたがってアカウントを作成してください。

  • OpenAIアカウントとAPIキー

    OpenAIのAPIキーと、APIキーを発行するためにOpenAIアカウントの作成が必要になります。
    OpenAIのアカウント作成はOpenAI platformで行えます。
    APIキーの取得はアカウント作成後にapi-keysページで行えます。
    「+ Create new secret key」をクリックし、名前を入力して「Create secret key」をクリックすると、APIキーが発行されます。
    発行されたAPIキーは作成時にしか知ることができず、後から使用しますので確実にメモに残してください。

    CreateApiKey

    なお、OpenAI APIキーを使用するには別途クレジット追加をする必要があります。
    クレジットの追加方法は以下の手順をご確認ください。

    How can I set up prepaid billing?

Lambda関数の作成・設定

Lambdaレイヤーの設定

画面上部にあるアイコンをクリックし、CloudShellを起動します。

CloudshellStart

CloudShellを起動したらopenaiモジュールのインストールを行います。
AWS LambdaでOpenAI APIを呼び出すには、openaiというモジュールをLambdaレイヤーで用意する必要があります。
CloudShell上で以下のコマンドを実行し、openaiモジュールのインストールとzip化を行います。

$ python3 -m venv openai_env
$ source openai_env/bin/activate
$ pip install openai==0.28
$ mkdir -p python/lib/python3.9/site-packages/
$ cp -r openai_env/lib/python3.9/site-packages/* python/lib/python3.9/site-packages/
$ zip -r openai_layer.zip python

CloudShellはAmazon Linux 2023に基づいており、デフォルトでPython3.9がプリインストールされています。
そのため今回の手順ではPython3.9を使用していますが、もし別バージョンのPythonを使用したい場合は、別環境でzipファイルの作成を行なってください。

また上記コマンドではopenaiバージョンを0.28に固定していますが、これは後続の手順で作成するLambda関数を実行した際に以下のエラーが発生するためです。

[ERROR] APIRemovedInV1: 

You tried to access openai.Completion, but this is no longer supported in openai>=1.0.0 - see the README at https://github.com/openai/openai-python for the API.

You can run `openai migrate` to automatically upgrade your codebase to use the 1.0.0 interface. 

Alternatively, you can pin your installation to the old version, e.g. `pip install openai==0.28`

このエラーは、旧APIであるopenai.Completionを使用しようとしたがバージョン1.0.0以降では廃止されたため使用できない、というものです。
対処法として、openai migrateコマンドでソースコードをバージョン1.0.0以降用のものに変換するか、もしくは古いopenaiバージョン0.28に固定するか提示されています。
今回は一時的な検証用として使用するため、古いバージョンに固定しました。

zipファイルの作成までできたら、「アクション」→「ファイルのダウンロード」をクリックします。

FileDownload

「個別のファイルのパス」には以下のパスを入力し、「ダウンロード」をクリックします。

/home/cloudshell-user/openai_layer.zip

これでローカルに「openai_layer」というzipファイルがダウンロードされました。
このzipファイルは、Lambdaレイヤー作成時にアップロード対象ファイルとして使用します。

次にLambdaレイヤーを作成します。
AWS Lambdaサービスの画面に移動し、サイドメニューの「レイヤー」をクリックします。

LayerSetting

レイヤーの管理画面に移動したら、「レイヤーの作成」をクリックします。

LayerCreate

それぞれ以下の設定値を入力し、「作成」をクリックします。

項目 設定値
名前 openaiapi-test-layer
アップロード方法 .zipファイルをアップロード(openai_layer.zip)
互換性のあるアーキテクチャ x86_64
互換性のあるランタイム Python3.9

※記載がない項目はすべてデフォルトで作成

Lambda関数の作成

サイドメニューの「関数」に移動し、「関数の作成」をクリックします。

LambdaCreate

それぞれ以下の設定値を入力し、「関数の作成」をクリックします。

項目 設定値
関数の作成 一から作成
関数名 openaiapi-test
ランタイム Python 3.9
アーキテクチャ x86_64

※記載がない項目はすべてデフォルトで作成

なお、タイムアウトはデフォルトで0分3秒となっているため、関数作成後に1分0秒に変更してください。
タイムアウトが短すぎるとレスポンスに時間がかかった際に処理が途中で終了してしまう可能性があります。

ソースコードには以下をそのまま貼り付けてください。

import os
import json
import openai

# OpenAI APIキーの設定(環境変数「OPENAI_API_KEY」から自動取得)
openai.api_key = os.getenv('OPENAI_API_KEY')

def lambda_handler(event, context):
    """
    AWS Lambdaのエントリーポイント。
    入力された文章をOpenAI APIを使って要約し、結果をJSON形式で返す。
    """
    
    # イベントから要約対象のテキストを取得(キーが存在しない場合は空文字列)
    original_text = event.get('text', '')

    # テキストが空の場合は400エラーを返す
    if not original_text:
        return {
            'statusCode': 400,
            'body': json.dumps({'error': '要約する文章が入力されていません。'}, ensure_ascii=False)
        }

    try:
        # OpenAI APIにリクエストを送信
        response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo",  # 使用するモデル
            messages=[
                {"role": "system", "content": "与えられた文章を簡潔に要約してください。"}, 
                {"role": "user", "content": original_text}
            ],
            temperature=0.3,  # 出力のランダム性を低めに設定(0.0 〜 2.0)
        )

        # APIのレスポンスから要約結果を取得
        summary = response['choices'][0]['message']['content'].strip() if response['choices'] else "要約に失敗しました。"

        # 成功した場合は200ステータスコードとともにJSON形式でレスポンスを返す
        return {
            'statusCode': 200,
            'body': json.dumps({'summary': summary}, ensure_ascii=False)
        }

    except Exception as e:
        # 例外発生時(APIエラーやネットワーク問題など)は500ステータスコードを返す
        return {
            'statusCode': 500,
            'body': json.dumps({'error': str(e)}, ensure_ascii=False)  # エラーメッセージをJSON形式で返す
        }

次に先ほど作成したLambdaレイヤーを設定します。
作成した「openaiapi-test」の詳細画面で下にスクロールし、「レイヤーの追加」をクリックします。

LayerAdd

それぞれ以下の設定値を入力し、「追加」をクリックします。

項目 設定値
レイヤーソース カスタムレイヤー
カスタムレイヤー openaiapi-test-layer
バージョン 1

環境変数の設定

OpenAIのAPIキーをLambda関数で使用できるようにします。
今回は検証のためOpenAIのAPIキーをLambdaの環境変数に設定しますが、本番環境で運用する場合はセキュリティの観点からAWS Secrets ManagerやAWS Systems Manager Parameter Storeなどに設定・管理することを推奨します。

AWS Lambdaの「設定」から「環境変数」に移動し、「編集」をクリックします。

EnvironmentalVariables

以下を入力し、「保存」をクリックします。

キー
OPENAI_API_KEY <OpenAIで取得したAPIキー>

動作確認

それでは作成したLambda関数をテスト実行してみます。
作成した「openaiapi-test」の詳細画面で「テスト」に移動し、以下を入力します。

項目 設定値
イベントアクションをテスト 新しいイベントを作成
イベント名 openaiapi-test

※記載がない項目はすべてデフォルトで作成

イベントJSONには要約してもらいたい文章を入力するのですが、今回はWikipediaにあったAWS Lambdaの説明文を入力してみます。
※任意の長文に変更しても問題ありません。

{
  "text": "AWS LambdaはAmazon.comが提供しているAmazon Web Services (AWS) の1つで、イベントの発生に応じてプログラムを実行する環境を提供するクラウドコンピューティングサービスである。2014年11月に提供が開始された。プログラムの実行に必要なサーバなどの環境が予め整えられているため、プログラムを作成して登録するだけで実行できるという特徴がある。同じAWSのサービスであるAmazon EC2は仮想化されたサーバを提供するのに対し、AWS Lambdaはプログラムの実行環境のみを提供するため、管理の手間が省かれるというのも特徴。プログラムの実行に必要なリソースは自動的に計算・割り当てされ、実行時間や回数などに応じて利用料金を支払う従量課金制となっている。また、実行するプログラムについては多数のプログラミング言語に対応している。"
}

入力したら「テスト」をクリックします。
すると以下のレスポンスが返ってきました。

{
  "statusCode": 200,
  "body": "{\"summary\": \"AWS LambdaはAWSが提供するサーバーレスコンピューティングのサービスであり、イベント駆動型のアーキテクチャを採用しています。開発者はインフラストラクチャを管理せずコードを実行でき、使用した分だけ料金が発生します。AWS Lambdaはコスト効率が高く、スケーラビリティに優れており、他のAWSサービスとの統合も容易で、API Gateway、S3、DynamoDBなどと連携してさまざまなサーバーレスアプリケーションを構築できます。\"}"
}

要約前の文字数が383文字に対し要約後は221文字、内容についてもAWS Lambdaの説明が簡潔に述べられており、問題なく要約されました。

考えられる応用例

今回作成したLambda関数を運用中システムに導入する際の活用例を考えてみました。
以下はあくまで一例ですので、参考程度に見ていただければ幸いです。
なお実運用にあたっては、業務における機密情報の取り扱いに十分ご注意ください。

インフラ状況に基づく通知とレポートの生成(Amazon EC2 + Amazon CloudWatch + Amazon SNS + AWS Lambda + OpenAI API)

Amazon CloudWatchで監視しているEC2インスタンスの状態を基に、Lambda関数がOpenAI APIを呼び出してレポートを生成し、システム管理者に通知する構成になります。

たとえば以下では、EC2インスタンスのCPU使用率が90%を超過した場合にシステム管理者に通知が行われるまでのフローを示しています。

Example1

Lambda関数は受け取った検知内容をOpenAI APIに送信し、「CPU使用率が高い状態が続いており、スケールアップを考慮すべきです」といったレポートを受け取り、SNSを通じてシステム管理者に通知します。
通知先としてSlackやMicrosoft Teamsなど、日頃から使用しているコミュニケーションツールを指定することで、発生した事象と生成AIからの提示アクションをリアルタイムでチーム全体に共有できます。

また通知内容を基に、実際にはどういう対応をおこなったのか証跡を残すことで対応の透明性が向上し、過去の対応履歴を振り返ることで、今後の障害対応の改善にも役立ちます。

要約文の生成と保存(Amazon EventBridge + AWS Lambda + Amazon S3 + Amazon SNS + OpenAI API)

ユーザーがS3バケットにアップロードした複数ファイルの要約文を、OpenAI APIを使用して生成し、別のS3バケットに保存する構成になります。
たとえば以下では、S3バケットに保存している営業、運営、マーケティング活動などに関する一定期間分(週次、月次など)の定期レポートの要約文を作成し、別のS3バケット(要約結果保存用S3バケット)に保存するフローを示しています。

Example2

要約結果保存用S3バケットに要約ファイルが保存された際、保存された旨をシステム管理者に通知します。

こちらも通知先としてSlackやMicrosoft Teamsなどを指定することで、チーム全体に要約の作成状況が共有されます。

これによりチームメンバーが現状をすぐに把握できることで、確認や報告の手間を減らすことができますし、要約を起点とした会話やフィードバックが自然と生まれるため、部門間の連携や次のアクションの意思決定もスムーズになります。

注意点とコストについて

AWS Lambdaは「リクエスト数」と「実行時間」で、OpenAI APIは利用したトークン数に基づいて課金されます。
それぞれの最新の料金表は以下を参照してください。

開発や学習目的での利用であればかかるコストはごくわずかですが、本番環境で運用する場合はムダなコストが発生しないように課金状況を常に確認するようにしてください。
また本番環境ではセキュリティの観点から、OpenAI APIキーをAWS Secrets ManagerやAWS Systems Manager Parameter Storeなどで管理することを推奨します。

まとめ

本記事では、AWS LambdaとOpenAI APIを組み合わせて簡単な文章要約ツールを作る方法をご紹介しました。
本記事の手順を参考にし、ご自身で担当されているプロジェクトや業務フローに適した活用方法をぜひ検討してみてください。
実運用にあたっては、費用の管理やAPIキーの保管方法などセキュリティ上の注意点も十分考慮してください。