Awesome
ChatGPT-API-unity
A client library of ChatGPT chat completion API for Unity.
See also official document and API reference.
How to import by Unity Package Manager
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",
...
}
}
How to use chat completion by ChatGPT API
- 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.
How to use chat completion by ChatGPT API more resilient
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",
...
}
}
How to calculate token length of text in local
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.
How to customize chat memories
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).
How to stream response
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}");
.
How to use function calling
- 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.
Changelog
See CHANGELOG.
3rd Party Notices
See NOTICE.
License
Licensed under the MIT license.