OpenAI API で C# でコマンドラインで会話する

# OpenAI API で C# でコマンドラインで会話する

![open-ai_with_csharp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/29ba9761-faed-8590-a43b-5cea0a31b4de.png)

こんにちは、@studio_meowtoon です。今回は、WSL の Ubuntu 22.04 で OpenAI API を C# から使いコマンドラインから会話する方法を紹介します。

## 目的

Windows 11 の Linux でクラウド開発します。

こちらから記事の一覧がご覧いただけます。

https://qiita.com/studio_meowtoon/items/6119ab05d8b13527efd8

## 実現すること

ローカル環境の Ubuntu で、OpenAI API を C# から使いコマンドラインから会話します。

:::note alert
C# には本来[厳格なコーディング規則](https://learn.microsoft.com/ja-jp/dotnet/csharp/fundamentals/coding-style/coding-conventions)がありますが、この記事では可読性のために、一部規則に沿わない表記方法を使用しています。ご注意ください。
:::

## 関連記事

**ChatGPT API** と比較してみましょう！

#### ChatGPT API

https://qiita.com/studio_meowtoon/items/2675b596191e4fa2d0e3

## 技術トピック

### OpenAI API とは？  

<details>
<summary>こちらを展開してご覧いただけます。</summary>

### [OpenAI API (オープンエーアイ エーピーアイ)](https://openai.com/blog/openai-api)

:::note info
OpenAI API は、OpenAI が提供する自然言語処理や人工知能技術にアクセスするためのプログラムインターフェース (API) です。

|特徴|
|:--|
|この API を使用することで、開発者は OpenAI の大規模な言語モデルを利用して、文章生成、文章分類、言語翻訳、質問応答、要約などの様々な自然言語処理タスクを自動化することができます。|
|また、OpenAI API は複数の言語に対応しており、簡単に統合することができるため、幅広いアプリケーションで利用されています。|

:::
</details>

## 開発環境

+ Windows 11 Home 22H2 を使用しています。  

