複数の生成AI APIをPostman(Newman)で自動テストしてレスポンスをCSVに出力する

チャットボットに生成AIを組み込む際、各社のAPI(OpenAI、Gemini、Bedrock(Claude))のレスポンスを比較して出力の違いなどを検証したかったので、PostmanのNewmanを活用して、APIリクエストを一括実行して結果をCSVに保存する方法を試してみました。

各APIの設定方法から、Postman(Newman)を使ったレスポンスの比較方法まで解説します。

## APIの設定
まず、各社の生成AI API(OpenAI, Gemini, Bedrock)をPostmanで設定します。

### 1. OpenAI API

#### APIキーの作成
OpenAIのAPIプラットフォームにログインし、APIキーを作成します。

![APIキー作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/0da90a96-9746-4c38-b26f-9b185c24f3c8.png)

また、APIを利用するには最低5 USDのクレジットをチャージする必要があります。

![クレジットチャージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/59f7382c-76d6-4ba6-aad7-1c26538ab4d6.png)

#### Postmanの設定
OpenAIの`/chat/completions`エンドポイントにリクエストを送ります。

- エンドポイント
  ```
  POST https://api.openai.com/v1/chat/completions
  ```

- Headers
  ```
  Content-Type: application/json
  Authorization: Bearer <APIキー>
  ```

- Body
  ```json
  {
    "model": "gpt-4o",
    "messages": [
      {
        "role": "system",
        "content": "{{system_prompt}}"
      },
      {
        "role": "user",
        "content": "{{input_prompt}}"
      }
    ],
    "max_tokens": 200,
    "temperature": 0.7
  }
  ```

#### 補足
- `{{system_prompt}}`と`{{input_prompt}}`にはNewmanで使用する`prompts.json`の値が入ります(後述)
- `max_tokens`と`temperature`は任意のパラメータです

![Postman 設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/9ac0ef6d-3256-473f-b586-80f30f00678b.png)

### 2. Gemini API

#### APIキーの作成
Google Cloudのプロジェクトを作成し、Gemini APIを有効化します。

![Google Cloud 設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/a169e821-934e-4bfd-bb8d-e452a38e0fb1.png)

次に、「APIとサービス > 認証情報」からAPIキーを作成します。

![APIキー作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/006f9292-932f-4612-8b4f-b9e1b7776af3.png)

#### Postmanの設定
Geminiのエンドポイントは、APIキーをクエリパラメータとして渡します。

- エンドポイント
  ```
  POST https://generativelanguage.googleapis.com/v1/models/gemini-1.5-pro:generateContent
  ```

- Params
  ```
  key: <APIキー>
  ```

- Headers
  ```
  Content-Type: application/json
  ```

- Body
  ```json
  {
    "contents": [
      {
        "role": "user",
        "parts": [
          {
            "text": "{{system_prompt}}"
          }
        ]
      },
      {
        "role": "user",
        "parts": [
          {
            "text": "{{input_prompt}}"
          }
        ]
      }
    ],
    "generationConfig": {
      "temperature": 0.7,
      "maxOutputTokens": 200
    }
  }
  ```

### 3. Bedrock(Claude API)

#### APIキーの作成
AWSコンソールで「Amazon Bedrock > モデルアクセス」を開き、使用したいモデルのアクセス権をリクエストします。

![Bedrock 設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/d86d9cfe-e44d-43fb-88c7-b797559752b3.png)

IAMユーザーを作成し、Bedrockアクセス用のIAMポリシーを設定します。  
`BedrockFullAccess`ポリシーを適用すると便利ですが、アクセスキー漏洩のリスクがあるため、必要な権限のみを付与するカスタムポリシーを推奨します。

設定後、IAMでアクセスキー(およびシークレットアクセスキー)を発行します。

![IAM 設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/32eedaa3-02ec-4ae4-a35c-44fb2223651b.png)

