最近openAI发布了目前chatGPT所使用的模型gpt-3.5-Turbo,之前使用了text-davinci-003模型做了一个galgame的AI女友对话的demo。这次趁着新接口的发布,对这个demo也同步更新了模型调用的代码。本篇文章将分享一下,如何在unity里使用UnityWebRequest实现与openAI的接口调用以及信息处理的示例,希望能够帮助到有需要的朋友。
一、gpt-3.5-Turbo官方示例分析
①首先我们需要知道turbo接口api的调用地址,从官方文档中查询,找到了调用连接,如下:
api调用地址:https://api.openai.com/v1/chat/completions
②调用api所需要发送的报文
1)Header:
①ContentType:application/json
②Authorization:Bearer 你的apikey
2)发送的报文主体
从openAI官方网站查询了一下Turbo的调用示例,官方展示了一个Python的代码示例:
# Note: you need to be using OpenAI Python v0.27.0 for the code below to work
import openai
openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Who won the world series in 2020?"},
{"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
{"role": "user", "content": "Where was it played?"}
]
)
从官方示例可以发现,我们需要发送的报文,应该包含model的名称以及需要发送的messages,实际上从官方文档里看,可以发送的字段会更多,需要的话请大家自行查询吧。
我们可以发现,发送的报文里,包含有role角色定义,以及角色所发送的消息。
这里我们注意一下,role的可选值,必须是
口 system:在初始化的时候,设置AI的角色设定,可以理解为是人设。
口 user:我们发送的信息,放在这里
口 assistant:模型返回的信息,放在这里
需要注意的是,观察官方示例,可以发现,所有发送的信息以及反馈信息均被放置在报文里,这样可以让模型回答的时候,关联前文。
3)返回的报文
模型返回的报文格式如下所示,返回的信息以Json格式反馈。
{
"id": "chatcmpl-6pWU3qzNuTBLU7U0tUw6Nqa0oQhWbHF",
"object": "chat.completion",
"created": 1677737615,
"model": "gpt-3.5-turbo-0301",
"usage": {
"prompt_tokens": 39,
"completion_tokens": 35,
"total_tokens": 74
},
"choices": [
{
"message": {
"role": "assistant",
"content": "你好,我是AI助手!"
},
"finish_reason": "stop",
"index": 0
}
]
}
二、unity发送的报文格式
因为我们需要使用unity来访问api,所以需要修改一下报文主体。这里我们将需要发送的报文写成Json格式:
{
"model":"gpt-3.5-turbo",
"messages":[
{"role": "system", "content": "你是一个经验丰富的AI助手,能帮我处理很多计算机事务"},
{"role": "user", "content": "你好"},
{"role": "assistant", "content": "你好,我是一个语言模型AI"}
]
}
三、Unity中调用api的代码示例
本节内容将介绍一下如何使用UnityWebRequest实现调用gpt-3.5-Turbo的代码实现。
1)首先定义一下数据发送的类,用作保存待发送的报文信息。
[Serializable]public class PostData
{
public string model;
public List messages;
}
[Serializable]
public class SendData
{
public string role;
public string content;
public SendData() { }
public SendData(string _role,string _content) {
role = _role;
content = _content;
}
}
2)定义一下返回数据的类,用于保存模型返回的数据信息
[Serializable]
public class MessageBack
{
public string id;
public string created;
public string model;
public List choices;
}
[Serializable]
public class MessageBody
{
public Message message;
public string finish_reason;
public string index;
}
[Serializable]
public class Message
{
public string role;
public string content;
}
3)unity使用UnityWebRequest调用api的代码示例
调用api的功能写成一个方法,输入的参数包含待发送的文本、openAI的密钥以及回调函数,方法里需要用的一些变量,我放在脚本里做了定义。
以下是完整的代码示例:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class GptTurboScript : MonoBehaviour
{
///
/// api地址
///
public string m_ApiUrl = "https://api.openai.com/v1/chat/completions";
///
/// gpt-3.5-turbo
///
public string m_gptModel = "gpt-3.5-turbo";
///
/// 缓存对话
///
[SerializeField]public List m_DataList = new List();
///
/// AI人设
///
public string Prompt;
private void Start()
{
//运行时,添加人设
m_DataList.Add(new SendData("system", Prompt));
}
///
/// 调用接口
///
///
///
///
///
public IEnumerator GetPostData(string _postWord,string _openAI_Key, System.Action _callback)
{
//缓存发送的信息列表
m_DataList.Add(new SendData("user", _postWord));
using (UnityWebRequest request = new UnityWebRequest(m_ApiUrl, "POST"))
{
PostData _postData = new PostData
{
model = m_gptModel,
messages = m_DataList
};
string _jsonText = JsonUtility.ToJson(_postData);
byte[] data = System.Text.Encoding.UTF8.GetBytes(_jsonText);
request.uploadHandler = (UploadHandler)new UploadHandlerRaw(data);
request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
request.SetRequestHeader("Authorization", string.Format("Bearer {0}", _openAI_Key));
yield return request.SendWebRequest();
if (request.responseCode == 200)
{
string _msg = request.downloadHandler.text;
MessageBack _textback = JsonUtility.FromJson(_msg);
if (_textback != null && _textback.choices.Count > 0)
{
string _backMsg = _textback.choices[0].message.content;
//添加记录
m_DataList.Add(new SendData("assistant", _backMsg));
_callback(_backMsg);
}
}
}
}
#region 数据包
[Serializable]public class PostData
{
public string model;
public List messages;
}
[Serializable]
public class SendData
{
public string role;
public string content;
public SendData() { }
public SendData(string _role,string _content) {
role = _role;
content = _content;
}
}
[Serializable]
public class MessageBack
{
public string id;
public string created;
public string model;
public List choices;
}
[Serializable]
public class MessageBody
{
public Message message;
public string finish_reason;
public string index;
}
[Serializable]
public class Message
{
public string role;
public string content;
}
#endregion
}
本文的代码示例是基于我前段时间做的一个使用chatGPT实现的二次元AI女友galgame的demo提取的,源码包提供了text-davinci-003以及gpt-3.5-Turbo两个模型的demo示例,源码已经发布在Gitee上,需要使用的朋友,可以自行下载参考。
Gitee地址:chatGPTAIGirlFrienchatGPTAIGirlFriendSample: 使用chatGPT+unity+Azure+VRoid制作的简单的AI女友(老婆)对话机器人的demo。