概要
2023年3月1日に一般公開されたChatGPT API(gpt-3.5-turbo)をSlackから使ってみました。
今まで最も性能の高いモデルだったGPT3(text-davinci-003) と比較すると、
API経由で入力されたデータはデフォルトで学習しないので情報漏洩のリスクが軽減し、
(ただし、データ自体はOpenAI社が30日間保存している)
利用価格は10分の1(英語の場合で約4000文字または750語あたり約0.27円)に削減されたようです。
システム構成
Slack/AWS Lambda/ChatGPT API
の3つです。
SlackからのリクエストをAWS Lambdaに送信する場合、API GatewayとAWS Lambdaを組み合わせてAPIエンドポイントを作成し、API Gatewayに認証/承認を設定することで安全なアーキテクチャを実現できそうでしたが、
今回はお手軽にChatGPT APIを利用したいので割愛します。
Slack(Slack App)
テキストをAWS Lambdaに送信する
AWS Lambda
Slackからテキストを受信し、ChatGPT APIにテキストを送信し、その回答をSlackに投稿する
ChatGPT API(gpt-3.5-turbo)
AWS Lambdaからテキストを受信し、回答を返却する
つくりかた
1. Slack AppのTokenを発行
1-1. Slack Appを作成
- https://api.slack.com/apps へアクセスする
-
Create New App → From scratch
を押下する - アプリ名とワークスペースを入力して
Create App
を押下する
アプリ名はなんでもOKですが私は「Chat GPT Service」にしました。
1-2. Slack botを設定
App Home
を押下し、Slack botの名前を設定する。
名前はなんでもOKですが私は「Chat GPT」にしました。
1-3. Slack(Slack App)のTokenを取得
1. OAuth & Permissions
を押下し、以下のScopesを設定する
2. Install to Workspace
を押下し、ワークスペースにインストールする
3. Tokenが発行されるのでBot User OAuth Token
のTokenを保持する
2. OpenAI APIのキーを発行
- OpenAIのAPI keysにアクセスする
-
+ Create new sercret key
を押下する -
API key generated
にAPIキーが発行されるので保持する
※有料版を利用する場合の注意点
私は無料版を利用していますが、有料版を利用する場合、
想定外の高額請求は避けたいので利用料制限を設定しておくことをお勧めします。
左側メニューBilling
のUsage limits
内のHard limit
(利用料が一定を超えたらAPIの利用停止)で設定できます。
3. 疎通用のAWS Lambdaを作成
3-1. 関数を作成
1. AWS Lambdaで関数を作成する
- ランタイム設定:Node.js 18.x
- アーキテクチャ:x86_64
2. タイムアウトを設定する
- タイムアウト:とりあえず3分
実運用では状況に応じて調整する必要があります。
3-2. 関数URLを設定
今回、認証タイプはNONEにする。
実運用には向かないです。
3-3. 疎通用のコードを作成
Slack Appと疎通を行うためのコードを作成する
export const handler = async (event) => {
let json = JSON.stringify(event.body);
return { statusCode: 200, body: json };
};
4. Slack Appのイベントを設定
4-1. Event Subscriptionsを設定
Slack AppのEvent Subscriptions
を押下してEnable EventsをONにし、
前項「3-2. 関数URLを設定」で作成したAWS Lambdaの関数URLを設定する。
Verified
になれば疎通成功です。
4-2. Subscribe to bot eventsを設定
Subscribe to bot eventsを以下のように設定し、Save Changes
を押下する
5. AWS Lambdaのレイヤーを作成
5-1. nvmを導入
ローカルのターミナルで以下のコマンドを実行する。
nodejsはLambdaで利用するバージョンに合わせました。
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
. ~/.nvm/nvm.sh
nvm install v18.13.0
5-2. パッケージを生成
ローカルのターミナルで以下のコマンドを実行する。
パッケージのバージョンは2023年3月1日時点で最新のものにしました。
mkdir nodejs
cd nodejs
npm install @slack/web-api
npm install openai
npm list @slack/web-api
# @slack/web-api@6.8.1
npm list openai
# openai@3.2.1
zip -r nodejs.zip .
5-3. レイヤーを作成
先ほどローカルで生成したnodejs.zip
をレイヤーにアップロードし、作成する
6. ChatGPT用のAWS Lambdaを作成
6-1. 環境変数を設定
前項「3. 疎通用のAWS Lambdaを作成」で作成済みのLambdaに、
「1. Slack AppのTokenを発行」と「2. OpenAI APIのキーを発行」で保持したTokenとキーを
SLACK_BOT_TOKEN
とOPENAI_API_KEY
にそれぞれ設定する
6-2. レイヤーを追加
前項「5-3. レイヤーを作成」で作成したレイヤーを関数に追加する
6-3. コードを変更
前項「3-3. 疎通用のコードを作成」で作成したコードを以下に変更する
import { WebClient } from '@slack/web-api';
import { Configuration, OpenAIApi } from 'openai';
const slackClient = new WebClient(process.env.SLACK_BOT_TOKEN);
const openaiConfig = new Configuration({ apiKey: process.env.OPENAI_API_KEY });
const openaiClient = new OpenAIApi(openaiConfig);
export const handler = async (event, context) => {
if (event.headers['x-slack-retry-num']) {
return { statusCode: 200, body: JSON.stringify({ message: 'No need to resend' }) };
}
const body = JSON.parse(event.body);
const text = body.event.text.replace(/<@.*>/g, '');
const openaiResponse = await createCompletion(text);
const thread_ts = body.event.thread_ts || body.event.ts;
await postMessage(body.event.channel, thread_ts, openaiResponse);
return { statusCode: 200, body: JSON.stringify({ success: true }) };
};
async function createCompletion(text) {
try {
const response = await openaiClient.createChatCompletion({
model: 'gpt-3.5-turbo',
messages: [{role: 'user', content: text}],
});
return response.data.choices[0].message?.content;
} catch(err) {
console.error(err);
}
}
async function postMessage(channel, thread_ts, text) {
try {
let payload = {
channel: channel,
thread_ts: thread_ts,
text: text,
as_user: true,
};
await slackClient.chat.postMessage(payload);
} catch(err) {
console.error(err);
}
}
つかいかた
- Slackのチャンネルに、作成したSlack Appを追加する
- botへのメンション付きでテキストを送信する
- botからスレッドに回答が届く