Node.js で OpenAI の 新API（Responses API）をシンプルに試す

## はじめに
### 新API
以下の公式の記事に登場している新API の「Responses API」をシンプルに試してみた、という話です。

●New tools for building agents | OpenAI
　https://openai.com/index/new-tools-for-building-agents/

![2025-03-14_23-40-49.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/f31a2f4e-2a36-49d9-a640-064cba65ef41.jpeg)

記事の中では、こちらの部分などに登場しています。

![2025-03-14_23-42-12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/3121fdbf-79a8-4567-8404-2dfa62059def.jpeg)

### 参照する情報

API の情報を追いかけてみていたところ以下が読みやすかったので、こちらも参照しつつ進めてみます。

●OpenAI Responses API と Agents SDK リリースのまとめ
　https://zenn.dev/openaidevs/articles/616681c2e7dc39

掲載されているサンプルは Python ですが、Node.js の処理に読みかえたり、以下の公式サンプルを併用しつつ活用していきます。

●openai/openai-node: Official JavaScript / TypeScript library for the OpenAI API
　https://github.com/openai/openai-node/tree/master

![2025-03-15_00-34-45.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/1bfa7da1-3c78-4eeb-a681-5be6126f1ddc.jpeg)

## 実際に試す

実際に API を試してみます。

### 利用するライブラリ

今回は、以下の記事を書いた時などにも使った [OpenAI の TypeScript・JavaScript用ライブラリ](https://www.npmjs.com/package/openai)を使います。

●GPT-4o と Node.js の process.loadEnvFile() と OpenAI のライブラリを組み合わせる - Qiita
　https://qiita.com/youtoy/items/d535f9dd3db95b914fab

![2025-03-15_00-13-34.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/6a8a17cf-caf8-4e66-ba3a-badff156a5d3.jpeg)

### 試してみる処理

参照記事を見ると、シンプルに使う場合の例が掲載されています。

![2025-03-15_00-16-44.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/d8e5e6b3-b834-43fe-b749-7314aa18ad62.jpeg)

Chat Completions を使う場合より、少しシンプルに書けるようです。

#### 実装

[公式の Node.js のサンプル](https://github.com/openai/openai-node/tree/master)なども見つつ、以下の内容を試してみました。

```javascript:app.mjs
import OpenAI from "openai";

process.loadEnvFile("./development.env");
const client = new OpenAI();

const response = await client.responses.create({
  model: "gpt-4o",
  input: "あなたは誰？",
});

console.log(response.output_text);
```

APIキーは、過去の記事でも使った Node.js の process.loadEnvFile() で設定してみました。具体的には以下のファイルを用意して、ここから APIキーを読みこんでいます。

```zsh:development.env
OPENAI_API_KEY=【ご自身の OpenAI の APIキー】
```

#### 実行結果

上記を実行した結果は以下のとおりです。

![2025-03-15_00-25-28.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/4a8d0023-5a71-412a-bc5a-9d394c821d53.jpeg)


## Chat Completions との差分
公式サンプルの以下を見ると、差分が分かる例が書かれています。

![2025-03-15_00-34-45.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/2d72077a-f497-4779-9c1f-6917382861b1.jpeg)

抜粋すると、以下のような形です。

### プロンプトまわり

```javascript
const completion = await client.chat.completions.create({
  model: 'gpt-4o',
  messages: [
    { role: 'developer', content: 'Talk like a pirate.' },
    { role: 'user', content: 'Are semicolons optional in JavaScript?' },
  ],
});
```

　↓

```javascript
const response = await client.responses.create({
  model: 'gpt-4o',
  instructions: 'You are a coding assistant that talks like a pirate',
  input: 'Are semicolons optional in JavaScript?',
});
```

### 出力の取得

```javascript
console.log(completion.choices[0].message.content);
```

　↓

```javascript
console.log(response.output_text);
```

すっきりと書けるようになっているのが分かります。


## さらにお試し

さらにストリーミングによる出力を試してみます。

### 実装

以下のような実装で試してみました。

```javascript
import OpenAI from "openai";

process.loadEnvFile("./development.env");
const client = new OpenAI();

const stream = await client.responses.create({
  model: "gpt-4o",
  input: "あなたは誰？",
  stream: true,
});

for await (const event of stream) {
  if (event.type === "response.output_text.delta") {
    console.log(event.delta);
  }
}
```

### 出力結果

上記を実行した結果は、以下のとおりで

![2025-03-15_01-09-48.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/a96e2ea6-f551-4feb-9533-ed18130c24e7.jpeg)