(non-Cloudflare Topic) daab の OpenAI 連携
前回の記事ではdirect用チャットボットであるdaabをコンテナ環境で起動させました。
この第二回目ではチャットボットをOpenAIとの対話式に作り変えます。
ping.jsの中身について
その前に一旦前回の中身を見ておきます。作業に使用したAmazon Linux 2023 を停止してしまった場合、以下の手順で起動させます。
sudo systemctl start docker
sudo systemctl status docker
sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
274793d6f332 amazonlinux:2023 "/bin/bash" 3 hours ago Exited (137) 2 hours ago daab
前回のイメージがあることが確認できましたので以下で起動します。
sudo docker start daab
次に以下のコマンドでログインし、作業ディレクトリに移動します。
sudo docker exec -it daab bash
cd daab
チャットボット本体のjsスクリプトを書き換えるためviエディタをインストールします。
yum install vi
インストールが出来たらファイルを開きます。
vi scripts/ping.js
/ Description:
// Utility commands surrounding Hubot uptime.
//
// Commands:
// ping - Reply with pong
// echo <text> - Reply back with <text>
// time - Reply with current time
'use strict';
module.exports = (robot) => {
robot.respond(/PING$/i, (res) => {
res.send('PONG');
});
robot.respond(/ADAPTER$/i, (res) => {
res.send(robot.adapterName);
});
robot.respond(/ECHO (.*)$/i, (res) => {
res.send(res.match[1]);
});
robot.respond(/TIME$/i, (res) => {
res.send(`Server time is: ${new Date()}`);
});
};
以下の部分が前回テストした箇所です。
robot.respond(/PING$/i, (res) => {
res.send('PONG');
});
特定のメッセージであるPING
が来たら単純にPONG
を返しています。
ChatGPT連携
1. OpenAIのアカウント作成とAPI Keyの準備
まずOpenAIのモジュールをインストールします。
npm install openai
次にOpenAIのアカウントを以下のページから作成します。
- https://openai.com/ja-JP/ へアクセス
- 画面下部のAPI Login をクリック
-
API
をクリック
- 左ペインのAPI Keysをクリック
- 画面右上
Create new secret keys
をクリック
- 適当な名前を付けて
create secret key
をクリック
- 出来上がった値を
Copy
daab スクリプトの改修
先ほど利用したrobot.respond
は特定の問い合わせにのみ反応するコマンドです。対話型チャットボットではこれでは少し具合が悪いためrobot.hear
を用います。ping.jsを以下に置換します。
'use strict';
const OpenAI = require('openai');
module.exports = (robot) => {
const openai = new OpenAI({
apiKey: "xxxxxxxxx",
});
robot.hear(/(.*)/, async(res) => {
try {
const input = res.match[1];
const match = input.match(/Hubot (.+)/);
const extracted = match[1];
const gptResponse = await openai.chat.completions.create({
model: "gpt-3.5-turbo",
messages: [{"role": "user", "content": extracted}],
});
const botReply = gptResponse.choices[0].message.content.trim();
res.send(botReply);
} catch (error) {
console.error("Error with OpenAI API request:", error);
res.send("Sorry, I'm having trouble connecting to the AI service.");
}
});
robot.respond(/PING$/i, async (res) => {
res.send('PONG');
});
robot.respond(/ADAPTER$/i, (res) => {
res.send(robot.adapterName);
});
robot.respond(/ECHO (.*)$/i, (res) => {
res.send(res.match[1]);
});
robot.respond(/TIME$/i, (res) => {
res.send(`Server time is: ${new Date()}`);
});
};
xxxxx
部分は先ほどコピーしたトークンに置き換えておきます。
置換後daab run
を実行すれば対話型チャットボットの完成です。
コード解説
robot.hear(/(.*)/, async(res) => {
ですべての入力が一度通る箇所になります。入力された値は
res.match[1]
に入ります。ただし文字列の先頭にHubspot
と含まれているため以下の部分でそれを除去しています。
const input = res.match[1];
const match = input.match(/Hubot (.+)/);
const extracted = match[1];
次にこの箇所でChatGPTとの対話を行います。
const gptResponse = await openai.chat.completions.create({
model: "gpt-3.5-turbo",
messages: [{"role": "user", "content": extracted}],
});
ChatGPTからは戻りがJSON形式となるためこのままではdaabが正しくレスポンスを戻すことが出来ません。このため以下で普通の文字列に整形しています。
const botReply = gptResponse.choices[0].message.content.trim();
またこのコードには先ほどの以下の部分がそのまま残っています。
robot.respond(/PING$/i, async (res) => {
res.send('PONG');
});
このため、ping
と入力されるとChatGPTとの対話の後PONG
が引き続き戻ります。
Discussion