Azure AI Bot ServiceとAzure OpenAIを使って「生成AIチャットボット」を作ってみる – 第2回:生成AIを使って質問に回答できるようにする
みなさん、こんにちは!
福岡オフィスの青柳です。
「Microsoft Azureで生成AIチャットボットを作ってみる」シリーズの第2回です。
- 第1回: シンプルな「オウム返し」ボットを作る
- (Azure AI Bot Serviceを触ってみる)
- 第2回: 生成AIを使って質問に回答できるようにする ← 当記事です
- (Azure OpenAIを組み合わせてみる)
- 第3回: 社内情報に基づいた回答ができるようにする (公開予定)
- (Cognitive Searchを使ったRAGを組み込む)
前回は、生成AIを使わないシンプルなチャットボットを作成することで、Azure AI Bot Serviceの使い方を理解しました。
今回は、前回作成したチャットボットに「Azure OpenAI」サービスを組み込んで、「生成AIチャットボット」を作成したいと思います。
作業の流れ
今回の作業は、前回の記事で構築した環境の続きとして行います。
- (1) Azure OpenAIをセットアップする
- (2) アプリケーションを生成AIに対応させる
- (3) ローカル環境でアプリケーションをテストする
- (4) Azure環境にアプリケーションをデプロイする
- (5) Azure環境にデプロイしたチャットボットをテストする
(1) Azure OpenAIをセットアップする
Azureポータル画面で「すべてのサービス」を開き、カテゴリ「AI + Machine Learning」にある「Azure OpenAI」をクリックします。
「Azure OpenAI」の画面が開きますので、上部メニューにある「作成」をクリックします。
ウィザード画面に沿って必要な情報を入力して行きます。
項目名 | 設定値 | |
---|---|---|
プロジェクトの詳細 | サブスクリプション | リソース作成先のサブスクリプションを選択 |
リソースグループ | リソース作成先のリソースグループを選択 | |
インスタンスの詳細 | リージョン | Japan East |
名前 | 任意の名前を指定 (例:kumamon-openai ) |
|
価格レベル | Standard S0 |
続いて、ネットワークに関する設定項目を選択します。
項目名 | 設定値 |
---|---|
種類 | インターネットを含むすべてのネットワークがこのリソースにアクセスできます。 |
ここでは、デフォルトの選択のまま次へ進みます。
続いて、リソースの「タグ」を設定する画面になります。
必要に応じてタグの設定を行います。
ウィザードの最後は、設定内容のレビュー画面になります。
内容を確認して、「作成」をクリックします。
リソースの作成中 (デプロイ中) の画面でしばらく待つと、「デプロイに成功しました」と表示されます。
画面下部の「リソースへ移動」をクリックすると、作成されたAzure OpenAIリソースの画面に遷移します。
続けて、Azure OpenAIで使用する「モデル」のデプロイを行います。
上部メニューにある「Azure OpenAI Studioに移動する」をクリックします。
「Azure OpenAI Studio」画面に遷移します。
左側のメニューから「デプロイ」を選択します。
「デプロイ」画面で、上部メニューにある「新しいデプロイの作成」をクリックします。
モデルのデプロイに関する設定を入力します。
項目名 | 設定値 |
---|---|
モデルを選択してください | gpt-4 |
モデルバージョン | 自動更新を既定に |
デプロイ名 | gpt-4 |
コンテンツフィルター | Default |
1分あたりのトークンレート制限 (数千) | 任意の値を指定 (あまり高いとアカウント全体に影響を与えますし、あまり低いと使い辛くなります) |
動的クォータを有効にする | 有効 |
「作成」をクリックします。
デプロイされたモデルが表示されていることを確認します。
これで「Azure OpenAI」サービスの準備は終わりです。
(2) アプリケーションを生成AIに対応させる
Node.jsアプリケーションからAzure OpenAIを利用するために、Microsoftが提供する「Azure OpenAIクライアントライブラリ」をインストールします。
JavaScript 用 Azure OpenAI クライアント ライブラリ | Microsoft Learn
https://learn.microsoft.com/ja-jp/javascript/api/overview/azure/openai-readme
my-chat-botディレクトリへ移動します。
cd my-chat-bot
npm install
コマンドを実行して、アプリケーションのディレクトリに「@azure/openai」パッケージをインストールします。
(-g
オプションを付けないように気をつけてください)
npm install @azure/openai
(私が作業した環境では、パッケージのバージョンは「1.0.0-beta.7」でした)
ここからは、ボットのメイン処理が記述されているbot.js
ファイルの内容を更新していきます。
まず、モジュールインポートの宣言に「@azure/openai」を追加します。
// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. const { ActivityHandler, MessageFactory } = require('botbuilder'); const { OpenAIClient, AzureKeyCredential } = require("@azure/openai");
Azure OpenAIのAPIを呼び出すための「エンドポイント」「APIキー」「使用するモデル (デプロイ名)」を定数宣言します。
const endpoint = 'https://XXXXXXXX.openai.azure.com/'; const apiKey = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'; const deploymentName = 'gpt-4';
「エンドポイント」「APIキー」は、Azureポータルで「Azure OpenAI」リソースの「キーとエンドポイント」画面で確認できます。
「使用するモデル (デプロイ名)」は、Azure OpenAI Studioの「デプロイ」画面で確認できます。
生成AI (Azure OpenAI) を呼び出して質問から回答を生成する処理を、関数「getReply()」として用意します。
const getReply = async (req) => { const messages = [ { role: "user", content: req }, ]; var res = ''; try { const client = new OpenAIClient(endpoint, new AzureKeyCredential(apiKey)); const events = client.listChatCompletions(deploymentName, messages, { maxTokens: 128 }); for await (const event of events) { for (const choice of event.choices) { const delta = choice.delta?.content; if (delta !== undefined) { res += delta; } } } } catch (err) { console.log(err); throw err; } return res; }
チャット形式で回答を生成する場合、「getCompletions」APIを使う方法と「listChatCompletions」APIを使う方法があります。
ただし、GTPモデルの最新バージョンでは「getCompletions」APIは使用できなくなっているので、注意してください。 (今回は「listChatCompletions」APIを使用しています)
チャットボットと会話のやり取りを行う処理を、以下のように更新します。
class EchoBot extends ActivityHandler { constructor() { super(); // See https://aka.ms/about-bot-activity-message to learn more about the message and other activity types. this.onMessage(async (context, next) => { const replyText = await getReply(context.activity.text); await context.sendActivity(MessageFactory.text(replyText, replyText)); // By calling next() you ensure that the next BotHandler is run. await next(); });
42行目で、ボットの返答内容replyText
にセットしている内容を、以下のように変更します。
- 変更前:
const replyText = `Echo: ${ context.activity.text }`;
- 変更後:
const replyText = await getReply(context.activity.text);
変更前は「オウム返し」処理でしたが、変更後は「getReply()」関数を呼び出す処理に変更しています。
最後に、これは無くても構わないのですが、ボットが最初に話すメッセージを「こんにちは、ようこそ!」から「質問をどうぞ!」に変更します。
this.onMembersAdded(async (context, next) => { const membersAdded = context.activity.membersAdded; const welcomeText = '質問をどうぞ!';
アプリケーションコードの変更は以上で全てです。
参考に、更新後の「bot.js」のコード全体を下記に掲載します。
bot.js (クリックすると展開します)
// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. const { ActivityHandler, MessageFactory } = require('botbuilder'); const { OpenAIClient, AzureKeyCredential } = require("@azure/openai"); const endpoint = 'https://XXXXXXXX.openai.azure.com/'; const apiKey = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'; const deploymentName = 'gpt-4'; const getReply = async (req) => { const messages = [ { role: "user", content: req }, ]; var res = ''; try { const client = new OpenAIClient(endpoint, new AzureKeyCredential(apiKey)); const events = client.listChatCompletions(deploymentName, messages, { maxTokens: 128 }); for await (const event of events) { for (const choice of event.choices) { const delta = choice.delta?.content; if (delta !== undefined) { res += delta; } } } } catch (err) { console.log(err); throw err; } return res; } class EchoBot extends ActivityHandler { constructor() { super(); // See https://aka.ms/about-bot-activity-message to learn more about the message and other activity types. this.onMessage(async (context, next) => { const replyText = await getReply(context.activity.text); await context.sendActivity(MessageFactory.text(replyText, replyText)); // By calling next() you ensure that the next BotHandler is run. await next(); }); this.onMembersAdded(async (context, next) => { const membersAdded = context.activity.membersAdded; const welcomeText = '質問をどうぞ!'; for (let cnt = 0; cnt < membersAdded.length; ++cnt) { if (membersAdded[cnt].id !== context.activity.recipient.id) { await context.sendActivity(MessageFactory.text(welcomeText, welcomeText)); } } // By calling next() you ensure that the next BotHandler is run. await next(); }); } } module.exports.EchoBot = EchoBot;
(3) ローカル環境でアプリケーションをテストする
更新したアプリケーションをローカル環境で実行して、「Bot Framework Emulator」を使ってテストします。
現在のディレクトリがmy-chat-botであることを確認して、以下のコマンドを実行します。
npm start
アプリケーションが待ち受け状態になりましたら、「Bot Framework Emulator」を起動します。
Bot URLhttp://localhost:3978/api/messages
を指定して接続します。
何か質問してみましょう。 ちゃんと生成AIが回答してくれましたか?
もし回答してくれない場合は、ここまでの手順や、アプリケーションコードの変更内容を、もう一度見直してみてください。 また、アプリケーションを起動しているターミナル画面に何かエラーが表示されていないか確認してみるのも良いでしょう。
テストが終わりましたら、アプリケーションを「Ctrl+C」で停止しておきます。
(4) Azure環境にアプリケーションをデプロイする
それでは、作成したアプリケーションをAzure環境にデプロイして実行しましょう。
前回 (第1回) で行ったように、App Serviceへのアプリケーションのデプロイは、ローカル環境でAzure CLIを使って行います。
まず、アプリケーションのディレクトリ (エントリポイントであるindex.jsが存在するディレクトリ) へ移動します。
cd my-chat-bot
前回デプロイを行った際に作成したzipファイルが残っている場合は、念のために削除しておきます。
rm ../deploy.zip
アプリケーション資産の一式をzipで圧縮します。
zip -r ../deploy.zip .
圧縮が終わったら、1つ親のディレクトリ (作成されたzipファイルが存在するディレクトリ) へ移動します。
cd ..
App Service (Webアプリ) のアプリケーションをデプロイするAzure CLIコマンドを実行します。
「リソースグループ名」「App Service (Webアプリ) の名前」は、皆さんの環境に合わせて入力してください。
az webapp deployment source config-zip --resource-group "<リソースグループ名>" --name "<App Service (Webアプリ) の名前>" --src ./deploy.zip
コマンドを実行しましたら、デプロイが正常に開始されることを確認します。
$ az webapp deployment source config-zip --resource-group "resourcegroup" --name "kumamon-chatbot-app" --src ./deploy.zip Getting scm site credentials for zip deployment Starting zip deployment. This operation can take a while to complete ... Deployment endpoint responded with status code 202
ステータスコード「202」(HTTP Accept) が表示されていれば、デプロイ開始しています。
ここからしばらく時間がかかりますので待ちます。
デプロイが完了すると、結果が表示されます。
{ "active": true, "author": "N/A", "author_email": "N/A", "build_summary": { "errors": [], "warnings": [] }, "complete": true, ・・・ (中略) ・・・ }
エラーが表示されていないことを確認します。
また、Azureポータルの「App Service」リソース画面でデプロイの履歴を確認することもできます。
(5) Azure環境にデプロイしたチャットボットをテストする
アプリケーションがデプロイできましたら、動作をテストしてみましょう。
Azureポータルで「Bot Service」の「Webチャットでテスト」を使ってテストします。
Microsoft Teamsからテストします。
無事に動作しましたでしょうか?
これで、Azureで作成した「生成AIチャットボット」の完成です!
おわりに
今回の記事では、前回作成した「シンプルなチャットボット」に「Azure OpenAI」を組み込みました。 ベースとなる「シンプルなチャットボット」が作成できていれば、それほど手間をかけずに「生成AIチャットボット」に進化させることができます。
今回作成したアプリケーションにはいくつか課題 (「アプリケーションコードにAPIキーがハードコードされている」等) がありますが、機会があれば改善してみたいと思います。
次のステップでは、今回作成した生成AIチャットボットに「Cognitive Search」サービスを使った「RAG」を組み込んで、より本格的な生成AIチャットボットにしたいと思います。