約1時間でAzure FunctionsとChatGPT APIを使った簡易のBotを作成してみた

AI時代の到来

株式会社ジェイテックジャパン CTOの高丘 @tomohisaです。この半年、それもこの数ヶ月でAIによるクリエイティブな作業のアシストのための機能が多数リリースされています。その中でも文章やプログラムを作成するChatGPTは、直接私たちプログラマーに役立つツールとなっています。
ChatGPTは他にも以下の点にも活用できそうです。

  • アイデアの整理やブレーンストーミングの際やそれに関して定義を聞く
  • メリット、デメリットを整理したりする

https://openai.com/blog/introducing-chatgpt-and-whisper-apis

この記事の執筆日の前日の、2023年3月1日に、OpenAIからChatGPTとWhisper APIが発表されました。これをSlackのチャットに導入したら色々便利だろうと考え、導入してみました。

ChatGPT Botの仕様

今回作成するChatGPT BOTは以下のことができることとします。

  • Slackにアプリとして追加可能
  • 各チャンネルに追加して、 @chatgptbotを付けて質問を送ったら、スレッドを作って返信する
  • OpenAIのChatGPT API "gpt-3.5-turbo"を使用する
  • スレッド内でさらに質問したらそのスレッド内に返信する
  • 複数の質問でコンテキストを理解した返答は不要(それが必要な場合はWebで各自が行う)

これにより、以下の利点があると感じました。

  • 他の人の質問が見えて、ディスカッションできる。また勉強になる
  • Slackは仕事中に開いているので、Webに行くより簡単に使用でき、見返しやすい
  • Slackだと、後から参照しやすい

ChatGPT botの技術仕様

Botの作り方は色々ありますが、以下の方法で作成します。

  • Slackで、アプリを作成する
  • Slackアプリの、Event Subscriptionでbotへのメンションを購読する
  • Azure FunctionのHTTPトリガーを使用する
  • OpenAIのAPIトークンを使用して、質問の答えを取得する
  • SlackアプリのIncoming Webhooksの機能を使用して、返信をポストする

以下の点を駆け足ですが具体的に解説していきます。

ChatGPT botの作成方法

https://zenn.dev/nix/articles/62d342b3e6d026

https://qiita.com/youtoy/items/b3e2e462029bf40f8a1a

上記のページを参考にさせていただきました。ありがとうございます。Azure Functionsで作成しているため、調整を加えています。

Slackでアプリを作成する

https://api.slack.com/apps/

  1. 上記のリンクからCreate New Appでアプリを作成する
  2. From Scratchで作成し、App Nameを入れ、Workspaceはインストールしたいワークスペースを入れる。
  3. アプリを作成したら、OAuth & PermissionsからBot Token Scopesを追加する。
    app_mentions:readとchat:writeを"Add an OAuth Scope"から追加する。
  4. Features - Incoming WebhooksをOnに変更する
  5. Event SubscriptionをONにして、Subscribe to bot eventsから、app_mentionを設定する。
    この後、Request URLを設定する必要があるのですが、Azure Functionを作成してからにします。
    タブを開いたままにして、AzureでFunctionを作成して下さい。

Azure Functions を作成する

https://portal.azure.com/#create/hub

  1. Azureから、[関数アプリ]を作成する
  2. リソースグループ:好きなもの
  3. 関数アプリ名:好きなもの
  4. 公開:コード
  5. ランタイムスタック:Node.js
  6. バージョン:18 LTS
  7. 地域:好きな場所
  8. オペレーションシステム:Windows (Linuxだとのちに面倒でした)
  9. プランの種類:サーバーレス

こちらでAzure Functionsを作成します。

  1. 作成完了後、Azure Funcitonsの「関数」タブから、「作成」をクリックします
  2. (例)ChatGPTFunctionのような名前でFunctionsを作成します。
  3. 開発環境:ポータルでの開発
  4. テンプレート:HTTP Trigger
  5. 新しい関数:好きな名前
  6. Authorization Level:Function
  7. [作成]ボタンで作成します。
  8. 関数の中に行って、[関数のURLを取得]をクリックします。
  9. 関数の「コードとテストに」以下のコードを入力する
const { WebClient } = require('@slack/web-api');
const { Configuration, OpenAIApi } = require("openai");
const openaiConfig = new Configuration({
  apiKey: process.env.OPENAI_API_KEY,
});
const openaiClient = new OpenAIApi(openaiConfig);

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');
    context.log(req.body);
    context.log(process.env.OPENAI_API_KEY);
    
    const token = process.env.SlackBotToken;
    const slackClient = new WebClient(token);
    const body = eval(req.body);
    if (body.challenge) {
        context.res = {
            body: body.challenge
        };
        return;
    }
    // リトライされた時は何行わずに終了する
    if (req.headers['x-slack-retry-num']) {
        return { statusCode: 200, body: JSON.stringify({ message: "No need to resend" }) };
    }

    const event = body.event;
    // Check if the event is a mention
    if (event.type === 'app_mention') {
        try {
            const cleanMessage = event.text.replace(/<@[^>]+>/g, '');
            const openaiResponse = await createCompletion(cleanMessage);
            // Construct the message text for the bot's reply
            const replyText = openaiResponse;

            // Use the WebClient to send the reply message
            await slackClient.chat.postMessage({
                channel: event.channel,
                text: replyText,
                thread_ts: body.event.thread_ts || body.event.ts
            });

            return { statusCode: 200, body: JSON.stringify({ message: openaiResponse }) };
            } catch (error) {
                console.error(`Error sending message: ${error}`);
        }
    }
    context.res = {
        status: 200
    };
};

