OpenAI API クイックスタート

どこでも、いつでも簡単に使用できるようにするために、OpenAI API を使用する手順を記述します。

OpenAI API を使用するためには、課金しているユーザーでログインする必要があります。また、APIクレジットを購入する必要があります。送信と受信のトークン数で課金されます。

次のページを参考にしています。

https://platform.openai.com/docs/quickstart

　
■ Ubuntu に JavaScript（Node.js）をインストール

今回は、Windows の WLS2 の Ubuntu 22.04 を使用しました。デフォルトでインストールされる Node.js のバージョンが古いため、そのままでは OpenAI API のサンプルプログラムが動作しないので、nvm を使用して v20 をインストールします。

```console
sudo apt update
sudo apt install npm
```

![0315_01m.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956789/3106b10b-19af-428a-b93c-a033dbcbd2dc.png)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956789/f28e2b2b-5f9d-4662-802c-4beddf7392d3.png" width=70%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956789/45c58a42-bf3c-43ac-a97b-f3a37c007755.png" width=70%>

```console
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
source ~/.bashrc
nvm --version
nvm install 20
nvm use 20
node -v　　（v20.19.0 が表示される）
```

　
 ■ Node.js に OpenAI API ライブラリを追加

プログラムを作成する作業フォルダを作成してそこに移動します。npm install コマンドを実行します。その作業フォルダで openai ライブラリが使用できるようになります。

```console
mkdir working_directory
cd working_directory
npm install openai
```

　
■ テキストエディタとデバッグ

VSCode を使用して、WSL2 上の Ubuntu の Node.js の実行とデバッグが可能です。

使用したサンプルプログラム：https://platform.openai.com/docs/quickstart?lang=javascript

［拡張機能］で、「Dev Containers」を追加します。

![0315_01n.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956789/e32b4302-768d-44ae-b68c-f3e72e6cbf93.png)


左下の［リモートウィンドウを開きます］ボタンを押します。

中央上で、「WSL への接続」を選択します。

左帯のエクスプローラーから「フォルダーを開く」を選択します。

サンプルプログラム（FirstAPIRequest.mjs）を配置したフォルダーを選択し、ファイルを開きます。まだファイルを作成していない場合は、新規作成してそこにプログラムコードをコピー貼り付けします。

![0315_02n.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956789/fe4f6bed-49fb-4e27-b0e5-b2244ab65c0b.png)

![0315_03n.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956789/8668be6e-f6ac-4b4d-b67d-27686ce6626e.png)

![0315_04n.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956789/e76c8376-a04a-4830-adb9-af443376a568.png)


左帯から［実行とデバッグ］を選択します。

「JavaScript Debug Termina」ボタンを押します（「実行とデバッグ」ボタンではなく）。すると、下部にターミナルウィンドウが開きます。

OpenAI API を実行するために、始めに、ここで環境変数をセットします。（グローバルで使えるように設定しても良い。）（先にテキストファイルに準備しておき、コピー貼り付けする。）
export OPENAI_API_KEY="..."

任意の行にブレークポイントを設定して、ターミナルウィンドウで、
node FirstAPIRequest.mjs
を実行すると（「実行とデバッグ」ボタンで実行するのではなく）、デバッグが開始され、ブレークポイントで停止します。

F5キー（実行）またはF10キー（ステップオーバー）で実行を継続すると、最後まで進み、結果がターミナルウィンドウに表示されます。

![0315_05n.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956789/0962279d-6519-4e9f-8163-28fde421f712.png)

※ テキストの文字コードは UTF-8 で開く（右下）

送信したデータ１

![0315_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956789/66ed3b4f-12b2-4e86-862a-399595cc04a4.png)


あなたは役に立つアシスタントです。

プログラミングにおける再帰についての俳句を書いてください。

受信したデータ１

![0315_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956789/5309b1c2-7775-45e0-9abf-ebc8b2a484e2.png)

関数が自らを呼び、
流れの中でループし、
無限の層

参考サンプルプログラム： https://platform.openai.com/docs/guides/text-generation

送信したデータ２
［システムメッセージ］を追加すると、特性を指示できます。

![0315_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956789/b1ad7e88-3944-42e6-ba5e-1b4b44485fa3.png)

あなたは役に立つアシスタントです。日本語で話してください。

![0315_12.png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956789/86a856e9-6dea-4f2e-b211-1c322ddddcbe.png)


（日本語で）
　繰り返し、
　コードの中に、
　無限の道


参考サンプルプログラム： https://platform.openai.com/docs/guides/text-generation

