A client library of ChatGPT chat completion API for Unity.
See also official document and API reference.
Add following dependencies to your /Packages/mainfest.json
.
{
"dependencies": {
"com.mochineko.chatgpt-api": "https://github.com/mochi-neko/ChatGPT-API-unity.git?path=/Assets/Mochineko/ChatGPT_API#0.7.3",
...
}
}
- Generate API key on OpenAI. (Take care your API key, this is a secret information then you should not open.)
- You can specify chat model. (Available models are defined by
Model
.) - Create an instance of
ChatCompletionAPIConnection
with API key and chat model. (This instance memorizes old messages in session.) - You can set system message (prompt) to instruct assistant with your situation by constructor of
ChatCompletionAPIConnection
. - Input user message and call
ChatCompletionAPIConnection.CompleteChatAsync()
. - Response message is in
ChatCompletionResponseBody.ResultMessage
(=ChatCompletionResponseBody.Choices[0].Message.Content
).
An essential sample code with UniTask is as follows:
#nullable enable
using System;
using System.Threading;
using Cysharp.Threading.Tasks;
using Mochineko.ChatGPT_API.Memories;
using UnityEngine;
namespace Mochineko.ChatGPT_API.Samples
{
/// <summary>
/// A sample component to complete chat by ChatGPT API on Unity.
/// </summary>
public sealed class ChatCompletionSample : MonoBehaviour
{
/// <summary>
/// API key generated by OpenAPI.
/// </summary>
[SerializeField] private string apiKey = string.Empty;
/// <summary>
/// System message to instruct assistant.
/// </summary>
[SerializeField, TextArea] private string systemMessage = string.Empty;
/// <summary>
/// Message sent to ChatGPT API.
/// </summary>
[SerializeField, TextArea] private string message = string.Empty;
/// <summary>
/// Max number of chat memory of queue.
/// </summary>
[SerializeField] private int maxMemoryCount = 20;
private ChatCompletionAPIConnection? connection;
private IChatMemory? memory;
private void Start()
{
// API Key must be set.
if (string.IsNullOrEmpty(apiKey))
{
Debug.LogError("OpenAI API key must be set.");
return;
}
memory = new FiniteQueueChatMemory(maxMemoryCount);
// Create instance of ChatGPTConnection with specifying chat model.
connection = new ChatCompletionAPIConnection(
apiKey,
memory,
systemMessage);
}
[ContextMenu(nameof(SendChat))]
public void SendChat()
{
SendChatAsync(this.GetCancellationTokenOnDestroy()).Forget();
}
[ContextMenu(nameof(ClearChatMemory))]
public void ClearChatMemory()
{
memory?.ClearAllMessages();
}
private async UniTask SendChatAsync(CancellationToken cancellationToken)
{
// Validations
if (connection == null)
{
Debug.LogError($"[ChatGPT_API.Samples] Connection is null.");
return;
}
if (string.IsNullOrEmpty(message))
{
Debug.LogError($"[ChatGPT_API.Samples] Chat content is empty.");
return;
}
ChatCompletionResponseBody response;
try
{
await UniTask.SwitchToThreadPool();
// Create message by ChatGPT chat completion API.
response = await connection.CompleteChatAsync(
message,
cancellationToken);
}
catch (Exception e)
{
// Exceptions should be caught.
Debug.LogException(e);
return;
}
await UniTask.SwitchToMainThread(cancellationToken);
// Log chat completion result.
Debug.Log($"[ChatGPT_API.Samples] Result:\n{response.ResultMessage}");
}
}
}
See also Sample.
See RelentChatCompletionAPIConnection
and RelentChatCompletionSample
using Relent.
You can use API with explicit error handling, retry, timeout, bulkhead, and so on.
{
"dependencies": {
"com.mochineko.chatgpt-api.relent": "https://github.com/mochi-neko/ChatGPT-API-unity.git?path=/Assets/Mochineko/ChatGPT_API.Relent#0.7.3",
"com.mochineko.chatgpt-api": "https://github.com/mochi-neko/ChatGPT-API-unity.git?path=/Assets/Mochineko/ChatGPT_API#0.7.3",
"com.mochineko.relent": "https://github.com/mochi-neko/Relent.git?path=/Assets/Mochineko/Relent#0.2.0",
"com.cysharp.unitask": "https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask",
...
}
}
You can calculate token length of text
by TiktokenSharp.Tiktoken.Encode(string)
as follows:
using TiktokenSharp;
private int CalculateTokenLength()
{
string text = "A text that you want to calculate token length.";
// Specify model name.
Tiktoken tiktoken = TikToken.EncodingForModel("gpt-3.5-turbo");
// Encoding is tokenizing.
int[] tokens = tikToken.Encode(text);
return tokens.Length;
}
If you want to calculate on Unity editor,
please use ItemuMenu > Mochineko > TiktokenEditor
window.
You can use customized memories of chat by implementing IChatMemory
interface.
Presets are available:
FiniteQueueChatMemory
- A queue that has max number of messages.
FiniteQueueWithFixedPromptsChatMemory
- A queue that has max number of user/assistant messages and free number of prompts (system messages).
FiniteTokenLengthQueueChatMemory
- A queue that has max number of token lenght of all messages.
FiniteTokenLengthQueueWithFixedPromptsChatMemory
- A queue that has max number of token lenght of user/assistant messages and free number of prompts (system messages).
See streaming sample.
You can await foreach as follows:
var builder = new StringBuilder();
// Receive enumerable from ChatGPT chat completion API.
var enumerable = await connection.CompleteChatAsStreamAsync(
message,
cancellationToken);
await foreach (var chunk in enumerable.WithCancellation(cancellationToken))
{
// First chunk has only "role" element.
if (chunk.Choices[0].Delta.Content is null)
{
Debug.Log($"[ChatGPT_API.Samples] Role:{chunk.Choices[0].Delta.Role}.");
continue;
}
var delta = chunk.Choices[0].Delta.Content;
builder.Append(delta);
Debug.Log($"[ChatGPT_API.Samples] Delta:{delta}, Current:{builder}");
}
// Log chat completion result.
Debug.Log($"[ChatGPT_API.Samples] Completed: \n{builder}");
.
- Define function with JSON schema.
- Specify function by request parameters.
- Call chat completion API.
- Use
result.Choices[0].Message.FunctionCall
See FunctionCalling()
in test code.
See CHANGELOG.
See NOTICE.
Licensed under the MIT license.