AWS Lambdaの関数URLを利用した時間のかかるOpenAI APIの非同期化

動機

最近流行のChatGPT、最近GPT4が公開されてより一層流行の兆しをみせています。 GPT2のころは色々試していたのですが、重い腰をあげて最近公開されたOpenAIのAPIを利用する環境を作ろうと思いたちました。 その前段として、SlackのスラッシュコマンドからLambdaを叩いてOpenAI APIを叩く環境を作ろうとしました。

Lambda関数URL

Lambdaで実装するにあたって、API呼び出しにはAPI Gatewayが必要なのかと覚悟していたのですが、知らぬ間にLambda単体でhttpsのエンドポイントを生やすことができるようになったようです。 機能は少なくシンプルなので用途にあった場合に利用を候補に入れるとよさそうです。

Lambda 関数 URL

Slackのスラッシュコマンドの仕様

一通りLambda関数(Python)とSlackスラッシュコマンドの連携を行うところまで実装し、動作テストを行っている時に、スラッシュコマンドの以下の制限にようやく気付きました。

サーバーからのリクエストに対して 3 秒以内に ack() メソッドで応答する必要があります。

Slack公式-Slackコマンド

OpenAIのAPIは3秒でレスポンスを返すのは難しく、非同期に直す必要性が出てきました。 Slackのスラッシュコマンドは、リクエスト時にresponse_urlを付与してくれており、一定時間内であれば、このエンドポイントにPOSTすることで、Slackへの投稿を行うことができるようになっています。 通しのコードは既に実装済みだったので、これをリクエスト受付関数外部API呼び出し関数に分離することにしました。

構成

以下の画像のような構成にしました。 1つ目の関数でリクエストを受け、必要な項目だけを2つ目の非同期実行Lambda関数に渡します。

リクエスト受付関数

セキュリティ

セキュリティの設定をNoneにしています。このままでは何の検証もしないと危険なので、きちんと検証をしましょう。今回はSlackAppのリクエスト検証の仕組みを利用しました。

関数設定

  • タイムアウト: 3秒(Slackスラッシュコマンドタイムアウト)
  • 送信先: 「外部API呼び出し関数」(正常時 / 非同期)
  • 関数URL: ON(認証タイプ:None)

コード

以下が大まかな流れ。 このLambda関数からLambdaを非同期で呼び出し、すぐにレスポンスを返して終了してしまいます。 今回はSlackに「処理中...」を表示するためにreturn文字列を指定しています。

次の外部API呼び出し関数を呼び出し、Payloadも渡します。 今回は処理種別、本文、response_urlを入れています。

外部API呼び出し関数

関数設定

こちらは関数URLはOFFの普通のLambda関数で良い。

  • タイムアウト: 2分(外部APIに合わせて最適な長さにする)

コード

前のLambdaから受けた情報をeventから取得し、外部API(OpenAI API)を叩きます。

最後にresponse_urlに対してPOSTします。

Slackに結果が表示されます。

author icon
  • IwaKen (moru3)
  • 札幌在住Webエンジニア。色々書いていきます。Tech系、ゲーム、映画、Youtubeなど多岐にわたって触れていきます。
  • twitter mark
  • youtube mark