🤖
OpenAIのChat Completion APIを使って、ChatGPTライクに会話ができるSlackBotを作る
以前の記事では、GPT3
の Completion API を使って Chat GPT ライクな Slack Bot を作っていましたが、 2023/03/02(日本時間)ついに GPT-3.5-turbo
を使う Chat Completion API が公開されました 🎉
早速そちらを使って Slack Bot を作ってみました。
🤖 作ったもの
Chat GPT のように前後の会話を考慮して回答してくれる Slack Bot です。
🛠️ 実装
Slack の API でスレッドの内容を取得し、それを Chat Completion API に渡すことで Chat GPT のように前後の会話を考慮した回答を返してくれます。
以下 Slack のBolt フレームワーク をつかった場合の実装例です。
export const useReplyEvent = (app: App) => {
app.event("message", async ({ event, client, logger }) => {
const { thread_ts: threadTs, bot_id: botId, text } = event as any;
// botの返信またはスレッドのメッセージでなければ何もしない
if (botId || !threadTs) {
return;
}
// スレッドのメッセージを取得
const threadMessagesResponse = await client.conversations.replies({
channel: event.channel,
ts: threadTs,
});
const messages = threadMessagesResponse.messages?.sort(
(a, b) => Number(a.ts) - Number(b.ts)
);
// GPT Botへの返信でなければ何もしない
if (!(messages![0].text?.includes(GPT_BOT_NAME) && messages![0].bot_id)) {
return;
}
try {
// token数の制限を回避するため、最大20件のメッセージで区切る
const prevMessages =
messages!.slice(1).slice(-20).map(m => {
const role = m.bot_id ? ChatCompletionRequestMessageRoleEnum.Assistant : ChatCompletionRequestMessageRoleEnum.User
return {role: role, content: m.text as string}
})
});
const configuration = new Configuration({
apiKey: config.openai.key,
});
const openAIClient = new OpenAIApi(configuration);
// Chat Completion API を呼び出す
const response = await openAIClient.createChatCompletion({
model: "gpt-3.5-turbo",
// 以下で会話部分を組み立てる
messages: [
{
role: ChatCompletionRequestMessageRoleEnum.System,
content: CHAT_GPT_SYSTEM_PROMPT,
},
...prevMessages,
{
role: ChatCompletionRequestMessageRoleEnum.User,
content: text as string,
},
],
top_p: 0.5,
frequency_penalty: 0.5,
});
const message = response.data.choices[0].message?.content || "";
// 回答メッセージを投稿する
if (message) {
await postAsGptBot({
client,
channel: event.channel,
threadTs,
text: message,
});
} else {
throw new Error("message is empty");
}
} catch (e) {
logger.error(e);
await postAsGptBot({
client,
channel: event.channel,
threadTs,
text: "大変申し訳ございません。エラーです。別スレッドでやり直してください。",
});
}
});
};
Chat Completion API に渡すメッセージにはrole
とcontent
の 2 つのプロパティがあります。
それを Slack Bot 側と、ユーザー側で適切に分けて渡すことが重要です。
[
{ "role": "system", "content": "You are a helpful assistant." },
{ "role": "user", "content": "Who won the world series in 2020?" },
{ "role": "assistant", "content": "The Los Angeles Dodgers won the World" },
{ "role": "user", "content": "Where was it played?" }
]
また API へ最初に渡す system
ロールの prompt の部分も大切です。
今回は Slack の formatting を考慮して返答してくれるように以下のような Prompt を渡しています。
export const CHAT_GPT_SYSTEM_PROMPT = `
You are an excellent AI assistant Slack Bot.
Please output your response message according to following format.
- bold: "*bold*"
- italic: "_italic_"
- strikethrough: "~strikethrough~"
- code: " \`code\` "
- link: "<https://slack.com|link text>"
- block: "\`\`\` code block \`\`\`"
- bulleted list: "* item1"
Be sure to include a space before and after the single quote in the sentence.
ex) word\`code\`word -> word \`code\` word
Let's begin.
`;
上記のコードを実際に実装した PR はこちらです。
以前記事で紹介した tell-me-bot という便利な質問回答 Bot にチャット機能を追加しています。
おわりに
Slack で Chat GPT が使えるのは最高に便利!
Open AI の API は今後も進化していくと思うので、楽しみです。
Discussion