:::note info
[WSL](https://learn.microsoft.com/ja-jp/windows/wsl/about) の Ubuntu を操作していきますので macOS の方も参考にして頂けます。  
:::

<details>

WSL (Microsoft Store アプリ版) [※ こちらの関連記事からインストール方法をご確認いただけます](https://qiita.com/studio_meowtoon/items/2aaa6579cb8e4fa1d874)

```sh
> wsl --version
WSL バージョン: 1.0.3.0
カーネル バージョン: 5.15.79.1
WSLg バージョン: 1.0.47
```

Ubuntu [※ こちらの関連記事からインストール方法をご確認いただけます](https://qiita.com/studio_meowtoon/items/2aaa6579cb8e4fa1d874)

```sh
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.1 LTS
Release:        22.04
```

.NET SDK [※ こちらの関連記事からインストール方法をご確認いただけます](https://qiita.com/studio_meowtoon/items/d68031c91462f6808dff)

```sh
$ dotnet --list-sdks
7.0.202 [/usr/share/dotnet/sdk]
$ dotnet --version
7.0.202
```

</details>

:::note warn
この記事では基本的に Ubuntu のターミナルで操作を行います。**Vim を使用してコピペする方法**を初めて学ぶ人のために、以下の記事で手順を紹介しています。ぜひ挑戦してみてください。
:::

https://qiita.com/studio_meowtoon/items/7771ad48676926e41463

## OpenAI と会話する手順

### OpenAI API のキーを取得します

https://platform.openai.com/account/api-keys

![api_keys.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/255a154a-6536-3e7b-9fa2-4e8bd74e74f5.png)

```sh
sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```

**Ubuntu** に **OPENAI_API_KEY** 環境変数を作成します。

```sh
$ export OPENAI_API_KEY=sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```

:::note alert
この環境変数が**一時的なもの**であることに注意してください。
:::

### プロジェクトの作成

:::note warn
.NET 環境をお持ちでない場合は、以下の関連記事から .NET SDK のインストール手順をご確認いただけます。
:::

https://qiita.com/studio_meowtoon/items/d68031c91462f6808dff

プロジェクトルートフォルダに移動します。
※ ~/tmp をプロジェクトルートフォルダとします。

```sh
$ cd ~/tmp
```

コンソールアプリを作成します。  
※ OpenAIApp がアプリ名です。  

```sh
$ dotnet new console -o OpenAIApp -f net7.0
```

コンソールアプリをビルド・実行します。

```sh
$ cd ~/tmp/OpenAIApp
$ dotnet run
Hello, World!
```

:::note info
ここまでの手順で、C#.NET コンソールアプリが作成できました。
:::

## ライブラリの追加

**OpenAI** のパッケージを [**NuGet**](https://learn.microsoft.com/ja-jp/nuget/what-is-nuget) で取得します。

```sh
$ dotnet add package OpenAI
```

パッケージを確認します。

```sh
$ dotnet list package
プロジェクト 'OpenAIApp' に次のパッケージ参照が含まれています
   [net7.0]:
   最上位レベル パッケージ      要求済み    解決済み
   > OpenAI          1.6.0   1.6.0
```

:::note info
ここまでの手順で、プロジェクトに **OpenAI** のパッケージを組み込むことができました。
:::

## コードの修正 その1

**OpenAI API** で会話します。

Program.cs を修正します。

```sh
$ vim Program.cs
```

ファイルの内容

```csharp:Program.cs
using static System.Console;
using static System.Environment;
using OpenAI_API;
namespace OpenAIApp {
    class Program {
        static async Task Main(string[] args) {
            // get an api key.
            string? apiKey = GetEnvironmentVariable("OPENAI_API_KEY");
            // create an api object.
            OpenAIAPI api = new(apiKey);
            // read a prompt from the console.
            WriteLine("Enter a prompt: ");
            string? prompt = ReadLine();
            // get a result from the api.
            string? result = await api.Completions.GetCompletion(prompt);
            WriteLine(result.Trim());
            // wait the console.
            ReadLine();
        }
    }
}
```

コンソールアプリをビルド・実行します。

```txt
$ dotnet run
Enter a prompt:
Are you human?
No, I am not human.
```

:::note info
ここまでの手順で、OpenAI API を使い **OpenAI と会話**することができました。
:::
:::note warn
しかし、現在のプログラムでは会話は**一回きりで終了**してしまいます。
:::

## コードの修正 その2

プログラムを**停止**するまで会話を**繰り返し**ます。

Program.cs を修正します。

```sh
$ vim Program.cs
```

ファイルの内容

```csharp:Program.cs
using static System.Console;
using static System.Environment;
using OpenAI_API;
namespace OpenAIApp {
    class Program {
        static async Task Main(string[] args) {
            // get an api key.
            string? apiKey = GetEnvironmentVariable("OPENAI_API_KEY");
            // create an api object.
            OpenAIAPI api = new(apiKey);
            // loop until a prompt is empty.
            string? prompt = null;
            do {
                // read a prompt from the console.
                WriteLine("Enter a prompt (or press Ctrl + C to exit):");
                prompt = ReadLine();
                if (!string.IsNullOrEmpty(prompt)) {
                    // get a result from the api.
                    string? result = await api.Completions.GetCompletion(prompt);
                    // print the result.
                    WriteLine(result.Trim());
                }
            } while (!string.IsNullOrEmpty(prompt));
            // wait the console.
            ReadLine();
        }
    }
}
```

コンソールアプリをビルド・実行します。

```txt
$ dotnet run
Enter a prompt (or press Ctrl + C to exit):
How are you?
I'm doing well, thank you for asking. How about you?
Enter a prompt (or press Ctrl + C to exit):
I'm fine. are you?
Yes, I'm doing well, thanks.
Enter a prompt (or press Ctrl + C to exit):
```

:::note info
ここまでの手順で、OpenAI API を使い **OpenAI** と**会話のラリー**を行うことができました。
:::
:::note warn
しかし、現在のプログラムでは自分の会話と **OpenAI** の会話の**表示が分かりづらい**です。
:::

## コードの修正 その3

**コンソール出力**に**色**を付けます。

Program.cs を修正します。

```sh
$ vim Program.cs
```

ファイルの内容

```csharp:Program.cs
using static System.Console;
using static System.ConsoleColor;
using static System.Environment;
using OpenAI_API;
namespace OpenAIApp {
    class Program {
        static async Task Main(string[] args) {
            // get an api key.
            string? apiKey = GetEnvironmentVariable("OPENAI_API_KEY");
            // create an api object.
            OpenAIAPI api = new(apiKey);
            // loop until a prompt is empty.
            string? prompt = null;
            do {
                // read a prompt from the console.
                ForegroundColor = Yellow;
                WriteLine("Enter a prompt (or press Ctrl + C to exit):");
                ResetColor();
                prompt = ReadLine();
                if (!string.IsNullOrEmpty(prompt)) {
                    // get a result from the api.
                    string? result = await api.Completions.GetCompletion(prompt);
                    // print the result.
                    ForegroundColor = Green;
                    WriteLine(result.Trim());
                }
            } while (!string.IsNullOrEmpty(prompt));
            // wait the console.
            ReadLine();
        }
    }
}
```

コンソールアプリをビルド・実行します。

```txt
$ dotnet run
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3206449/8a069d86-e3e7-e419-7f09-38251236002d.png)

:::note info
ここまでの手順で、OpenAI API を使い **OpenAI** と会話を楽しむプログラムを作成することができました。
:::

## まとめ

ローカル環境の Ubuntu で、OpenAI API を C# から使いコマンドラインから会話することができました。

:::note warn
実際の開発では、軽量なテキストエディタである **VS Code** や、**IDE (統合開発環境)** を使用して、.NET プログラムを開発することが一般的です。しかし、dotnet コマンドでビルドしたり、実行したりすることも、.NET 開発環境を理解する上で役立ちます。
:::

どうでしたか？ Window 11 の WSL Ubuntu に、.NET の開発環境を手軽に構築することができます。ぜひお試しください。今後も .NET の開発環境などを紹介していきますので、ぜひお楽しみにしてください。

## 参考資料

https://github.com/OkGoDoIt/OpenAI-API-dotnet