Unity接入DeepSeek实现AI对话功能
目录
一、DeepSeek简介
1.文档
2.必要准备
(1)获取API密钥
(2)API接口地址
(3)了解Token机制
二、模型与UI
三、脚本与参数设置
对话参数设置
NPC角色配置
角色交互脚本
使用说明
一、DeepSeek简介
DeepSeek是由杭州深度求索公司研发的一款国产开源大语言模型。这款模型于2025年1月20日正式发布,其独特之处在于:在训练数据标注量极少的情况下,仍能显著提升模型推理能力。在数学运算、代码生成和自然语言理解等核心任务上,其表现已与OpenAI o1正式版相当。这款兼具高性能与普惠性的AI模型,特别适合开发者群体使用。接下来我们将通过一个简单的Unity调用示例,为大家展示如何快速接入和使用DeepSeek的强大功能。
1.文档
要了解如何编写接入DeepSeek的代码和设置相关参数,首先要来学习它的文档。DeepSeek的官方API文档地址是:https://api-docs.deepseek.com/zh-cn/
我们希望使用它的对话API,文档中给出了一些示例:
文档没有提供C#脚本示例,不过它提供了重要参数的信息,之后我们可以让AI协助补全脚本。
在“对话补全”(https://api-docs.deepseek.com/zh-cn/api/create-chat-completion)中,提供了更详细的参数含义和示例。
2.必要准备
(1)获取API密钥
在Unity中集成DeepSeek服务前,需先获取API密钥。请访问以下地址申请:https://platform.deepseek.com/api_keys
重要提示:密钥仅在申请成功时完整显示一次,后续只能查看基本信息。请务必妥善保存,建议存储在本地安全位置。
(2)API接口地址
调用DeepSeek对话补全功能的API端点为:https://api.deepseek.com/v1/chat/completions
(3)了解Token机制
每个DeepSeek新账户将获赠10元初始额度,可用于兑换token。
token是计费基础单元,相当于文本处理中的"字词"单位:
- 1个中文词语 ≈ 1 token
- 1个英文单词 ≈ 1 token
- 1个数字或符号 ≈ 1 token
常见换算比例:
- 英文字符:1个≈0.3 token
- 中文字符:1个≈0.6 token
当前DeepSeek的计费标准如下:
建议大家根据自己的需求来估算消耗的token和费用,在控制台可以查看余额:https://platform.deepseek.com/
二、模型与UI
示例中,我们使用Unity-Chan模型作为对话角色,该模型可以从Unity资源商店中免费下载。
同时,还需要准备简单的UI,如图:
下方的提问框是用InputField组件制作的,右上方的回答框是用ScrollView组件搭配Text组件制作的。为了方便显示更多内容,要将ScrollView的窗口做大一些。美观起见,隐藏了滚动条。
三、脚本与参数设置
我尝试使用DeepSeek生成相关脚本时,最初版本可能会出现报错。这时就需要根据报错信息让AI进行修改,并要求其严格遵循官方文档来编写代码。
以下是对话管理器脚本:
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
using System.Collections.Generic;public class DeepSeekDialogueManager : MonoBehaviour {// API配置[Header("API Settings")][SerializeField] private string apiKey = "在此处填入你申请的API密钥"; // DeepSeek API密钥[SerializeField] private string modelName = "deepseek-chat"; // 使用的模型名称[SerializeField] private string apiUrl = "https://api.deepseek.com/v1/chat/completions"; // API请求地址// 对话参数[Header("Dialogue Settings")][Range(0, 2)] public float temperature = 0.7f; // 控制生成文本的随机性(0-2,值越高越随机)[Range(1, 1000)] public int maxTokens = 150; // 生成的最大令牌数(控制回复长度)// 角色设定[System.Serializable]public class NPCCharacter {public string name;[TextArea(3, 10)]public string personalityPrompt = "你是虚拟人物Unity-Chan,是个性格活泼,聪明可爱的女生。擅长Unity和C#编程知识。";}[SerializeField] public NPCCharacter npcCharacter;// 回调委托,用于异步处理API响应public delegate void DialogueCallback(string response, bool isSuccess);/// <summary>/// 发送对话请求/// </summary>/// <param name="userMessage">玩家输入内容</param>/// <param name="callback">处理API响应的回调函数</param>public void SendDialogueRequest(string userMessage, DialogueCallback callback) {StartCoroutine(ProcessDialogueRequest(userMessage, callback));}private IEnumerator ProcessDialogueRequest(string userInput, DialogueCallback callback) {// 构建消息列表List<Message> messages = new List<Message> {new Message { role = "system", content = npcCharacter.personalityPrompt },new Message { role = "user", content = userInput }};// 构建请求体ChatRequest requestBody = new ChatRequest {model = modelName,messages = messages,temperature = temperature,max_tokens = maxTokens};string jsonBody = JsonUtility.ToJson(requestBody);Debug.Log("Sending JSON: " + jsonBody);UnityWebRequest request = CreateWebRequest(jsonBody);yield return request.SendWebRequest();if (IsRequestError(request)) {Debug.LogError($"API Error: {request.responseCode}\n{request.downloadHandler.text}");callback?.Invoke(null, false);yield break;}DeepSeekResponse response = ParseResponse(request.downloadHandler.text);if (response != null && response.choices.Length > 0) {string npcReply = response.choices[0].message.content;callback?.Invoke(npcReply, true);} else {callback?.Invoke(name + "(陷入沉默)", false);}}private UnityWebRequest CreateWebRequest(string jsonBody) {byte[] bodyRaw = System.Text.Encoding.UTF8.GetBytes(jsonBody);var request = new UnityWebRequest(apiUrl, "POST");request.uploadHandler = new UploadHandlerRaw(bodyRaw);request.downloadHandler = new DownloadHandlerBuffer();request.SetRequestHeader("Content-Type", "application/json");request.SetRequestHeader("Authorization", $"Bearer {apiKey}");request.SetRequestHeader("Accept", "application/json");return request;}private bool IsRequestError(UnityWebRequest request) {return request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError || request.result == UnityWebRequest.Result.DataProcessingError;}private DeepSeekResponse ParseResponse(string jsonResponse) {try {return JsonUtility.FromJson<DeepSeekResponse>(jsonResponse);} catch (System.Exception e) {Debug.LogError($"JSON解析失败: {e.Message}\n响应内容:{jsonResponse}");return null;}}// 可序列化数据结构[System.Serializable]private class ChatRequest {public string model;public List<Message> messages;public float temperature;public int max_tokens;}[System.Serializable]public class Message {public string role;public string content;}[System.Serializable]private class DeepSeekResponse {public Choice[] choices;}[System.Serializable]private class Choice {public Message message;}
}
使用方法:
- 将此脚本挂载到场景中的任意物体(如主摄像机)
- 配置相关参数:
- API Key:填写你申请的API密钥
- Model Name:默认使用deepseek-chat,如需深度推理可使用deepseek-reasoner
- API Url:https://api.deepseek.com/v1/chat/completions
对话参数设置
Temperature:采样温度值,范围0-2。数值越高(如0.8)输出越随机,数值越低(如0.2)输出越稳定。建议参考官方文档,本示例设为0.7。
Max Tokens:设置每次请求生成内容的最大token数(1-8192)。注意输入和输出的总token数不能超过模型上下文长度限制。本示例设为150。
NPC角色配置
角色名称:Unity-Chan
性格设定:虚拟角色Unity-Chan,性格活泼可爱,精通Unity引擎和C#编程。
角色交互脚本
该脚本用于显示AI生成的对话回复。
using System.Collections;
using UnityEngine;
using UnityEngine.UI;public class NPCInteraction : MonoBehaviour
{[Header("组件引用")][SerializeField] private DeepSeekDialogueManager dialogueManager; // 对话管理器[SerializeField] private InputField inputField; // 玩家输入框[SerializeField] private Text dialogueText; // 对话显示文本[Header("参数设置")] [SerializeField] private float typingSpeed = 0.05f; // 打字效果速度private string characterName;void Start(){characterName = dialogueManager.npcCharacter.name;// 注册输入回调inputField.onSubmit.AddListener((text) => {dialogueManager.SendDialogueRequest(text, HandleAIResponse);});}// 处理AI回复private void HandleAIResponse(string response, bool success) {string displayText = success ? $"{characterName}:{response}" : $"{characterName}:(通讯中断)";StartCoroutine(TypewriterEffect(displayText));}// 打字机效果private IEnumerator TypewriterEffect(string text) {string currentText = "";foreach (char c in text){currentText += c;dialogueText.text = currentText;yield return new WaitForSeconds(typingSpeed);}}
}
使用说明
- 将脚本挂载到角色模型上
- 配置参数:
- Dialogue Manager:拖入对话管理器对象
- Input Field:拖入玩家输入框
- Dialogue Text:拖入对话显示文本框
- 调整Typing Speed参数控制打字效果速度
四、Demo