unity-C#调用百度千帆AppBuilder的OpenApi

目录

  • 功能描述
  • 准备工作
    • 百度智能云账号
    • 创建应用
    • 编辑应用
    • 创建Api秘钥
    • Api调用流程
    • unity代码
      • Unitywebrequest
        • 非流式
        • 流式
        • 注意事项
      • Restsharp

功能描述

使用百度千帆AppBuilder平台,通过api调用的方式实现AI大模型对话功能(文字)

准备工作

百度智能云账号

请自行在百度智能云进行创建
百度智能云官网
在这里插入图片描述
tips记得开通大模型的服务(需付费)

创建应用

进入AppBuilder点击创建应用
在这里插入图片描述

编辑应用

设置你需要的应用信息,如果有知识库的话需要设置对应的知识库(一个应用目前只能对应一个知识库)

  1. 设置名字和头像-这个只在网页访问的时候会显示
  2. 设置角色设定,可以先输入一些关键词,点击优化让ai帮你优化
  3. 选择知识库一个应用只能对应一个知识库(20240430)
  4. 还可以设置你需要的内容
  5. 右上角设置基模(目前ERNIE-4.0-8K比较贵,ERNIE-3.5-8K相对便宜效果也不错,根据实际需求选择即可)
  6. 右下角输入内容预览效果
  7. 以上内容确定后点击右上角的发布即可
    在这里插入图片描述

创建Api秘钥

在这里插入图片描述
点击右上方的个人中心图标
点击Api秘钥
在这里插入图片描述
新增秘钥,点击复制按钮一键复制秘钥

Api调用流程

官方文档

在这里插入图片描述
调用流程如下:

  1. 获取创建的应用的appid
  2. 获取api秘钥
  3. 先调用新建会话的api,获取conversation_id
  4. 根据conversation_id调用大模型对话接口正式发起会话

unity代码

Unitywebrequest

非流式

使用非流式的调用方式的话就跟平常的api调用没差,这里就不多做说明了

流式
const string API_KEY = "api秘钥";const string _baseUrl = "https://qianfan.baidubce.com/v2/app/conversation";const string _startConversRoute = "/runs";const string _appId = "appid";RequestBody _reqBody;//实例化的请求体string _temResultTotal = "";string _temAsk = "";private StreamReader streamReader;private MemoryStream responseStream;private string _temConversationID;//临时对话idconst string TAG = "YiyanAppBuilderApiCtr";
///调用接口
///
IEnumerator YiyanAppBuilderStreamIE(string prompt){this._temAsk = prompt;yield return GetConversationID();//调用新建会话接口获取conversationidbyte[] bodyRaw = Data2byte(prompt);//将请求的内容封装在请求体中最后一并转化为字节数据using (UnityWebRequest request = UnityWebRequest.Post($"{_baseUrl}{_startConversRoute}", "")){request.SetRequestHeader("Accept", "application/octet-stream");//改行可加可不加request.SetRequestHeader("Authorization", $"Bearer {API_KEY}");request.SetRequestHeader("Content-Type", "application/json");request.uploadHandler = new UploadHandlerRaw(bodyRaw);//将请求的数据添加如请求中request.SendWebRequest();//发起调用byte[] results = new byte[1024];//try//{  tips 如果追求流式效果,此处不能使用trycatch包裹业务代码,否则实现的效果和非流式一样while (!request.isDone){yield return new WaitForSeconds(0.5f);//添加yield return (填null或者0)都行results = request.downloadHandler.data;this.HandleStreamData(results);//对接受的数据进行处理}if (request.isDone && results != null){//业务逻辑}//}//catch (Exception ex)//{//}}yield return null;}private void HandleStreamData(byte[] results){string line = "";if (results != null){responseStream = new MemoryStream(results);streamReader = new StreamReader(responseStream);while ((line = streamReader.ReadLine()) != null){string _temResult = "";if (line.Length < 6) continue;try{//将字节流数据的头信息(data: )去掉,然后通过json转换得到我们想要的数据if (JObject.Parse(line.Substring(5))["answer"].ToString() == "") continue;Debug.Log(line.Substring(5));_temResult = JObject.Parse(line.Substring(5))["answer"].ToString();}catch (Exception ex){//说明json转换失败,跳过Debug.Log("yiyan transform byte2json fail>>>>" + ex.Message + line.Substring(5));continue;}if (!_temStreamCBList.ContainsKey(_temResult)){//对数据进行过滤,将出现的特殊符号去掉_temResult = _temResult.Replace("\n", "").Replace(" ", "").Replace("\t", "").Replace("\r", "");_temResult = FilterStr(_temResult);if (_temResult == null || _temResult == "") continue;Debug.Log(_temResult);//将流数据转换加入队列,调用循环进行播放和处理this._temResultTotal += _temResult;try{_temStreamCBList.Add(_temResult, _temResult);}catch (Exception ex){Log.Info($"{TAG}>>>ArgumentException: An item with the same key has already been added. Key");continue;}if (_temStreamCBList.Count == 1){//业务逻辑}}}}}/***  根据apikey和appid获取conversation_id用于开启对话*/IEnumerator GetConversationID(){Dictionary<string, string> form = new Dictionary<string, string>();form.Add("app_id", _reqBody.app_id);string _jsonBody = JsonConvert.SerializeObject(form);byte[] bytes = Encoding.UTF8.GetBytes(_jsonBody);using (UnityWebRequest request = UnityWebRequest.Post(_baseUrl, "")){request.SetRequestHeader("Content-Type", "application/json");request.SetRequestHeader("Authorization", $"Bearer {API_KEY}");request.uploadHandler = new UploadHandlerRaw(bytes);yield return request.SendWebRequest();ResponseBody response = JsonUtility.FromJson<ResponseBody>(request.downloadHandler.text);_temConversationID = response.conversation_id;Debug.Log(_temConversationID);}}private byte[] Data2byte(string prompt){_reqBody.query = prompt;_reqBody.conversation_id = _temConversationID;string body = JsonConvert.SerializeObject(_reqBody);byte[] bodyRaw = Encoding.UTF8.GetBytes(body);return bodyRaw;}public string FilterStr(string str){string pattern = @"\*|\^|\[(\d+)\]"; // 匹配 *、^、[ 和 ] 字符  以及[]里的数字//Regex reg = new Regex("\\s+");string _regResult = Regex.Replace(str, pattern, "");//Debug.Log(_regResult);return _regResult;}#region 请求yiyan-api需要的请求体[Serializable]
class RequestBody
{public string app_id;public string query;public bool stream;public string conversation_id;
}
[Serializable]
class ResponseBody
{public string request_id;public string conversation_id;
}
#endregion
注意事项

截止至20240430也就是今天为止
官方请求后返回的数据中会在最后有关于知识库的下标的数据,如下图
在这里插入图片描述
官方的回复是
在这里插入图片描述
因此在实际进行调用的时候还需要对最后的数据进行过滤

通过以上流程即可调用成功

Restsharp

该插件可以更便捷的实现调用,不过该插件存在多线程(UI更新不及时)的问题,因此不做该插件实现调用api的内容

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/5310.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣---二叉树的右视图

给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4] 输出: [1,3,4]示例 2: 输入: [1,null,3] 输出: [1,3]示例 3: 输入: [] 输出: []实现方法&…

