今話題のChatGPT APIをTypeScriptから簡単に呼び出せるライブラリを作った！

# はじめに

昨日から話題沸騰中の**ChatGPT API**、みなさんはもうお試ししましたか？
以前からAPIの提供は期待されていて、OpenAIも予定はしていると言っていたものの実際にいつ発表になるのかは具体的には明言されていませんでした。

そして、ここに来て満を持しての**ChatGPT API**の登場です。

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

これは、ひとりの個人開発者としてワクワクが止まりません。

ただ、ChatGPT APIと言われても、プログラミングを始めたばかりの方や、わざわざREST APIを呼び出してレスポンスを取得して〜までの処理を書くのが面倒な方にとっては後で触ろう思ってしまうかもしれません。

僕的には、この機会の損失は本当にもったいないと思いました。
なので、今回`TypeScript`から`prompt()`を呼び出すだけで余計な設定いらずで**Chat GPT API**を使うことができるライブラリ、`ts-chatgpt`をリリースいたしました！！！

https://github.com/takagimeow/ts-chatgpt

> CommonJSでビルドされているので、Node.jsが動く既存のプロジェクトでもすぐに採用できると思います。（もちろんNode.jsのバージョンについては適宜ご確認をお願いいたします。ちなみに推奨バージョンは`14`以降です。）

## インストール

インストールは簡単です。`npm install ts-chatgpt`を実行して、既存のプロジェクト、もしくは新しいプロジェクトに追加してください。

```shell
npm install ts-chatgpt
```

`yarn`をお使いの方はこちら。

```shell
yarn add ts-chatgpt
```

## OPENAI_API_KEY環境変数の準備

このライブラリは、OpenAIから提供されているAPIキーを使ってChatGPT APIを呼び出しています。
なので、ライブラリを実際に使用する前に、必ずこのAPIキーを取得して、`OPENAI_API_KEY`環境変数として設定してからご使用ください。

まずは[こちら](https://platform.openai.com/overview)のページにアクセスします。アカウントを未作成の方は、最初にアカウントを作成する必要がありますのでご注意ください。

https://platform.openai.com/overview

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/f8ef642f-a140-9175-8404-950ebea6088a.png)

アクセスしたら、右上のアカウントをクリックします。
表示されるメニューから**View API Keys**を選択します。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/3ac4e6fb-82cd-fe60-fc25-e5b6b9abf6d8.png)

**API Keys**のページにアクセスしたら、画面中央にある**Create new secret key**をクリックします。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/cfe7516d-e7ba-dce3-1642-0260e93b44a8.png)

モーダルと共にシークレットキーが表示されますので、コピーしておきます。このキーはとても大事なキーなので他人には絶対に教えないようにお気をつけください。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/b8699174-56ec-c652-92f6-35c6b0884417.png)

これで必要な準備は整いましたので、コピーしたシークレットキーを`.env`ファイルに貼り付けます。

```.env
OPENAI_API_KEY="xxx-xxx-xxx"
```

## さっそく使ってみる

使い方はとっても簡単です。

まず、`prompt()`を`ts-chatgpt`からインポートします。

```ts
import { prompt } from "ts-chatgpt";
```

そして、非同期関数の中で必要な引数を与えて呼び出します。

```ts
async function main() {
    const response = await prompt({
      model: "gpt-3.5-turbo-0301",
      messages: [
        {
          role: "user",
          content: "Hello, I'm a user",
        },
      ],
    });
}
```

これで完了です！！！
受け取ったレスポンスには次のような内容が保存されています。

```shell
{
  id: 'xxx',
  object: 'chat.completion',
  created: 1677777177,
  model: 'gpt-3.5-turbo-0301',
  usage: { prompt_tokens: 13, completion_tokens: 11, total_tokens: 24 },
  choices: [ { message: [{
      role: 'assistant',
      content: 'Hello there! How can I assist you today?'
  }], finish_reason: 'stop', index: 0 } ]
}
```

このレスポンスの型は`ChatGPTResponse`として`ts-chatgpt`から公開されていますので、必要に応じてご活用ください。

## 引数の詳細

`prompt()`を呼び出す際に渡した`model`には、現在次の２つの値を渡せるようになっています。

| Model                | Description        | Available |
| -------------------- | ------------------ | --------- |
| `gpt-3.5-turbo`      | The default model. | ✅        |
| `gpt-3.5-turbo-0301` | -                  | ✅        |

これらのモデルは、いわゆるChatGPT APIのエンジンに相当するもので、現在のChatGPT製品に採用されているものと同じモデルとなっています。

また`messages`配列の要素として`Message`型の値を渡すことができます。
`Role`としては`system`、`assistant`、そして`user`の３つを設定することが可能となっています。

実際にChatGPTに対して入力するテキストは`content`として渡します。

```ts
export type Role = "system" | "assistant" | "user";
export interface Message {
  role: Role;
  content: string;
}
```

`messages`配列という形で、複数の`Message`を設定できるようになっている理由は会話上の文脈を維持するためです。これをカスタマイズすることで、より開発者にとって自然な文脈に沿った応答を得ることができるようになっています。

# まとめ

今回、ChatGPT APIをラップしたライブラリを開発するにあたって、より使いやすく余計な設定などを意識しなくても使いこなせるものを目指しました。

なので、クラスはあえて採用せず、関数の呼び出しのみで**ChatGPT API**を呼び出すことができるようになっています。
環境変数`OPENAI_API_KEY`に関しても、開発者がそのためだけに`dotenv`をインストールしなくても自動的に読み取れるようになっておりますので、安心してご活用ください。

https://github.com/takagimeow/ts-chatgpt

このライブラリを活用して、個人開発者のみなさまが世界をあっと驚かせるアプリケーションを公開する日が来ることをとても楽しみにしております。

# 参考にした記事

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

https://platform.openai.com/docs/guides/chat

https://platform.openai.com/docs/api-reference/chat/create

https://www.itmedia.co.jp/news/articles/2303/02/news076.html