送信したデータ３
［アシスタントメッセージ］で会話履歴を追加できます。次のAIの回答に履歴を反映します。

![0315_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956789/f22624bb-57c7-4bf9-b27e-523c6f0a6d4f.png)

コンコン。
そこにいるのは誰？
オレンジだよ。

受信したデータ３

![0315_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956789/74371b8e-53ba-4993-9d49-64360b297cf6.png)

オレンジ誰？　（英語では Orange who? ）

※ 前の会話が無いと、
「オレンジですね。果物のオレンジを指しているのでしょうか？それとも色のオレンジでしょうか？どちらについてもっと知りたいですか？ 」が返される。

## その他のサンプル

AnalyzeImageInputs.mjs

![0315_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956789/2bbce47e-cdc0-4005-8293-9328e3eb5f9b.png)

この画像は何ですか。日本語で説明してください。

![0315_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956789/9b666661-caa1-40ca-a4ca-a6b7fe89b072.png)

この画像には、青い空と草原が広がっている風景が映っています。中央には木製の歩道が見え、その両側には緑の草や灌木があります。穏やかな自然の風景が感じられ、開放感があります。

　
ConvertImageText.mjs
URLまたはファイルの画像を言葉に変換するプログラムを作成しました。
プログラムは、テキストファイルを1行ずつ読み込み、画像の場合は OpenAI API を使用して文章に変換し、文章の場合はそのまま出力します。
（OCR 機能を追加することも可能かもしれませんが、今のところ他の画像と同じに処理します。）

「temperature: 0, 」を指定しても、全く同じ回答になるわけではないようです（なので削除）。

```javascript:ConvertImageText.mjs
import OpenAI from "openai"
import fs from 'fs';

const openai = new OpenAI();

function isUrl(text) {
    const urlPattern = /https?:\/\/\S+/;
    return urlPattern.test(text);
}

function isImageFile(text) {
    const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.webp'];
    return imageExtensions.some(ext => text.trim().toLowerCase().endsWith(ext));
}

async function analyzeImageUrl(imageUrl) {
    try {
        const response = await openai.chat.completions.create({
            model: "gpt-4o-mini",
            messages: [
                {
                    role: "user",
                    content: [
                        { type: "text", text: "What's in this image? Please speak in Japanese." },
                        { type: "image_url", image_url: { url: imageUrl } },
                    ],
                },
            ],
        });
        return response.choices[0].message.content;
    } catch (error) {
        console.error("Error analyzing image URL:", error);
        return "（エラーが発生しました）";
    }
}

async function analyzeImageFile(imagePath) {
    try {
        const imageBuffer = fs.readFileSync(imagePath);
        const encodedImage = imageBuffer.toString('base64');
        
        const response = await openai.chat.completions.create({
            model: "gpt-4o-mini",
            messages: [
                {
                    role: "user",
                    content: [
                        { type: "text", text: "What's in this image? Please speak in Japanese." },
                        { type: "image_url", image_url: { url: `data:image/jpeg;base64,${encodedImage}` } },
                    ],
                },
            ],
        });
        return response.choices[0].message.content;
    } catch (error) {
        console.error("Error analyzing image file:", error);
        return "（エラーが発生しました）";
    }
}


// 使用例
const inputFilename = 'input.txt';
const outputFilename = 'output.txt';
let outputText = "";

const inputLines = fs.readFileSync(inputFilename, 'utf-8').split('\n');

(async () => { // await を使用するための即時実行関数
    for (let line of inputLines) {
        line = line.trim();
    
        if (isUrl(line) || isImageFile(line)) {
            let text = "";
    
            if (isUrl(line)) {
                console.log(`URL found: ${line}`);
                text = await analyzeImageUrl(line);

            } else if (isImageFile(line)) {
                console.log(`Image file found: ${line}`);
                text = await analyzeImageFile(line);
            }
    
            let prefix = "";
            prefix = "この画像";
            if (text.startsWith(prefix)) {
                 text = "画像" + text.slice(prefix.length);
            }
            prefix = "申し訳ありませんが";
            if (text.startsWith(prefix)) {
                text = "（説明できない画像）";
            }

            outputText += text + '\n';

        } else {
            outputText += line + '\n';
        }    
    }
    
    fs.writeFileSync(outputFilename, outputText, 'utf-8');
    console.log(`Character count: ${outputText.length}`);
})();

```

```console:実行
node ConvertImageText.mjs
URL found: https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg
Image file found: top.jpg
Character count: 4382
```