Search code examples
c#unity-game-enginechatgpt-api

How to implement ChatGPT into Unity?


I am currently trying to implement the capabilities of ChatGPT into my unity project using C#.

I have JSON classes for wrapping my request and unwrapping it, and I successfully managed to implement it, so that whenever I send a request I'm getting a response. The problem is that the responses I get are totally random. For example, I'd ask it 'What is a verb?' and it would give me a response telling me about factors contributing towards a successful podcast. Not sure if my configuration is wrong or what exactly is going on, so I'll post the classes below.

Request class:

namespace OpenAIAPIManagement
{
    [Serializable]
    public class OpenAIAPIRequest
    {
        public string model = "gpt-3.5-turbo";
        public Message[] messages;
        public float temperature = 0.5f;
        public int max_tokens = 50;
        public float top_p = 1f;
        public float presence_penalty = 0f;
        public float frequency_penalty = 0f;

        public OpenAIAPIRequest(string model_, Message[] messages_, float temperature_, int max_tokens_, float top_p_, float presence_penalty_, float frequency_penalty_)
        {
            this.model = model_;
            this.messages = messages_;
            this.temperature = temperature_;
            this.max_tokens = max_tokens_;
            this.top_p = top_p_;
            this.presence_penalty = presence_penalty_;
            this.frequency_penalty = frequency_penalty_;
        }
    }

    [Serializable]
    public class Message
    {
        public string role = "user";
        public string content = "What is your purpose?";

        public Message(string role_, string content_)
        {
            this.role = role_;
            this.content = content_;
        }
    }
}

The way I send the response:

public static async Task<Message> SendMessageToChatGPT(Message[] message, float temperature, int max_tokens, float top_p, float presence_penalty, float frequency_penalty)
    {
        string request = OpenAIAPIManager.SerializeAPIRequest("gpt-4", message, temperature, max_tokens, top_p, presence_penalty, frequency_penalty);

        HttpClient client = new HttpClient();
        client.DefaultRequestHeaders.Add("Authorization", $"Bearer {_apiKey}");
        HttpResponseMessage response = await client.PostAsync(_apiURL, new StringContent(request, System.Text.Encoding.UTF8, "application/json"));

        if (response.IsSuccessStatusCode)
        {
            Message responseMessage = OpenAIAPIManager.DeserializeAPIResponse(await response.Content.ReadAsStringAsync()).choices[0].message;
            Debug.Log("ChatGPT: " + responseMessage.content);
            return await Task.FromResult<Message>(responseMessage);
        }
        else
        {
            return await Task.FromResult<Message>(new Message("Error", "Status" + response.StatusCode));
        }
}

And finally taking the string out of the text field:

public async void ProcessMessageFromInputField()
{
    if (_userInput && !string.IsNullOrWhiteSpace(_userInput.text))
    {
        _chatData.Clear();
        _chatData.Add(_userInput.text + _userPostfix);
        PostMessageToContentPanel(_chatData[0]);
        _userInput.text = "";
        Message userMessage = new Message("user", _userInput.text);
        Message chatAgentResponse = await OpenAIAPIManager.SendMessageToChatGPT(new Message[]{userMessage}, 0.7f, 256, 1f, 0f, 0f);
        PostMessageToContentPanel(chatAgentResponse.content + _aiPostfix);
    }
}

I have read the API and configured it to the best of my abilities, but if I'm missing something.


Solution

  • You need to provide a prompt to tell the AI model what kind of conversation you want it to have with you. At the moment you're just sending the ChatGPT API a single message at a time:

    Message chatAgentResponse = await OpenAIAPIManager.SendMessageToChatGPT(new Message[]{userMessage}, 0.7f, 256, 1f, 0f, 0f);
    

    You're initialising a new list of messages as part of each request and it only contains the message you want to send to the chat model. You should craft a message with the "system" role explaining what kind of conversation you want the AI to complete your chat with, e.g.

    Message promptMessage = new Message("system", "You are an AI participant in a chess game. Your opponent is having a conversation with you. Respond professionally as though you are taking part in a renowned international chess tournament, and there is a significant amount of publicity surrounding this match. The whole world is watching.");
    Message[] messages = {promptMessage, userMessage};
    Message chatAgentResponse = await OpenAIAPIManager.SendMessageToChatGPT(messages, 0.7f, 256, 1f, 0f, 0f);
    

    To get the AI model to continue the conversation and remember what has already been said, you'll need to append the response message from the API to this list, then append your user's reply, and keep sending the full list with every request. Have a look at the chat completion guide here, the example API call demonstrates this well: https://platform.openai.com/docs/guides/chat/introduction

    However, you'll also need to be aware of the maximum number of tokens (basically words, but not exactly) you can use with the model you have chosen. This will grow as the conversation evolves, and eventually you'll run out: https://platform.openai.com/docs/api-reference/chat/create#chat/create-max_tokens. For example, gpt-4-32k supports 8 times as many tokens as gpt-3.5-turbo, but isn't publicly available yet, and will be much more expensive when it is initially released. https://platform.openai.com/docs/models/gpt-4