OpenAI の API を TypeScript から使ってみた【ChatGPT】

# 概要

この記事は、OpenAI の API を使用する方法を紹介します。
API にリクエストを行うための事前登録のやり方と、API の使い方について解説します。

リクエストとレスポンスの長さにもよりますが、このページで叩いたときの利用料金は、$0.00005 ぐらいでした。安くて個人開発でも無理なく利用できます。

# 事前準備

## 支払い方法を登録する

OpenAI の API を利用するためには、支払い方法を登録する必要があります。
アカウント設定の [こちらの Billing overview](https://platform.openai.com/account/billing/overview) から支払い方法を設定しましょう。
![register_billing_method.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508663/67e0330d-d6f8-96f6-85c1-f14ae614ae15.png)

## API キーを発行する

次に API キーを発行する必要があります。
[API キー発行ページ](https://platform.openai.com/account/api-keys)から発行をしましょう！
API キーはリクエストを送信するときに使います。

:::note warn
一度しか見ることができないのでコピペをしておきましょう！
:::

![create_api_key.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508663/f0955315-d8b0-a709-8154-12bd00ab62bc.png)

## 任意：利用上限を設定する

使いすぎないように、[アカウント設定の利用上限ページ](https://platform.openai.com/account/billing/limits)から利用上限を設定するといいと思います。このあたり、とても親切ですね。（たまに AWS で十数万円請求されている人とかいますよね。）
![set_usage_limit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3508663/fb9b8e73-0413-770f-0e18-d7a5ece2960c.png)


# 実際に API を叩いてみた

今回は GPT に俳句を読ませてみました。
出力された俳句は 5-11-7 の字余りすぎる句になってしまいました。この句の良さは全くわかりません。

:::note warn
HTTP 401 が返ってくるときは、API キーが間違っている可能性があります。取得した API キーを 1 行目に設定することを忘れないでください。
:::

```typescript:OpenAI API を叩くコード
process.env.OPENAI_API_KEY = "<取得した API キーを設定する>"
import { Configuration, OpenAIApi } from "openai"

test("ChatGPT の API を呼び出す", async () => {
  // 手順 2 で取得した API キーを設定する
  const configuration = new Configuration({ apiKey: process.env.OPENAI_API_KEY })
  // OpenAI のクライアントを初期化する
  const openai = new OpenAIApi(configuration)

  // リクエストを送信
  const completion = await openai.createChatCompletion({
    // 今回は言語モデル GPT 3.5 を使用する
    model: "gpt-3.5-turbo",
    // messages には ChatGPT に送信したい会話の内容を含める
    messages: [
      { role: "system", content: "ユーザーが指定する単語を含めた俳句を一つ出力せよ" },
      { role: "user", content: "アパート" },
    ],
  })

  // レスポンスボディを JSON 形式の文字列に変換
  const responseBody = JSON.stringify(completion.data)
  // レスポンスボディを表示
  console.log(responseBody)
})
```

レスポンスは JSON で返ってきます。返ってくるレスポンスはこんな感じです。

```json:レスポンスボディ
{
  "id": "chatcmpl-XXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "object": "chat.completion",
  "created": 1688776267,
  "model": "gpt-3.5-turbo-0613",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "アパートの\n静かな夜を彩る\n一輪の花"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": { "prompt_tokens": 42, "completion_tokens": 23, "total_tokens": 65 }
}
```


# 解説

## リクエストの解説

今回リクエストに使った項目について解説します。
詳しくは、[OpenAI API のリファレンス](https://platform.openai.com/docs/api-reference/chat/create)を御覧ください。

| 項目 | 説明 |
|:----|:-----|
| model | 使用する AI のモデルを指定します。 `gpt-4` や `gpt-3.5-turbo` などが使用可能です。 |
| messages | 送信する会話を表す配列です。 発言者を表す `role` とその発言内容 `content` を指定できます。 |

`role` には主に `system`、`user`、`assistant` を指定できます。
messages は、この 3 人の会話を書くことになります。
[ChatGPT](https://chat.openai.com/) を使うときは、自分（`user`）と ChatGPT（`assistant`）だけなので、`system` が見慣れないと思います。

| 項目 | 説明 |
|:----|:-----|
| system | API を使用するサーバーなどのシステムです。 |
| user | システムを利用するユーザーです。 |
| assistant | GPT などの AI です。 |


## レスポンスの解説

レスポンスで重要なのは、`choices` です。`choices` がリクエストの `messages` に対する返答になります。
AI が回答しているので、`role` はもちろん `assistant` になります。