nginx+Tomcat动静分离

本⽂的动静分离主要是通过nginxtomcat来实现&#xff0c;其中nginx处理图⽚、html等静态的⽂ 件&#xff0c;tomcat处理jsp、do等动态⽂件. 实验环境 192.168.200.133 nginx反向代理 192.168.200.129 static 192.168.200.130 dynamic 步骤 修改三台主机名 [rootadmin ~]#…

关于Centos 7/8 网络设置 与工具连接

网络三步曲的配置 1、首先更改虚拟机的网络配置 查看子网地址以及网关 如果有要求需要更改IP地址&#xff0c;规定第三位是指定数值&#xff0c;那么需要全部更改 例如&#xff0c;IP地址为192.168.200.30 其中200为重点&#xff0c;更改时为以下步骤 1、点击DHCP设置&#x…

【数据结构】顺序表专题

前言 本篇文章我们来进行有关顺序表的专题训练&#xff0c;让我们一起来看一下有关顺序表的算法题 &#x1f493; 个人主页&#xff1a;小张同学zkf ⏩ 文章专栏&#xff1a;数据结构 &#x1f4dd;若有问题 评论区见 &#x1f389;欢迎大家点赞&#x1f44d;收藏⭐文章 1.移除…

每天五分钟深度学习:导数是反向传播算法的数学基础

本文重点 导数作为微积分学的核心概念之一,不仅在数学领域内占有举足轻重的地位,更在实际问题中发挥着不可替代的作用。我们要想学习反现象传播算法,我们前提是先要学习导数的概念。本节课程我们将看一下导数是什么? 导数 导数,顾名思义,是函数在某一点或某一段区间内…

【国标语音对讲】EasyCVR视频汇聚平台海康/大华/宇视摄像头GB28181语音对讲配置

一、背景分析 近年来&#xff0c;国内视频监控应用发展迅猛&#xff0c;系统接入规模不断扩大&#xff0c;涌现了大量平台提供商&#xff0c;平台提供商的接入协议各不相同&#xff0c;终端制造商需要给每款终端维护提供各种不同平台的软件版本&#xff0c;造成了极大的资源浪…

值得买科技新思路,导购电商的终点是“AI+出海”?

在以往&#xff0c;大众普遍认为品牌的消费者大多是高度忠诚人群&#xff0c;而事实上&#xff0c;非品牌忠诚者相比重度消费者&#xff0c;对促进品牌增长更为重要。 这类非品牌忠诚者被定义为摇摆的消费者群体&#xff0c;也就是那些购买品牌产品概率在20%-80%之间的消费者。…

mysql-sql练习-5-行列互转

