【GPT-3×Unity】会話できるAI

# はじめに
こんにちはKuniと申します。今回、withARハッカソンというハッカソンに参加させていただき、そこで使用したAIとの会話をUnityに実装した方法を書きたいと思います。withARハッカソンについては下記のリンクを参照してください。

https://withar.jp/work

# 使用するAPI
今回使用するAPIはOpenAIから提供されているAPIを使用します。OpenAIは最近、自然な応答するとTwitterで話題になったChatGPTを提供している企業です。ChatGPT自体は(12\19現在)APIが公開されていないため、代わりに近い動作を行うGPT-3というモデルを使用したいと思います。下記にAPIの詳細が記載されております。

https://beta.openai.com/docs/introduction/overview

# 開発環境
・Unity 2021.3.8f
・Windows 11(Windows10でも動作確認済み)
・OpenAI API 1.2.0

# Unity使用前の準備
### OpenAIのアカウント作成
APIを使用するためには、OpenAIのアカウントを作成する必要があります。こちらのサイトの右上からすでにアカウントをお持ちの方はLogInを、初めて作られる方はSignUpから作成してください。

https://openai.com/api/

### API Keyの作成
こちらのリンクからAPI Keyを作成してください。Create New Secret Keyから新しく作成することができます。こちらはこの後APIを使用するときに必要となります。
注意：一度ポップアップのウィンドウを消してしまうと2度とそのAPI Keyを見ることができないので、メモなどをしておくことをお勧めします。

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

# UnityにGPT-3の導入
### NugetからOpenAIのファイルをダウンロード
実際にUnityで構築する方法を解説していきたいと思います。
まず、下記のサイトの右の方にあるDownload Packageからダウンロードをしてください。

https://www.nuget.org/packages/OpenAI

![openAI01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517131/a5b8e95d-db0b-a5da-5c27-b238ab904940.png)

そしてそのファイルの拡張子を.nupkgから.zipに変更してください。
そうするとWindowsで展開できるようになります。
展開を行うと以下の画像のようになっていると思います。

![スクリーンショット_20221223_225559.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517131/e3c35e17-9c6b-24da-8cf0-597f69c21e10.png)

この中のlibフォルダ内のnetstandard2.0フォルダ内にOpenAI_API.dllがあることを確認します。

### もう一つのファイルをダウンロード
OpenAIのAPIだけをUnityにインポートするとエラーが発生します。それをしないためにMicrosoft.Bcl.AsyncInterfaces.dllというファイルをダウンロードします。
下記のサイトから先ほどと同じ方法でダウンロード、展開を行います。

https://www.nuget.org/packages/Microsoft.Bcl.AsyncInterfaces

### Unityにインポート
先ほどダウンロードした二つのファイルをUnityにインポートします。
pluginsというファイル内に二つとも配置をします。

`Assembly 'Assets/Plugins/OpenAI_API.dll' will not be loaded due to errors:
OpenAI_API references strong named Newtonsoft.Json Assembly references: 12.0.0.0 Found in project: 13.0.0.0.
Assembly Version Validation can be disabled in Player Settings "Assembly Version Validation"`
というエラーが発生するので、このエラーの通りにPlayer SettingsのAssembly Version Validationを無効化します。
こちらのエラーの正しい解消法がわからないのでわかる方がいらっしゃいましたら教えていただけると幸いです。

![openAI03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517131/3bc2d30c-feba-450c-9b12-c03b8d3960be.png)

### スクリプト
下記のスクリプトを記述してください。今回はInputTextから入力された文字をGPT-3に渡して、そこから返ってきたものをoutputTextで表示するようにしています。InputtextはInputField、outputTextはTMPのTextを使用しています。

```c#:test.cs
using OpenAI_API;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using UnityEngine;
using TMPro;

public class Test : MonoBehaviour
{
    //出力先のText
    [SerializeField]
    private TextMeshProUGUI _outputText;
    //入力に使用するInputField
    [SerializeField]
    private TMP_InputField _inputText;
    
    async Task StartAsync()
    {
        try
        {
            /*OpenApiの作成　apikeyはAPIを使用する際に必要なKey
             * 下記のサイトでシークレットキーを発行できる
             * https://beta.openai.com/account/api-keys
             * 
             * Engine.○○は言語処理を行うエンジンの指定
             * 下記で確認できる
             * https://beta.openai.com/docs/models/overview
             * ""で囲ってモデルの指定もできる
             * 今回は会話が可能なモデルを使用している。
             */
            //var api = new OpenAI_API.OpenAIAPI(apikey, Engine.Davinci);
            var api = new OpenAI_API.OpenAIAPI("your apikey", "text-davinci-003");

            //エンジンに送信している。_imputTextの部分で入力された文章
            //temperature＝使用するサンプリング数。明確な答えがある場合は0に近い値。より創造的なものを求める場合は0.9に近い値
            var result = await api.Completions.CreateCompletionAsync(_inputText.text, temperature: 0.9);
            
            //結果の出力
            Debug.Log("result=" + result.ToString());
            _outputText.text = result.ToString();
        }
        catch (System.Exception e)
        {
            Debug.LogError(e.Message);
        }
    }

    //InputFieldが確定された場合に実行される
    public void StartAIText()
    {
        var task = StartAsync();
    }
}
```

このスクリプトを何かしらのオブジェクトにAdd Componentを行い、シーン上にInputFieldとTextを設置してください。
そして、InputFieldのOn End Editに新しくイベントを作成し、そこにStartAITextを設定することで動作します。

# 結果
https://youtu.be/XCsU9f0vsqo

# 最後に
インタラクティブに反応してくれるAIを使用するとコンテンツの可能性が無限大に広がるなと思っています。
簡単に環境を構築できるので是非皆さんもやってみてください。
記事の内容で質問やコメントがございましたらDMをしていただけると幸いです。
そして、Twitterをフォローしていただけると嬉しいです！