openai-nodeを利用してChatGPTのAPIを実行してみるまで

## この記事は何

[openai](https://github.com/openai/openai-node)のnpmライブラリを使って、新規のプロジェクトからChatGPTのAPIを叩けるようになるまでを記事にしました。
これから触ってみたい！と言った人などの参考になればと思います。

## 環境

- Node.js v18.15.0
- TypeScript v5.0.3
- pnpm v8.1.0
  - パッケージマネージャはお好みで

## APIキーの作成

OpenAIのアカウントを作成して[APIキー作成のページ](https://platform.openai.com/account/api-keys)より、API Keyを作成します。

モーダルで1度しかキーは表示されないため、注意してください。

## プロジェクトを作成

`package.json`と`tsconfig.json`の作成、必要パッケージのインストールを行います。
パッケージは下記をインストールしています。

- `openai`: OpenAI公式で提供している、OpenAI APIの利用をサポートしているライブラリです。
- `typescript`
- `ts-node`: サクッとTypeScriptのコードを実行したいので、入れています。

コマンドと、`tsconfig.json` は下記になります。

```
pnpm init
pnpm i openai
pnpm i --save-dev typescript ts-node
npx tsc --init
```

```json:tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
    "module": "commonjs", /* Specify what module code is generated. */
    "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
    "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
    "strict": true, /* Enable all strict type-checking options. */
    "skipLibCheck": true /* Skip type checking all .d.ts files. */
  }
}

```

## OpenAI APIを実行するコードを書いていく。

- [ChatCompletions](https://platform.openai.com/docs/guides/chat) を実行するためのコードを書いていきます。

```typescript:lib/openai.ts
import { Configuration, OpenAIApi } from 'openai';

const configuration = new Configuration({
  apiKey: 'YOUR_API_KEY',
})

const openAI = new OpenAIApi(configuration);

export const getChatCompletion = async (content: string): Promise<string> => {
  try {
    const completion = await openAI.createChatCompletion({
      model: 'gpt-3.5-turbo',
      messages: [
        {
          role: 'user',
          content: content,
        },
      ],
    });

    return completion.data!.choices[0]!.message!.content
  } catch (error: any) { // https://github.com/openai/openai-node/issues/76
    if (error.response) {
      return `${error.response.status}, ${error.response.data}`;
    } else {
      return `${error.type}, ${error.message}`;
    };
  };
};

```

`configuration` はOpenAI APIを利用するための設定を記載しています。
基本発行した`apiKey`を設定すれば大丈夫です。
(簡略化のためにハードコードでAPIキーを記載するように書いてますが、環境変数から読むなどするようにしましょう:pray:)

`getChatCompletion` 関数に`content` を渡して、ChatCompletionsを実行、`content`に沿った内容を返してくれるようになっています。
`openai`ライブラリで提供されている、`createChatCompletion`を利用しています。
引数は以下の二つが必須になります。

- model: 使用するモデルのID、[ここから](https://platform.openai.com/docs/models/overview)利用できるものは確認できます。
- messages: チャットを生成するためのメッセージを配列の形式で渡します。
  - role: 誰がそのメッセージを送信したかを記載します。`user`、`assistant`、`system`の3つが使える。
  - content: チャットの内容になります。
  - 複数のメッセージを配列で渡すことで、対話のようにメッセージを作成することも可能です。
    - トークンも増え、料金が増加するので、渡し過ぎには注意です。

エラー周りは型などが公式から提供されておらず、これからといった感じです。[^1]

[^1]: https://github.com/openai/openai-node/issues/76 で起票はされているようです。

最後に、作成した関数を実行するための`index.ts` を作成します。

```typescript:index.ts
import { getChatCompletion } from './lib/openai';

const exec = async () => {
  const responseText = await getChatCompletion('こんにちは、あなたの名前を教えてください。');
  console.log(responseText);
};

exec();

```

実行した結果は下記になります。

```
$ pnpm exec ts-node index.ts
申し訳ありません、私はAIアシスタントであり、名前を持っていません。あなたが何かお手伝いできますか？

```

名前は持っていないらしいです。

## 終わりに

実際にOpenAIを実行までは比較的簡単に作ることができました。
こちらをベースにBotに組み込んでみたり、自身のサービスに入れてみることなどもできそうなので、色々使い倒していこうと思います。