当前位置: 首页 > wzjs >正文

惠州网站建设制作win10系统优化工具

惠州网站建设制作,win10系统优化工具,西地那非片功效与作用主要会有哪些,手机怎么做钓鱼网站在当今的游戏开发中,AI 的应用越来越广泛,从简单的对话系统到复杂的智能 NPC。本文将介绍如何使用 Unity 实现一个与 Ollama API 进行交互的应用程序,该应用程序能够接收并处理来自服务器的实时流式响应数据,并将其展示给用户。 &…

在当今的游戏开发中,AI 的应用越来越广泛,从简单的对话系统到复杂的智能 NPC。本文将介绍如何使用 Unity 实现一个与 Ollama API 进行交互的应用程序,该应用程序能够接收并处理来自服务器的实时流式响应数据,并将其展示给用户。


🎯 功能概述

本示例展示了如何创建一个简单的 Unity 应用程序,它允许用户输入文本并通过 HTTP POST 请求发送至 Ollama API。应用程序会实时接收返回的数据流,并逐步更新 UI 上显示的内容。以下是具体的功能点:

  • 用户通过 TMP_InputField 输入文本。
  • 点击按钮或按下回车键后,文本会被发送到 Ollama API。
  • 使用 UnityWebRequest 发起异步请求,并通过自定义下载处理器接收流式响应。
  • 数据处理过程中,去除不需要的标记和转义字符,确保最终输出干净整洁。
  • 实时更新 UI 显示内容,提供即时反馈。

🔧 关键代码解析

1. 初始化与事件绑定

void Start()
{if (sendButton != null){sendButton.onClick.AddListener(OnSendButtonClicked);}if (userInputField != null){userInputField.onEndEdit.AddListener(OnInputEndEdit);}if (responseText == null){Debug.LogError("responseText 未赋值!");}else{Debug.Log("responseText 已赋值");}
}

这段代码确保了当用户完成编辑或点击按钮时,相应的事件会被触发,开始处理用户的输入。

2. 发送请求与处理响应

IEnumerator SendPromptToOllamaStream(string prompt)
{var requestJson = new RequestModel{model = "deepseek-r1:7b-Quantization",prompt = prompt,stream = true};string jsonData = JsonConvert.SerializeObject(requestJson);using (UnityWebRequest request = new UnityWebRequest(OLLAMA_URL, "POST")){byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonData);request.uploadHandler = new UploadHandlerRaw(bodyRaw);request.downloadHandler = new CustomDownloadHandler(ProcessStreamChunk); // 自定义下载处理器request.SetRequestHeader("Content-Type", "application/json");yield return request.SendWebRequest();if (request.result != UnityWebRequest.Result.Success){Debug.LogError("请求失败: " + request.error);}else{Debug.Log("请求完成");string finalResponse = currentResponseBuilder.ToString();Debug.Log("最终回复内容: " + finalResponse);if (responseText != null){responseText.text = finalResponse;}}}
}

这里我们构建了一个 JSON 请求体,包含了模型名称、用户输入以及是否启用流式传输的标志位。然后使用 UnityWebRequest 发起 POST 请求,并通过自定义的下载处理器来处理返回的数据流。

3. 处理不完整的 JSON 数据

由于服务器可能分多次返回数据,我们需要一个方法来正确地解析这些片段:

private void ProcessStreamChunk(byte[] data)
{// 解析逻辑...
}

此方法负责拼接所有收到的数据块,直到找到一个完整的 JSON 对象为止,再进行反序列化和进一步处理。

4. 清理响应数据

为了保证输出的整洁性,我们需要对原始响应做一些清理工作:

private string CleanResponseSegment(string segment)
{// 清理逻辑...
}

这一步主要是去除一些不必要的 HTML 标签或其他非预期字符,使得最终展示给用户的文本更加友好。

完整代码

