项目实训——Unity接入DeepSeek等大模型(1)
本次项目实训我主要负责Unity3D开发AI模拟对话的功能与前端开发部分,因为Unity部分是以WebGL形式嵌入前端,因此首先进行这一部分的开发。我准备接入DeepSeek、ChatGPT和豆包AI,首先获取了需要使用的测试Key,接下来完成模型接入的相关设置。
·
本次项目实训我主要负责Unity3D开发AI模拟对话的功能与前端开发部分,因为Unity部分是以WebGL形式嵌入前端,因此首先进行这一部分的开发。
我准备接入DeepSeek、ChatGPT和豆包AI,首先获取了需要使用的测试Key,接下来完成模型接入的相关设置。
大模型对话管理脚本
LLM父脚本和DeepSeek调用部分
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using UnityEngine;
public class LLM : MonoBehaviour
{
/// <summary>
/// api地址
/// </summary>
[SerializeField] protected string url;
/// <summary>
/// 提示词,与消息一起发送
/// </summary>
[Header("发送的提示词设定")]
[SerializeField] protected string m_Prompt = string.Empty;
/// <summary>
/// 语言
/// </summary
[Header("设置回复的语言")]
[SerializeField] protected string lan = "中文";
/// <summary>
/// 上下文保留条数
/// </summary>
[Header("上下文保留条数")]
[SerializeField] protected int m_HistoryKeepCount = 15;
/// <summary>
/// 缓存对话
/// </summary>
[SerializeField] public List<SendData> m_DataList = new List<SendData>();
/// <summary>
/// 计算方法调用的时间
/// </summary>
[SerializeField] protected Stopwatch stopwatch = new Stopwatch();
/// <summary>
/// 发送消息
/// </summary>
public virtual void PostMsg(string _msg, Action<string> _callback)
{
//上下文条数设置
CheckHistory();
//提示词处理
string message = "当前为角色的人物设定:" + m_Prompt +
" 回答的语言:" + lan +
" 接下来是我的提问:" + _msg;
//缓存发送的信息列表
m_DataList.Add(new SendData("user", message));
StartCoroutine(Request(message, _callback));
}
public virtual IEnumerator Request(string _postWord, System.Action<string> _callback)
{
yield return new WaitForEndOfFrame();
}
/// <summary>
/// 设置保留的上下文条数,防止太长
/// </summary>
public virtual void CheckHistory()
{
if (m_DataList.Count > m_HistoryKeepCount)
{
m_DataList.RemoveAt(0);
}
}
[Serializable]
public class SendData
{
[SerializeField] public string role;
[SerializeField] public string content;
public SendData() { }
public SendData(string _role, string _content)
{
role = _role;
content = _content;
}
}
}
LLM父类定义了基础的成员变量,任何大模型都共有的一些属性:
- url:服务器接口地址,虽然在这个脚本里没有实际用到,但通常用于指定LLM API的地址。
- m_Prompt:预设的提示词(Prompt),在发送消息时附在用户输入前,用来设定AI的行为。
- lan:回复使用的语言,比如默认是“中文”,可以用来提示LLM用特定语言回答。
- m_HistoryKeepCount:保留的上下文消息数量,默认是15条。超出后会自动删除最旧的记录,防止上下文过长导致性能问题。
- m_DataList:缓存对话内容的列表,每次用户提问或系统响应都会保存下来,方便后续管理上下文。
- stopwatch:计时器(System.Diagnostics.Stopwatch),用来统计接口调用耗时。
同时定义了一些核心方法(Functions):
-
PostMsg(string _msg, Action<string> _callback)
- 对外接口,发送用户消息。
- 会调用 CheckHistory() 先检查对话记录条数。
- 然后将提示词、语言、用户输入拼接成最终发送内容。
- 把这条信息添加到缓存列表 m_DataList。
- 最后启动协程 Request() 发起请求(实际请求逻辑留空,待子类实现)。
-
IEnumerator Request(string _postWord, System.Action<string> _callback)
- 虚拟方法(virtual),目前只等待一帧(WaitForEndOfFrame())。
- 子类去重写这个方法,实现具体的网络请求逻辑(比如用UnityWebRequest去访问API)。
-
CheckHistory():检查 m_DataList 的数量,如果超过设定的 m_HistoryKeepCount,就移除最早的消息,保持上下文不过长。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class ChatDeepSeek : LLM
{
public ChatDeepSeek()
{
url = "https://api.deepseek.com/v1/chat/completions";
}
/// <summary>
/// api key
/// </summary>
[SerializeField] private string api_key;
/// <summary>
/// AI设定
/// </summary>
public string m_SystemSetting = string.Empty;
/// <summary>
/// 模型名称
/// </summary>
public string m_ModelName = "deepseek-chat";
private void Start()
{
//运行时,添加AI设定
m_DataList.Add(new SendData("system", m_SystemSetting));
}
/// <summary>
/// 发送消息
/// </summary>
/// <returns></returns>
public override void PostMsg(string _msg, Action<string> _callback)
{
base.PostMsg(_msg, _callback);
}
/// <summary>
/// 调用接口
/// </summary>
/// <param name="_postWord"></param>
/// <param name="_callback"></param>
/// <returns></returns>
public override IEnumerator Request(string _postWord, System.Action<string> _callback)
{
stopwatch.Restart();
using (UnityWebRequest request = new UnityWebRequest(url, "POST"))
{
PostData _postData = new PostData
{
model = m_ModelName,
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}", api_key));
yield return request.SendWebRequest();
if (request.responseCode == 200)
{
string _msgBack = request.downloadHandler.text;
MessageBack _textback = JsonUtility.FromJson<MessageBack>(_msgBack);
if (_textback != null && _textback.choices.Count > 0)
{
string _backMsg = _textback.choices[0].message.content;
//添加记录
m_DataList.Add(new SendData("assistant", _backMsg));
_callback(_backMsg);
}
}
else
{
string _msgBack = request.downloadHandler.text;
Debug.LogError(_msgBack);
}
stopwatch.Stop();
Debug.Log("DeepSeek耗时:" + stopwatch.Elapsed.TotalSeconds);
}
}
#region 数据包
[Serializable]
public class PostData
{
public string model;
public List<SendData> messages;
public bool stream = false;
}
[Serializable]
public class MessageBack
{
public string id;
public string created;
public string model;
public List<MessageBody> 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
}
基本变量:
- api_key :你的 DeepSeek API 密钥(用来鉴权)。
- m_SystemSetting :初始的系统提示词(比如定义AI性格、风格)。
- m_ModelName :模型名,默认是 "deepseek-chat"。
核心方法:重写Request()协程
Request 方法向 DeepSeek API 发送带有对话历史的POST请求,设置认证信息,接收并解析AI回复,更新本地记录,通过回调返回结果,同时统计请求耗时。
场景交互
模型调用之后需要可视化的提供交互方法,为输入框配置响应时间,以便于将输入的提问打包成数据包提交给目标服务器,提问输入包括文本和语音两种方式,这里之后会调用讯飞的语音转文字接口进行完善。
/// <summary>
/// 发送信息
/// </summary>
public void SendData()
{
if (m_InputWord.text.Equals(""))
return;
if (m_CreateVoiceMode)//合成输入为语音
{
CallBack(m_InputWord.text);
m_InputWord.text = "";
return;
}
//添加记录聊天
m_ChatHistory.Add(m_InputWord.text);
//提示词
string _msg = m_InputWord.text;
//发送数据
m_ChatSettings.m_ChatModel.PostMsg(_msg, CallBack);
m_InputWord.text = "";
m_TextBack.text = "正在思考中...";
//切换思考动作
SetAnimator("state", 1);
}
实现效果
更多推荐
所有评论(0)