#### Postmanの設定
Bedrock APIはAWS Signature認証を使用するため、PostmanのAuthタブでAWS認証を設定します。

- エンドポイント
  ```
  POST https://bedrock-runtime.ap-northeast-1.amazonaws.com/model/anthropic.claude-3-5-sonnet-20240620-v1:0/invoke
  ```

- Auth
  ```
  Auth Type: AWS Signature
  AccessKey: <発行したアクセスキー>
  SecretKey: <発行したシークレットアクセスキー>
  AWS Region: <リージョン>
  Service Name: bedrock
  ```

![Postman AWS 設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/92f4ff0f-382e-4f23-8868-0f40dab9fdfc.png)

- Headers
  ```
  Content-Type: application/json
  Accept: application/json
  ```

- Body
  ```json
  {
    "messages": [
      {
        "role": "system",
        "content": "{{system_prompt}}"
      },
      {
        "role": "user",
        "content": "{{input_prompt}}"
      }
    ],
    "max_tokens": 200,
    "anthropic_version": "bedrock-2023-05-31"
  }
  ```

## Newmanの設定
Newmanは、CLIから実行できるPostmanのCollection Runnerです。  
JSONにまとめた検証用のプロンプトを読み込んでAPIリクエストを実行し、異なるAIモデルに同じプロンプトを送信して、レスポンスを比較・検証することができます。

PostmanのGUIでもCollection Runnerを実行できますが、標準機能ではCSVに出力できないため、今回はNewmanを使用しました。Newmanを使うことで、CLIでの一括実行と結果の自動出力が可能になります。

https://github.com/postmanlabs/newman

https://github.com/matt-ball/newman-reporter-csv

### 1. インストール
まず、作業用フォルダを作成し、`newman`と`newman-reporter-csv`をローカルにインストールします。

```bash
$ npm install newman newman-reporter-csv
```

### 2. `collection.json`の作成
PostmanのCollection Runnerで使用するAPI定義を`collection.json`にエクスポートします。

1. PostmanでAPIリクエストを作成
2. 「Export」から「Collection v2.1」を選択
3. `collection.json`として保存

![Postman Export](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/64731217-0cd1-405e-98a9-ce6f5e72f4da.png)

これにより、Postmanのリクエスト設定がそのまま`collection.json`に保存され、Newmanで再利用できます。

### 3. `prompts.json`の作成
テスト用のプロンプトを`prompts.json`にまとめます。  
このファイルを使って、異なるプロンプトを一括でAPIに送信し、レスポンスを比較できます。

**記載例**
```json
[
  {
    "system_prompt": "あなたは旅行のプランナーです。",
    "input_prompt": "おすすめの旅行先を3つ提案してください。"
  },
  {
    "system_prompt": "あなたはITエンジニアであり、初心者向けのプログラミング講師でもあります。",
    "input_prompt": "プログラミング初心者におすすめの学習言語を3つ提案してください。"
  },
  {
    "system_prompt": "あなたは健康アドバイザーです。",
    "input_prompt": "毎日の健康習慣として取り入れるべき3つの習慣を提案してください。"
  }
]
```

### 4. Newmanの実行
以下のコマンドを実行すると、APIリクエストが自動で実行され、レスポンスがCSVに出力されます。

```bash
$ npx newman run collection.json -d prompts.json -r cli,csv \
  --reporter-csv-export responses.csv --reporter-csv-includeBody
```

- `-d prompts.json` → データファイル(`prompts.json`)を指定し、各プロンプトを順番に適用
- `-r cli,csv` → CLI出力とCSVレポートの両方を有効化
- `--reporter-csv-export responses.csv` → レスポンス結果を`responses.csv`に保存
- `--reporter-csv-includeBody` → レスポンスの中身をCSVのフィールドに含める


実行すると、以下のようなCSVが生成されます。

![スクリーンショット 2025-03-02 16.57.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/ec8189dd-1180-4f69-96b6-77608016b82d.png)