1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Discord.js] DiscordBotにGPT-3を(API利用で)組み込む

Last updated at Posted at 2022-12-05

動機

巷で話題のChatGPTで利用されているモデルについて、OpenAIのAPIから叩けることを知りました。
LINEでやり取りできるようにする記事を読んで自分でもなにかやってみたいなと思ったので、なずなさんおなじみのDiscordBotへ、機能追加の形で取り組むことにしました。

作業していたブランチとそのPRは以下です。
https://github.com/na2na-p/2na2-Discord/pull/157

準備

  • OpenAIのAPI Key発行
    割愛します。

作業

Slash Commandの登録

const command: commandSetType = {
	name: 'gpt3',
	description: 'おしゃべりAIです。予告なく使えなくなる場合があります。',
	options: [
		{
			type: 3,
			name: 'prompt',
			description: 'AIに入力する文章です。',
			required: true,
		},
	],
};

// 別ファイルでcommandSetTypeを定義しています。下記のとおりです。
// export type commandSetType = Omit<ChatInputApplicationCommandData, 'name'> & {
//	name: Lowercase<string>;
// };

Slash Command検知した際の処理

private async interactionHook(interaction: Readonly<ChatInputCommandInteraction>): Promise<boolean> {
	if (interaction.commandName === 'gpt3') {
        // 3秒以上かかるので必要
		interaction.deferReply();
		const prompt = interaction.options.getString('prompt', true);
        // fetchGpt3{prompt: string}を受け取って文字列を返す関数
		const completions = await fetchGpt3({ prompt });
		console.log(completions);
		interaction.editReply(completions);
		return true;
	} else {
		return false;
	}
}

fetchする関数

import ENDPOINTS from '@/constants/ENDPOINTS.js';
// configはAPIキー等を持っています。
import { config } from '@/config/index.js';
import GPT3_MODELS from '@/constants/GPT3_MODELS.js';

// https://api.openai.com/v1/completions に飛ばします
const COMPLETION_ENDPOINT = `${ENDPOINTS.OPEN_AI}/completions`;

// 0~1
const TEMPERATURE = 0.9;
// 2048 or 4000
const MAX_TOKENS = 4000;

/**
 * @see https://beta.openai.com/docs/api-reference/completions/create
 */
async function fetchGpt3({ prompt }: {prompt: string}): Promise<string> {
	const options = {
		model: GPT3_MODELS.davinci,
		max_tokens: MAX_TOKENS,
		temperature: TEMPERATURE,
		prompt,
	};

	const response = await fetch(COMPLETION_ENDPOINT, {
		method: 'POST',
		headers: {
			'Content-Type': 'application/json',
			'Authorization': `Bearer ${config.openAiApiKey}`,
		},
		body: JSON.stringify(options),
	});

	const results = await response.json();
	try {
		// results.choicesの中からランダムに返す
        // エラー(tokensが長過ぎる等)の場合にresults.choicesは帰ってこないのでtry-catchしてます
		const randomIndex = Math.floor(Math.random() * results.choices.length);
		return results.choices[randomIndex].text;
	} catch (e) {
		return results.message;
	}
}

export default fetchGpt3;

まとめ

かなーり雑ですが、フェッチする箇所だけ取り出して使いまわしが効くような書き方をしたつもりです。おもちゃとしての性能が非常に高く、作業時間は少しでしたが満足です。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?