using System;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using TMPro;
using System.Collections;
using Newtonsoft.Json;public class OllamaStreamingClient1 : MonoBehaviour
{[Header("UI References")]public TMP_InputField userInputField; // 用户输入框public Button sendButton;             // 提交按钮public TMP_Text responseText;         // 显示回复的文本组件private const string OLLAMA_URL = "http://127.0.0.1:11434/api/generate"; // Ollama API 地址private StringBuilder currentResponseBuilder = new StringBuilder();      // 构建最终回复内容private StringBuilder jsonBuffer = new StringBuilder();                   // 缓冲区,用于拼接不完整的 JSON 数据// ✅ 全局静态变量,用于临时缓存 response 内容public static StringBuilder TempResponseBuilder = new StringBuilder();//  deepseek-r1:7b-Quantizationvoid Start(){if (sendButton != null){sendButton.onClick.AddListener(OnSendButtonClicked);}if (userInputField != null){userInputField.onEndEdit.AddListener(OnInputEndEdit);}if (responseText == null){Debug.LogError("responseText 未赋值!");}else{Debug.Log("responseText 已赋值");}}void OnInputEndEdit(string text){if (text.EndsWith("\n")){OnSendButtonClicked();}}public void OnSendButtonClicked(){string userMessage = userInputField.text.Trim();if (!string.IsNullOrEmpty(userMessage)){Debug.Log($"发送用户输入:{userMessage}");StartCoroutine(SendPromptToOllamaStream(userMessage));userInputField.text = "";userInputField.ActivateInputField();if (responseText != null)responseText.text = "";// ✅ 每次新请求前清空临时缓存TempResponseBuilder.Clear();}}IEnumerator SendPromptToOllamaStream(string prompt){var requestJson = new RequestModel{model = "deepseek-r1:7b-Quantization",prompt = prompt,stream = true};string jsonData = JsonConvert.SerializeObject(requestJson);using (UnityWebRequest request = new UnityWebRequest(OLLAMA_URL, "POST")){byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonData);request.uploadHandler = new UploadHandlerRaw(bodyRaw);request.downloadHandler = new CustomDownloadHandler(ProcessStreamChunk); // 自定义下载处理器request.SetRequestHeader("Content-Type", "application/json");Debug.Log("开始发送请求...");yield return request.SendWebRequest();if (request.result != UnityWebRequest.Result.Success){Debug.LogError("请求失败: " + request.error);}else{Debug.Log("请求完成");string finalResponse = currentResponseBuilder.ToString();Debug.Log("最终回复内容: " + finalResponse);if (responseText != null){responseText.text = finalResponse;}}}}private void ProcessStreamChunk(byte[] data){if (data == null || data.Length == 0) return;string chunk = Encoding.UTF8.GetString(data);jsonBuffer.Append(chunk);while (true){int startIndex = jsonBuffer.ToString().IndexOf('{');if (startIndex == -1) break;int endIndex = FindMatchingBrace(jsonBuffer.ToString(), startIndex);if (endIndex == -1) break; // JSON 不完整,等待下一块string jsonString = jsonBuffer.ToString(startIndex, endIndex - startIndex);try{var responseWrapper = JsonConvert.DeserializeObject<OllamaStreamResponse>(jsonString);if (responseWrapper == null){jsonBuffer.Remove(0, endIndex);continue;}if (!string.IsNullOrEmpty(responseWrapper.response)){string cleanedResponse = CleanResponseSegment(responseWrapper.response);// ✅ 如果清理后的内容是空或为 "<tool_response>",则跳过拼接if (!string.IsNullOrWhiteSpace(cleanedResponse) && !cleanedResponse.Equals("<tool_response>", StringComparison.Ordinal)){TempResponseBuilder.Append(cleanedResponse);}}if (responseWrapper.done){currentResponseBuilder.Clear();currentResponseBuilder.Append(TempResponseBuilder.ToString());UpdateUIText();TempResponseBuilder.Clear(); // 清空全局 buffer}}catch (Exception ex){Debug.LogWarning("JSON 解析失败:" + ex.Message);jsonBuffer.Remove(0, endIndex);continue;}jsonBuffer.Remove(0, endIndex);}}private string CleanResponseSegment(string segment){if (string.IsNullOrEmpty(segment)) return "";// 替换 Unicode 转义字符segment = segment.Replace("\\u003c", "<").Replace("\\u003e", ">");// 去除 <|t|> 类似的标记segment = segment.Replace("<|t|>", "").Replace("|>", "").Replace("<|", "");// 去除 "</think>" 标记(包括可能出现的变体)segment = segment.Replace("<think>", "").Replace("</think>", "")  // 处理可能的 Unicode 或转义形式;    // 可选:处理中文标记return segment.Trim();}private void UpdateUIText(){if (responseText != null){responseText.text = currentResponseBuilder.ToString();Debug.Log("UI 更新为:" + currentResponseBuilder.ToString());}else{Debug.LogWarning("responseText 为 null,无法更新 UI!");}}private int FindMatchingBrace(string str, int start){int depth = 1;for (int i = start + 1; i < str.Length; i++){if (str[i] == '{') depth++;else if (str[i] == '}') depth--;if (depth == 0){return i + 1; // 包含最后的 }}}return -1;}[Serializable]private class RequestModel{public string model;public string prompt;public bool stream;}[Serializable]private class OllamaStreamResponse{public string model;public string created_at;public string response;public bool done;public string done_reason;}}

 


📦 扩展与优化建议

1. 增加错误处理机制

可以在每个可能出错的地方添加更详细的错误处理逻辑,比如网络超时、无效的 JSON 格式等。

2. 改进用户体验

可以考虑增加加载动画或提示信息,让用户知道请求正在处理中。

3. 性能优化

对于频繁的 UI 更新操作,可以考虑批量更新以减少渲染开销。


📖 结语

通过上述步骤,我们已经成功实现了一个基于 Unity 和 Ollama API 的简单但功能强大的聊天机器人前端。希望这篇博客能够帮助你快速上手相关技术,并激发你在自己的项目中尝试更多创新的可能性!

http://www.dtcms.com/wzjs/251326.html

相关文章:

  • 全国小微企业名录官网快速seo排名优化
  • 提升网站安全免费公司网站建站
  • 如何查网站开发商广告设计与制作
  • 贸易网站建设案例百度霸屏推广靠谱吗
  • 河南郑州做网站h汉狮投放广告找什么平台
  • 网页制作三剑客是指什么su搜索引擎优化
  • 沈阳做网站黑酷科技在百度怎么免费发布广告
  • 做教学的视频网站有哪些问题刷粉网站推广便宜
  • 网站建设所需资料品牌公关
  • 公众号制作的网站开发成都百度seo优化公司
  • 政府网站建设成本百度热搜榜第一
  • 电子商务网站推广主要方式网络流量统计工具
  • wordpress发布文章空白怎么网站排名seo
  • 怎么做动态网站aspseo怎么收费的
  • 全景网站开发多少钱长沙网络公司排名
  • 网站排名提升软件磁力猫torrentkitty官网
  • 网站模板版权seo研究中心道一老师
  • 个人做地方民生网站semantic
  • 长沙企业建站销售电话东莞seo建站咨询
  • 怎样做网站设计成都百度推广账户优化
  • 网站设计步骤及注意事项自媒体平台注册官网
  • 鄂州市政府门户网站 鄂州要闻长沙seo步骤
  • 经营类网站备案怎样做网络推广营销
  • 做网站好的品牌百度手机助手app下载
  • 简单网页制作视频教程seo网络推广优化教程
  • 酒类网站建设方案案如何制作一个网页
  • 泉州效率网络网站建设泰州网站优化公司
  • 租外国服务器做的网站要备案吗友情手机站
  • 2023年山东还有疫情吗镇江网站关键字优化
  • 网站建设应该注意的设计要点河北电子商务seo