目录 成绩单 简单互转 需求 多行转多列 分组 判断 聚合 理解 分组 合并 逆向需求 多列转多行 输出 合并 abc 去重 合并 拆分 需求 建表 多行转多列 逆向需求 多列转多行 拆分 按长度 拆分 按个数 成绩单 简单互转 需求 多行转多列 分组 判断 聚合 with tmp as(--…

[Transactional Level Bypass] Bypass Validation Rule in Apex Batch Class

问题 现有一个batch job用于批量更新Lead&#xff0c;最近频繁收到apex exception email, 显示更新Lead的时候触发了validation rule&#xff0c;导致apex job运行失败。 batch class节选如下&#xff1a; public void execute(Database.BatchableContext bc, List<Lead&…

49. 字母异位词分组 128. 最长连续序列

49. 字母异位词分组 128. 最长连续序列 把集合里面的所有元素都放入set容器里面 定义结果最大连续数量 ans for循环遍历每个元素 先判断集合里面有没有比这个元素小1的 如果没有 说明这个元素就是序列的第一个元素 然后接着找集合里面有没有比这个元素大1的 while一直找 …

C语言中的趣味代码(五)

我想以此篇结束关于C语言的博客&#xff0c;因为在C语言拖得越久越不能给大家带来新的创作&#xff0c;在此我也相信大家对C语言已经有了一个新的认知。进入正题&#xff0c;在这一篇中我主要编一个“英语单词练习小程序”来给大家展开介绍&#xff0c;从测试版逐步改良&#x…

【无标题】测试下目录间距

文章目录 前言一、Java基础题1、Java语言的三大特性2、JDK 和 JRE 有什么区别3、Java基本数据类型及其封装类4、说明一下public static void main(String args[])这段声明里关键字的作用5、 与 equals 的区别6、Java语言的三大特性7、Java语言的三大特性8、Java语言的三大特性9…

OpenHarmony实战开发-属性样式动画

在关键帧&#xff08;Keyframes&#xff09;中动态设置父组件的width和height&#xff0c;实现组件变大缩小。子组件设置scale属性使父子组件同时缩放&#xff0c;再设置opacity实现父子组件的显示与隐藏。 <!-- xxx.hml --> <div class"container"><…

OGG extract进程占据大量虚拟内存导致服务器内存异常增长分析

现象 oracle服务器一节点内存&#xff0c;一个月来持续升高&#xff0c;近一月上涨10%左右。 问题分析 OS内存使用情况 使用内存最大的10个进程如下&#xff0c;PID为279417占用最大的内存。 查询279417&#xff0c;发现是ogg相关进程。 发现ogg的extract进程占用了大量的虚拟内…

vite打包配置

目录 minify默认是esbuild&#xff0c;不能启动下面配置 使用&#xff1a; plugins: [viteMockServe({mockPath: mock})]根目录新建mock/index.ts. 有例子Mock file examples&#xff1a;https://www.npmjs.com/package/vite-plugin-mock-server 开发环境生产环境地址替换。根…

spark实验求TOP值

实验1&#xff1a;求TOP值 已知存在两个文本文件&#xff0c;file1.txt和file2.txt&#xff0c;内容分别如下&#xff1a; file1.txt 1,1768,50,155 2,1218, 600,211 3,2239,788,242 4,3101,28,599 5,4899,290,129 6,3110,54,1201 7,4436,259,877 8,2369,7890,27 fil…

活性炭复合纳米纤维膜

活性炭复合纳米纤维膜是一种结合了活性炭和纳米纤维技术的新型复合材料。这种材料通常通过特定的制备工艺&#xff0c;如静电纺丝技术&#xff0c;将活性炭纳米纤维与其他材料&#xff08;如TiO2、聚合物等&#xff09;结合在一起&#xff0c;形成具有良好结构和功能的薄膜。 活…

UDP!!!

UDP!!! 一 : 传输层的协议:二 : UDP2.1 UDP长度2.2 UDP校验和2.2.1 : 为什么会出现传输出错的情况??2.2.3: 对数据进行校验的方式CRCmd5 三 : UDP的适用场景 一 : 传输层的协议: 传输层的协议有UDP,TCP UDP:无连接,不可靠传输,面向数据报,全双工 TCP:有连接,可靠传输,面向字…

nvm 切换 Node 版本失败

创建vue3项目时&#xff0c;需要切换到更高版本的 node&#xff0c;于是使用 nvm (node 包版本管理工具)进行版本切换 切换版本时&#xff0c;显示成功&#xff0c;但再次查看当前 node 版本时&#xff0c;发现没切换过来。 解决方法&#xff1a; where node 查看node的安装…

vue路由(路由基本使用,传参,多级路由)

目录 vue-router简介路由配置和使用嵌套&#xff08;多级&#xff09;路由路由传参方式1&#xff1a;路由的query参数方式2&#xff1a;路由的params参数props配置 命名路由取消路由组件在前进后退 vue-router简介 vue的一个插件库&#xff0c;专门用来实现SPA应用 路由配置…