Why not login to Qiita and try out its useful features?

We'll deliver articles that match you.

You can read useful information later.

6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Serverless Framework + AWS LambdaでのChatGPT APIの作成方法(github actionsでの自動deploy)

Last updated at Posted at 2023-10-02

こんにちは。プログラミングスクールHappiness Chainでメンターをしているryoです。

今回、Pyton on Django + Next.jsのアプリにて、ChatGPTを機能として盛り込むため、serverless framework + AWS Lambdaにて、ChatGPT APIを作成しましたのでそちらの手順を紹介します。

serveless frameworkのプロジェクトを作成

※Node.jsとServerless Frameworkをインストールしていない場合はインストールします。

sls create --template aws-python3 --name chatgpt-api --path chatgpt-api

言語はpythonのため、テンプレートはaws-python3を使用します。
上記実行にて、handler.pyとserverless.ymlが含まれたディレクトリが作成されます。

serverless.ymlを編集

最終的な内容は以下の通りです。

serveless.yml
service: chatgpt-api
frameworkVersion: "3"

provider:
  name: aws
  runtime: python3.9
  stage: ${opt:stage, 'prod'}
  region: ${opt:region, "ap-northeast-1"}
  timeout: 180
  layers:
    - Ref: PythonRequirementsLambdaLayer

functions:
  get_text:
    handler: handler.chatgpt
    url:
      authorizer: aws_iam
      cors:
        allowCredentials: true
        allowedHeaders:
          - Content-Type
          - Authorization
        allowedMethods:
          - POST
        allowedOrigins:
          - http://localhost:3000
          - https://xxxxxx.com
        exposedResponseHeaders:
          - Special-Response-Header
        maxAge: 6000
custom:
  pythonRequirements:
    dockerizePip: true
    zip: true
    layer: true
plugins:
  - serverless-python-requirements

ChatGPTに利用するoepnaiのライブラリは重いため、serverless-python-requirementsというプラグインを使用します。
こちらを使用することで、外部ライブラリを関数に含めずデプロイできます。

custom:
  pythonRequirements:
        # docker上にライブラリをインストールする、LambdaサーバのOSに依存しなくなる
    dockerizePip: true
    # ライブラリの圧縮
    zip: true
    # 依存ライブラリのレイヤー化
    layer: true

関数を外部から呼び出すために、選択肢として、以下の通りです。

  • API Gateway

    • メリット
      • 複数関数ある(REST API)の場合、ひとつのhostnameから各関数にpathを割り振れる
      • ドメインをカスタマイズできる
    • デメリット
      • timeoutがmax30秒(stepfnuctionsを使えば回避できるが、構築するのにやや面倒。リクエストを2回送る必要あり、front側も一工夫必要。)
  • Funtion URL

    • メリット
      • タイムアウトがmax3000秒
      • 構築が楽
    • デメリット
      • ドメインをカスタマイズできない

今回chatgptへのinput、outputの文量が1000文字以上見込まれ、処理が30秒を超えるため、Function URLを採用。
認証として、IAMを使用。
corsも設定。

functions:
  chatgpt:
    handler: handler.chatgpt
    url:
      authorizer: aws_iam
      cors:
        allowCredentials: true
        allowedHeaders:
          - Content-Type
          - Authorization
        allowedMethods:
          - POST
        allowedOrigins:
          - http://localhost:3000
          - https://xxxxxxxx.jp
        exposedResponseHeaders:
          - Special-Response-Header
        maxAge: 6000

pluginをインストール

serverless-python-requirementsを使用するためpluginをインストールします。

serverless plugin install -n serverless-python-requirements

requirements.txtを作成

requirements.txt
openai

handler.pyを編集

handler.py
import json
import os

import openai

openai.api_key = os.environ["OPENAI_API_KEY"]


def chatgpt(event, context):
    body = json.loads(event["body"])
    if "user" not in body:
        return {
            'statusCode': 400,
            'headers': {
                "Access-Control-Allow-Headers": "Content-Type",
            },
            'body': "Arguments Error: user is required"
        }
    messages = []
    messages.append({"role": "user", "content": body["user"]})

    if "system" in body:
        messages.append({"role": "system", "content": body["system"]})

    if "assistant" in body:
        messages.append({"role": "assistant", "content": body["assistant"]})

    response = openai.ChatCompletion.create(
        model="gpt-4",
        messages=messages,
    )

    return {
        'statusCode': 200,
        'headers': {
            "Access-Control-Allow-Headers": "Content-Type",
        },
        'body': json.dumps({"text": response["choices"][0]["message"]["content"]})
    }

AWS Configureの設定

aws configure
AWS Access Key ID:
AWS Secret Access Key:
Default region name:
Default output format:

deploy

sls deploy

環境変数の設定

上記コマンドにてAWS Lambdaに関数が作成されるので、
そちらに環境変数を設定します。
スクリーンショット 2023-10-02 12.29.39.png

Postmanで動作確認

Authoriztion TypeとしてAWS Signatureを選択。
AccessKeyとSecretKeyはLambdaアクセス用に作成したIAMを設定。
AWS RegionとSevice Nameを設定。

スクリーンショット 2023-10-02 11.41.19.png

bodyとして以下のように記述することで、以下のようなレスポンスを得られます。

スクリーンショット 2023-10-02 11.42.58.png

github actionsでの自動deploy

serverless/github-action使用でのdeployにて不明なエラーがあったため、
github actions内でserverlessをインストールしてデプロイするようにしています。
デプロイ前に、AWSの認証をしており、githubのsecretsに設定する必要があります。
また、pluginを使用しているので、pluginのインストールもする必要があります。

.github/workflows/deploy-serverless.yml
name: Deploy main branch

on:
  push:
    branches:
      - main

jobs:
  deploy:
    name: deploy
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    strategy:
      matrix:
        node-version: [16.x]
    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-region: ap-northeast-1
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      - name: serverless config
        run: npx serverless config credentials --provider aws --key ${{ secrets.AWS_ACCESS_KEY_ID }} --secret ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      - name: serverless install
        run: npm i -g serverless
      - name: serverless python requirements install
        run: serverless plugin install -n serverless-python-requirements
      - name: serverless deploy
        run: serverless deploy
6
2
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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?