async function createCompletion(text) {
    try {
        const response = await openaiClient.createChatCompletion({
          model: "gpt-3.5-turbo",
          messages:[{role: "user", content: text}],
        });
        console.log('openaiResponse: ', response);
        return response.data.choices[0].message.content;
    } catch(err) {
        console.error(err);
    }
}
  1. npmの設定をする
    Azureの関数を開き、「開発ツール」のセクションに「コンソール」というセクションがあるため、ここでnpmのパッケージをインストールする
c:\home\site\wwwroot> npm i @slack/web-api
c:\home\site\wwwroot> npm i openai

上記の2つのコマンドを実行します。これによりnpmのパッケージがインストールされます。

  1. Slackのアプリ設定で[Install App]から、[Install to Workspace]ボタンを押し「Bot User OAuth Token」をコピーする

  2. 構成からアプリケーション設定を追加する。
    Azureの「設定」ー「構成」ー「アプリケーション設定」ー「新しいアプリケーション設定」新規の設定を追加する。
    名称:SlackBotToken
    値:上記でコピーしたBot User OAuth Token

  3. 構成からOPENAI_API_KEYを設定する

https://platform.openai.com/account/api-keys

上記のページから[Create new Secret Key]をして、コピーする。
Azureの「設定」ー「構成」ー「アプリケーション設定」ー「新しいアプリケーション設定」新規の設定を追加する。
名称:OPENAI_API_KEY
値:上記でコピーしたOpenAI Secret Key
を設定する。

  1. AzureのBotの関数からURLの設定をコピーして、Slack Appに設定する。
    https://********.azurewebsites.net/api/chatGPTFunctions?code=****** のようなリンクをコピーする。
    上記のリンクをSlackのEvent SubscriptionのRequest URLに貼り付ける。
    Slack APIのEvent Subscription - Enable Events (On)にして、Request URLに上記のAzureのBotのURLを貼り付ける。
    Securityコードが入っていてOK(Slackからの情報はPOSTで送信される)

  2. Verifyを行い、正しく動作することを確認

上記でアプリが動作するはずです。

Slackから @chatgptbot宛にメッセージを送ると返事が返ってこれば成功です。

デバッグの方法

今回の方法では、 ブラウザ上でNode.jsを使用して、Functionsを作成したため、動作確認をAzure上で行います。

モニターの「呼び出し」タブを使用する

関数内の「モニター」に呼び出しの結果が表示されます。
エラーの詳細、npmのエラーなどをみて調整ができます。
このページは実行して5分くらい追加に時間がかかる場合もあるので気長に待ちます。

モニターの「ログ」タブを使用する

ここでは、ログに接続して、応答が早くコンソールの結果を見ることができます。わからない内容がある場合は、コードからログを吐き出してデバッグ可能です。

ChatGPTでこの機能をどれだけ作成できたか

このAzure Functionを作るにあたり、ChatGPTを使って色々質問して作成しようと試みてみました。かなり参考になる情報を返してくれてヒントになる情報が返ってくるので、とても助かりました。
しかしAzureやSlackの設定の部分に関しては、そのまま行おうとしても、該当するメニューがなくて類似のメニューを探すなどの作業が多々ありました。Azure Function, SlackやNode.jsのことをわからない人がいきなり作業してできるかと言えると、少し難しいと感じます。
結局のところ、開発者の技能やデバッグスキルに影響されると感じました。
結局はドキュメントを読んだり、ZennやQiitaのサンプルを見たりすることが一番役に立ちました。

結論

駆け足で画像もなしで振り返りましたが、疑問点がありましたら、コメントなどで教えて下さい。できるだけ答えたり画像を貼って記事を更新いたします。

Slack上でChatGPTを実際に使ってみたところ、コーディングというより、アイデアの整理にとても役立つと感じました。他の人の質問を見てそれからアイデアを議論したりしやすくなりますね。

注意点としてはこれはちょっと理由がわからないのですがAPIで質問した時より、OpenAIのサイトで質問した方が長く詳細な返答となることがありました。 渡すオプションなども確認してみます。

ChatGPTなどのAI技術はAI専門家でなくても簡単に使えるようになってきました。ちょうどiPhoneがリリースされて、皆がアイデアをアプリにして行った時のような高揚感を感じます。
ここまでAPIが整備されると、AIの理解力というより、アプリケーションとしてまとめる力が生きるようになるので、わたしたち開発者が色々なことをできるようになったのはとても楽しみです。
私たちも便利に使えるようになったものをどんどん活用して、アプリケーション化していきたいと考えています。

ジェイテックジャパンブログ

Discussion