なんか新しいゲームが作れそうな予感は感じた。クエスト受注とかChat GPTにさせれば、シナリオかけなくてもゲーム作れそう。
アカウント作成とAPI Keyの取得
Chat GPTを使う前準備!SDKとかいらないのはいいところよね。
OpenAIにログインをしてアカウントを作成
下記リンクへアクセスして、まずはOpenAIのアカウントを作成します。
https://platform.openai.com/overview
API keyを取得する
右上の自分のアイコンっぽいところをクリックするとポップアップ表示が出るので、View API keysを選択すると下図のページが開きます。この中で、「Create new secret key」ボタンを押して、新しいAPI keyを作成します。
ここで表示されるAPI keysは後で再確認できなくなるので、必ずこのタイミングで控えるようにしてください。
注意書きにも「再びは、見られまへんで!」と書かれています!
なお、表示されているキーは削除済みなので、これ使わないように!!
Chat GPTとやりとりをするスクリプト
やり取りするのに特別なSDKとかはいらないので、スクリプトを用意してしまいましょう。ここでは冒険者ギルドの受付の人に挨拶をする、というシチュエーションでテストしたいと思います。
スクリプト
ちょっと長い!長い理由はChatGPTとの連絡をするためのお約束のデータを宣言する必要があるからです。実際にゲームを作る場合は、別のファイルに分けた方が良いと思います。
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
public class TestChat : MonoBehaviour
{
#region 必要なクラスの定義など
[System.Serializable]
public class MessageModel
{
public string role;
public string content;
}
[System.Serializable]
public class CompletionRequestModel
{
public string model;
public List<MessageModel> messages;
}
[System.Serializable]
public class ChatGPTRecieveModel
{
public string id;
public string @object;
public int created;
public Choice[] choices;
public Usage usage;
[System.Serializable]
public class Choice
{
public int index;
public MessageModel message;
public string finish_reason;
}
[System.Serializable]
public class Usage
{
public int prompt_tokens;
public int completion_tokens;
public int total_tokens;
}
}
#endregion
private MessageModel assistantModel = new()
{
role = "system",
content = "あなたは冒険者ギルドの受付です。"
};
private readonly string apiKey = "ここに自分のAPI keyを入れてください";
private List<MessageModel> communicationHistory = new();
void Start()
{
communicationHistory.Add(assistantModel);
MessageSubmit("はじめまして");
}
private void Communication(string newMessage, Action<MessageModel> result)
{
Debug.Log(newMessage);
communicationHistory.Add(new MessageModel()
{
role = "user",
content = newMessage
});
var apiUrl = "https://api.openai.com/v1/chat/completions";
var jsonOptions = JsonUtility.ToJson(
new CompletionRequestModel()
{
model = "gpt-3.5-turbo",
messages = communicationHistory
}, true);
var headers = new Dictionary<string, string>
{
{"Authorization", "Bearer " + apiKey},
{"Content-type", "application/json"},
{"X-Slack-No-Retry", "1"}
};
var request = new UnityWebRequest(apiUrl, "POST")
{
uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(jsonOptions)),
downloadHandler = new DownloadHandlerBuffer()
};
foreach (var header in headers)
{
request.SetRequestHeader(header.Key, header.Value);
}
var operation = request.SendWebRequest();
operation.completed += _ =>
{
if (operation.webRequest.result == UnityWebRequest.Result.ConnectionError ||
operation.webRequest.result == UnityWebRequest.Result.ProtocolError)
{
Debug.LogError(operation.webRequest.error);
throw new Exception();
}
else
{
var responseString = operation.webRequest.downloadHandler.text;
var responseObject = JsonUtility.FromJson<ChatGPTRecieveModel>(responseString);
communicationHistory.Add(responseObject.choices[0].message);
Debug.Log(responseObject.choices[0].message.content);
}
request.Dispose();
};
}
public void MessageSubmit(string sendMessage)
{
Communication(sendMessage, (result) =>
{
Debug.Log( result.content );
});
}
}
スクリプトを貼り付けてログを確認
あとは空のGameObjectに先のスクリプトを貼り付けて実行し、コンソールのログを確認してみてください。下図のような返答が返ってきたら成功です。
エラーパターン:400 Bad Request
メッセージ投げた後に、400エラーが発生する場合は、各クラスの変数名が違う可能性があります。Jsonデータでやり取りをする都合上、データの構造が合っていても、変数名が異なる場合は解釈が行われません。送信・受信両方のデータで一致が求められますので、注意してください。
エラーパターン:401 Unauthorized
こっちはAPI keyが間違ってる可能性が高いです。空白が入ってないかなど、注意して入力してください。まぁ確認する方法は無いので、メモしてない場合は作り直すしかないかもしれませんね。
コメント